From 5c4517a8f12d8d15969e10380f2bd6be54cb2f17 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Tue, 16 Jan 2018 14:40:51 -0800 Subject: [PATCH 01/45] Update Preview Version 1.0.md --- doc/Preview Version 1.0.md | 122 +++++++++++++++++++++++++++++++++---- 1 file changed, 110 insertions(+), 12 deletions(-) diff --git a/doc/Preview Version 1.0.md b/doc/Preview Version 1.0.md index b67c9ea..20fdd74 100644 --- a/doc/Preview Version 1.0.md +++ b/doc/Preview Version 1.0.md @@ -4,9 +4,9 @@ PLASMA is approaching a 1.0 release after _only_ 12 years. Hopefully it was wort Download the two disk images: -(PLASMA Preview 1.0 System)[https://github.com/dschmenk/PLASMA/blob/master/PLASMA-PRE1.PO?raw=true] +[PLASMA Preview 1.0 System](https://github.com/dschmenk/PLASMA/blob/master/PLASMA-PRE1.PO?raw=true) -(PLASMA 1.0 Build System)[https://github.com/dschmenk/PLASMA/blob/master/PLASMA-BLD1.PO?raw=true] +[PLASMA 1.0 Build System](https://github.com/dschmenk/PLASMA/blob/master/PLASMA-BLD1.PO?raw=true) PLASMA can be run from floppies, System in drive 1, and Build in drive 2. All Apple II computers are supported, from the earliest Rev 0 to the last Apple IIGS. However, an accelerator and hard disk/CFFA are highly recommended. The recommended mass storage installation looks like: @@ -14,27 +14,125 @@ System Files => /HARDISK/PLASMA.PRE1/ Build Files => /HARDISK/BLD/ -Keeping the system files seperate from the build directory will make upgrading to the final 1.0 Release later a little easier. 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, launch PLASMA.SYSTEM from your command processor of choice. +Keeping the system files seperate from the build directory will make upgrading to the final 1.0 Release later a little easier. 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. ## 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. Launch `PLASMA16.SYSTEM` to use the 16 bit PLASMA VM. If you don't have the right CPU, it will print a message and restart. -# PLASMA Command Line Shell +## PLASMA Command Line Shell PLASMA incorporates a very basic command line shell to facilitate navigating the filesystem and executing both SYSTEM programs and PLASMA modules. It has a few built-in commands: | Command | Operation | -|:-------------------:|-----------------------| -| C [PREFIX] | Catalog prefix -| P \ | change to Prefix -| / | change to parent prefix -| V | show online Volumes -| -\ | launch SYSTEM program -| +\ | exec PLASMA module +|:----------------------------:|-------------------------| +| C [PREFIX] | Catalog prefix +| P \ | change to Prefix +| / | change to parent prefix +| V | show online Volumes +| -\ [PARAMS] | launch SYSTEM program +| +\ [PARAMS] | exec PLASMA module ``` [Optional parameters] ``` -The shell is very breif 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. +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 + +The Developers Preview comes with a basic set of system modules. When PLASMA is launched, the SYS/ directory immediately below where PLASMA.SYSTEM was launched contains the modules. The system volume (where PLASMA was started) 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 ProDOS 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]] \ [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 + +## Source Code + +This is a Developers Preview, so sample source code is included from the project. It all builds without alteration and shloud be a good starting point for further explorations. There was a PLASMA SANDBOX in previous versions that was a minimal editor+compiler playground. It wasn't the full language and has been superceded by the real PLASMA compiler. However, the examples that accompanied the SANDBOX are included here. They have been updated to use the `INCLUDE "INC/CMDSYS.PLH` line so that they may compile arnd run, but no gaurentees. You will probably have to fix whatever differences you come accross. An exercise, as they say, left up to the student. + +## 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. The goal is to spend considerable effort improving the load time before the final 1.0 release. 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. + +- Many modules in the project aren't included in the Developer Preview. Only those modules that have gotten a good workout are included. The rest of the modules will be tested and included for the final 1.0 release. Feel free to try them out, and give feedback. Chances are they will work out of the box, or just a small tweak. + +- The documentation is sparse and incomplete. Yep, could use your help... + +# 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. + +# 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 ;-) +- HandyAndy (6502.org): Catching the grammatical errors that I ain't no good at. From 802fa831dfe429b46045dd7e5cf281bb996dbdde Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Tue, 16 Jan 2018 14:53:11 -0800 Subject: [PATCH 02/45] Update Preview Version 1.0.md --- doc/Preview Version 1.0.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/doc/Preview Version 1.0.md b/doc/Preview Version 1.0.md index 20fdd74..732e191 100644 --- a/doc/Preview Version 1.0.md +++ b/doc/Preview Version 1.0.md @@ -1,6 +1,6 @@ # Developer Preview Version 1.0 -PLASMA is approaching a 1.0 release after _only_ 12 years. Hopefully it was worth the wait. To work out the remaining kinks, this Developer Preview will allow programmers to kcick the tires, so to speak, to provide feedback on the system. +PLASMA is approaching a 1.0 release after _only_ 12 years. Hopefully it was worth the wait. To work out the remaining kinks, this Developer Preview will allow programmers to kick the tires, so to speak, to provide feedback on the system. Download the two disk images: @@ -50,7 +50,7 @@ The Developers Preview comes with a basic set of system modules. When PLASMA is 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]] \ [OUTPUT FILE] ++PLASM [-[W][O[2]] [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. @@ -60,7 +60,7 @@ There are some demo programs included for your perusal. Check out `ROGUE` for so ## Source Code -This is a Developers Preview, so sample source code is included from the project. It all builds without alteration and shloud be a good starting point for further explorations. There was a PLASMA SANDBOX in previous versions that was a minimal editor+compiler playground. It wasn't the full language and has been superceded by the real PLASMA compiler. However, the examples that accompanied the SANDBOX are included here. They have been updated to use the `INCLUDE "INC/CMDSYS.PLH` line so that they may compile arnd run, but no gaurentees. You will probably have to fix whatever differences you come accross. An exercise, as they say, left up to the student. +This is a Developers Preview, so sample source code is included from the project. It all builds without alteration and shloud be a good starting point for further explorations. There was a PLASMA SANDBOX in previous versions that was a minimal editor+compiler playground. It wasn't the full language and has been superceded by the real PLASMA compiler. However, the examples that accompanied the SANDBOX are included here. They have been updated to use the `INCLUDE "INC/CMDSYS.PLH"` line so that they may compile arnd run, but no gaurentees. You will probably have to fix whatever differences you come accross. An exercise, as they say, left up to the student. ## Issues @@ -121,7 +121,7 @@ drop, h, drop = func() ``` a = func() // Two values silently dropped ``` -To generate compiler warning for this issue, and a few others, use the -W option when compiling. +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. @@ -136,3 +136,6 @@ I wish to thank the people who have contributed the the PLASMA project. They hav - 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 ;-) - HandyAndy (6502.org): Catching the grammatical errors that I ain't no good at. + +Dave Schmenk +http://schmenk.is-a-geek.com From 2bd2b0f3af59287cef519636508929f3cb3fe913 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Tue, 16 Jan 2018 19:30:14 -0800 Subject: [PATCH 03/45] handyandy's grammar fixes --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 06520e8..4883747 100755 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ PLASMA: **P**roto **L**anguage **A**s**S**e**M**bler for **A**pple PLASMA is a medium level programming language targeting the 8-bit 6502 processor. Historically, there were simple languages developed in the early years of computers that improved on the tedium of assembly language programming while still being low level enough for system coding. Languages like B, FORTH, and PLASMA fall into this category. -PLASMA is a combination of operating environment, virtual machine, and assembler/compiler matched closely to the 6502 architecture. It is an attempt to satisfy a few challenges surrounding code size, efficient execution, small runtime and flexible code location. By architecting a unique bytecode that maps nearly one-to-one to the higher-level representation, the compiler can be very simple and execute quickly on the Apple II for a self-hosted environment. A modular approach provides for incremental development and code reuse. The syntax of the language is heavily influenced by assembly, Pascal, and C. The design philosophy was to be as simple as feasible while retaining flexibility and symantic clarity. You won't find any unnecessary or redundant syntax in PLASMA. +PLASMA is a combination of operating environment, virtual machine, and assembler/compiler matched closely to the 6502 architecture. It is an attempt to satisfy a few challenges surrounding code size, efficient execution, small runtime and flexible code location. By architecting a unique bytecode that maps nearly one-to-one to the higher-level representation, the compiler can be very simple and execute quickly on the Apple II for a self-hosted environment. A modular approach provides for incremental development and code reuse. The syntax of the language is heavily influenced by assembly, Pascal, and C. The design philosophy was to be as simple as feasible while retaining flexibility and semantic clarity. You won't find any unnecessary or redundant syntax in PLASMA. Different projects have led to the architecture of PLASMA, most notably Apple Pascal, FORTH, and my own Java VM for the 6502: VM02. Each has tried to map a generic VM to the 6502 with varying levels of success. Apple Pascal, based on the USCD Pascal using the p-code interpreter, was a very powerful system and ran fast enough on the Apple II to be interactive but didn't win any speed contests. FORTH was the poster child for efficiency and obtuse syntax. Commonly referred to as a write only language, it was difficult to come up to speed as a developer, especially when using others' code. My own project in creating a Java VM for the Apple II uncovered the folly of shoehorning a large, 32-bit virtual memory environment into 8-bit, 64K hardware. @@ -380,7 +380,7 @@ char[64] txtfile = "UNTITLED" ### Function Definitions -Functions are defined after all constants, variables and data. Function definitions can be `export`ed for inclusion in other modules and can be forward declared with a `predef` type in the constant and variable declarations. Functions can take parameters, passed on the evaluation stack, then copied to the local frame for easy access. They can have their own variable declarations, however, unlike the global declarations, no data can be predeclared - only storage space. A local frame is built for every function invocation and there is also a limit of 254 bytes of local storage. Each parameter takes two bytes of local storage, plus two bytes for the previous frame pointer. If a function has no parameters or local variables, no local frame will be created, improving performance. Functions always return a single value by default. +Functions are defined after all constants, variables and data. Function definitions can be `export`ed for inclusion in other modules and can be forward declared with a `predef` type in the constant and variable declarations. Functions can take parameters passed on the evaluation stack, then copied to the local frame for easy access. They can have their own variable declarations, however, unlike the global declarations, no data can be predeclared - only storage space. A local frame is built for every function invocation and there is also a limit of 254 bytes of local storage. Each parameter takes two bytes of local storage, plus two bytes for the previous frame pointer. If a function has no parameters or local variables, no local frame will be created, improving performance. Functions return a single value by default. ``` def myfunc(a, b) // Two parameters and defaults to one returned value ``` @@ -600,7 +600,7 @@ redraw ### Exported Declarations -Data and function labels can be exported so other modules may access this modules data and code. By prepending `export` to the data or functions declaration, the label will become available to the loader for inter-module resolution. Exported labels are converted to uppercase with 16 significant characters. Although the label will have to match the local version, external modules will match the case-insignificant, short version. Thus, "ThisIsAVeryLongLabelName" would be exported as: "THISISAVERYLONGL". +Data and function labels can be exported so other modules may access this modules' data and code. By prepending `export` to the data or functions declaration, the label will become available to the loader for inter-module resolution. Exported labels are converted to uppercase with 16 significant characters. Although the label will have to match the local version, external modules will match the case-insignificant, short version. Thus, "ThisIsAVeryLongLabelName" would be exported as: "THISISAVERYLONGL". Here is an example using the `import`s from the previous examples to export an initialized array of 10 elements (2 defined + null delimiter): @@ -692,7 +692,7 @@ putc(']') putc('\n') ``` -Escaped characters, like the `\n` above are replaces with the Carriage Return character. The list of escaped characters is: +Escaped characters, like the `\n` above are replaced with the Carriage Return character. The list of escaped characters is: | Escaped Char | ASCII Value |:------------:|------------ @@ -1256,7 +1256,7 @@ would silently return 100,0 because of the return value count in the definition. ## Native Assembly Functions -Assembly code in PLASMA is implemented strictly as a pass-through to the assembler. No syntax checking, or checking at all, is made. All assembly routines *must* come after all data has been declared, and before any PLASMA function definitions. Native assembly functions can't see PLASMA labels and definitions, so they are pretty much relegated to leaf functions. Lastly, PLASMA modules are re-locatable, but labels inside assembly functions don't get flagged for fix-ups. The assembly code must use all relative branches and only accessing data/code at a fixed address. Data passed in on the PLASMA evaluation stack is readily accessed with the X register and the zero page address of the ESTK. The X register must be properly saved, incremented, and/or decremented to remain consistent with the rest of PLASMA. Parameters are **popped** off the evaluation stack with `INX`, and the return value is **pushed** with `DEX`. It is possible to relocate absolute addresses with a little trickery. Look to some of the library modules where native code is fixed up in the initialization block. +Native assembly functions are only available on the cross-compiler. Assembly code in PLASMA is implemented strictly as a pass-through to the assembler. No syntax checking, or checking at all, is made. All assembly routines *must* come after all data has been declared, and before any PLASMA function definitions. Native assembly functions can't see PLASMA labels and definitions, so they are pretty much relegated to leaf functions. Lastly, PLASMA modules are re-locatable, but labels inside assembly functions don't get flagged for fix-ups. The assembly code must use all relative branches and only access data/code at a fixed address. Data passed in on the PLASMA evaluation stack is readily accessed with the X register and the zero page address of the ESTK. The X register must be properly saved, incremented, and/or decremented to remain consistent with the rest of PLASMA. Parameters are **popped** off the evaluation stack with `INX`, and the return value is **pushed** with `DEX`. It is possible to relocate absolute addresses with a little trickery. Look to some of the library modules where native code is fixed up in the initialization block. # Implementation From 8869392a11ad29e1553231ccb05a47ac08810cdf Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Tue, 16 Jan 2018 19:41:11 -0800 Subject: [PATCH 04/45] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 4883747..5eb582d 100755 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ +# 1/17/2018 Developer Preview 1.0 Available +Download and read the Release Notes: +https://github.com/dschmenk/PLASMA/blob/master/doc/Preview%20Version%201.0.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) From 9dc2a68bf492026fbeac02425a37d480db4ef16a Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Tue, 16 Jan 2018 20:12:38 -0800 Subject: [PATCH 05/45] Update Preview Version 1.0.md --- doc/Preview Version 1.0.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/Preview Version 1.0.md b/doc/Preview Version 1.0.md index 732e191..b29fa6d 100644 --- a/doc/Preview Version 1.0.md +++ b/doc/Preview Version 1.0.md @@ -127,6 +127,8 @@ To generate compiler warning for this issue, and a few others, use the `-W` opti 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 + # 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: From 938461691e8c0343cb15497b0f5025b4baf43a3b Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 17 Jan 2018 06:51:35 -0800 Subject: [PATCH 06/45] Update Preview Version 1.0.md --- doc/Preview Version 1.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Preview Version 1.0.md b/doc/Preview Version 1.0.md index b29fa6d..e7fa80c 100644 --- a/doc/Preview Version 1.0.md +++ b/doc/Preview Version 1.0.md @@ -60,7 +60,7 @@ There are some demo programs included for your perusal. Check out `ROGUE` for so ## Source Code -This is a Developers Preview, so sample source code is included from the project. It all builds without alteration and shloud be a good starting point for further explorations. There was a PLASMA SANDBOX in previous versions that was a minimal editor+compiler playground. It wasn't the full language and has been superceded by the real PLASMA compiler. However, the examples that accompanied the SANDBOX are included here. They have been updated to use the `INCLUDE "INC/CMDSYS.PLH"` line so that they may compile arnd run, but no gaurentees. You will probably have to fix whatever differences you come accross. An exercise, as they say, left up to the student. +This is a Developers Preview, so sample source code is included from the project. It all builds without alteration and should be a good starting point for further explorations. There was a PLASMA SANDBOX in previous versions that was a minimal editor+compiler playground. It wasn't the full language and has been superceded by the real PLASMA compiler. However, the examples that accompanied the SANDBOX are included here. They have been updated to use the `INCLUDE "INC/CMDSYS.PLH"` line so that they may compile arnd run, but no gaurentees. You will probably have to fix whatever differences you come accross. An exercise, as they say, left up to the student. ## Issues From 4d934b3caaec887dbf8914602f13b2b00b3ce960 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 17 Jan 2018 06:52:57 -0800 Subject: [PATCH 07/45] Update Preview Version 1.0.md --- doc/Preview Version 1.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Preview Version 1.0.md b/doc/Preview Version 1.0.md index e7fa80c..0dd1c3e 100644 --- a/doc/Preview Version 1.0.md +++ b/doc/Preview Version 1.0.md @@ -64,7 +64,7 @@ This is a Developers Preview, so sample source code is included from the project ## 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. The goal is to spend considerable effort improving the load time before the final 1.0 release. 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 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. The goal is to spend considerable effort improving the load time before the final 1.0 release. 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. - Many modules in the project aren't included in the Developer Preview. Only those modules that have gotten a good workout are included. The rest of the modules will be tested and included for the final 1.0 release. Feel free to try them out, and give feedback. Chances are they will work out of the box, or just a small tweak. From 16f5cd6f1bc770f87e50d456dc667fd708c7981d Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 17 Jan 2018 10:28:41 -0800 Subject: [PATCH 08/45] Update magic # in module load --- src/vmsrc/plvm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vmsrc/plvm.c b/src/vmsrc/plvm.c index cca64ef..3296c35 100755 --- a/src/vmsrc/plvm.c +++ b/src/vmsrc/plvm.c @@ -265,7 +265,7 @@ int load_mod(byte *mod) moddep = header + 1; modsize = header[0] | (header[1] << 8); magic = header[2] | (header[3] << 8); - if (magic == 0xDA7F) + if (magic == 0x6502) { /* * This is a relocatable bytecode module. From 38f19dff2fcb21d620521a0f6f93f941ed922b51 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 17 Jan 2018 11:27:59 -0800 Subject: [PATCH 09/45] Add sieve.pla to sample source --- PLASMA-BLD1.PO | Bin 143360 -> 143360 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/PLASMA-BLD1.PO b/PLASMA-BLD1.PO index 19cdfc7c8e0c80010d313d5f7b9c4b3d38cd8154..d555f3570e018eacc8345471c3e5dfdc3cec4af5 100644 GIT binary patch delta 583 zcmZ8d$x6gP5KWKc0@~`%Vh*Fo>dV1 z0FNRJ;xG6GUR~xt#Hvp8U|*{8-m6zHb@9=4@zM1(mS^3~@%$nib2e9tJH^TMwPnk^ z{Fl{cv7F_N_IHn1Ez2~`tM=Ot)_XbF^D@}OTF=*S19y-2th15Ga{&O0Fz3xr^RkK( z4TQxZV$>8o&QDam0)ALJ;)iEifYhR%VsTy8gbUJzz=g6pjx^^L;lrU2@yIj>h>vyI zo^`m0Dx4F_r>1;WHx{_SYk*eZk&^5Ysftou3PV-4(-aO;HBn21wn^c_*2Z?x%_0(M zw&I}iAZO~ymFAHLkiIdWSlW{Z2EbU98-=m~1)M0rOhyC*;e_50as2 zVl)j7aAswBZL|2tkW28-B~&WT1iz87ib$i*%Lu%dw9RVzGkS=Gk?DO&H4>*9PiTrc rrx`JZ4#z&RhturIq4Ye delta 85 zcmZp8z|ru4V}mLSBiCj%7F$Mf2GZQisW34uW@KVydHDFr)5(lXf0k)5u`N5pm;wNe;1|6B From 3b2c80b7183c414822858934a2996e8513ca7993 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 17 Jan 2018 18:46:29 -0800 Subject: [PATCH 10/45] Update Preview Version 1.0.md --- doc/Preview Version 1.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Preview Version 1.0.md b/doc/Preview Version 1.0.md index 0dd1c3e..1ff527a 100644 --- a/doc/Preview Version 1.0.md +++ b/doc/Preview Version 1.0.md @@ -137,7 +137,7 @@ I wish to thank the people who have contributed the the PLASMA project. They hav - 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 ;-) -- HandyAndy (6502.org): Catching the grammatical errors that I ain't no good at. +- Andy Werner (6502.org): Catching the grammatical errors that I ain't no good at. Dave Schmenk http://schmenk.is-a-geek.com From 5ac6a556c853883ae3e55b10b3209e93ffab536f Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 17 Jan 2018 21:13:16 -0800 Subject: [PATCH 11/45] Only adjust frame pointer for ENTER/LEAVE --- src/vmsrc/plvm01.s | 192 ++++++++++++++++++++++---------------------- src/vmsrc/plvm02.s | 48 ++--------- src/vmsrc/plvm03.s | 25 +++--- src/vmsrc/plvm802.s | 20 +---- 4 files changed, 119 insertions(+), 166 deletions(-) diff --git a/src/vmsrc/plvm01.s b/src/vmsrc/plvm01.s index 80b828e..8801fc9 100644 --- a/src/vmsrc/plvm01.s +++ b/src/vmsrc/plvm01.s @@ -9,7 +9,7 @@ SELFMODIFY = 1 ;* ;* VM ZERO PAGE LOCATIONS ;* - !SOURCE "vmsrc/plvmzp.inc" + !SOURCE "vmsrc/plvmzp.inc" DVSIGN = TMP+2 DROP = $EF NEXTOP = $F0 @@ -22,11 +22,11 @@ OPPAGE = OPIDX+1 ;* ;* INTERPRETER INSTRUCTION POINTER INCREMENT MACRO ;* - !MACRO INC_IP { - INY - BNE *+4 - INC IPH - } + !MACRO INC_IP { + INY + BNE *+4 + INC IPH +} ;* ;* INTERPRETER HEADER+INITIALIZATION ;* @@ -36,14 +36,14 @@ SEGBEGIN JMP VMINIT ;* SYSTEM INTERPRETER ENTRYPOINT ;* INTERP PLA - CLC - ADC #$01 + CLC + ADC #$01 STA IPL PLA - ADC #$00 + ADC #$00 STA IPH - LDY #$00 - JMP FETCHOP + LDY #$00 + JMP FETCHOP ;* ;* ENTER INTO USER BYTECODE INTERPRETER ;* @@ -51,14 +51,14 @@ IINTERP PLA STA TMPL PLA STA TMPH - LDY #$02 - LDA (TMP),Y - STA IPH - DEY - LDA (TMP),Y - STA IPL + LDY #$02 + LDA (TMP),Y + STA IPH DEY - JMP FETCHOP + LDA (TMP),Y + STA IPL + DEY + JMP FETCHOP ;* ;* MUL TOS-1 BY TOS ;* @@ -121,13 +121,13 @@ COMP LDA #$FF ;* !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 + !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 ;* ;* DIV TOS-1 BY TOS ;* @@ -921,90 +921,90 @@ CALLADR JSR $FFFF ;* ;* INDIRECT CALL TO ADDRESS (NATIVE CODE) ;* -ICAL LDA ESTKL,X - STA ICALADR+1 - LDA ESTKH,X - STA ICALADR+2 - INX - TYA - CLC - ADC IPL - PHA - LDA IPH - ADC #$00 - PHA -ICALADR JSR $FFFF - PLA - STA IPH - PLA - STA IPL - LDY #$01 - JMP FETCHOP +ICAL LDA ESTKL,X + STA ICALADR+1 + LDA ESTKH,X + STA ICALADR+2 + INX + TYA + CLC + ADC IPL + PHA + LDA IPH + ADC #$00 + PHA +ICALADR JSR $FFFF + PLA + STA IPH + PLA + STA IPL + LDY #$01 + JMP FETCHOP ;* ;* ENTER FUNCTION WITH FRAME SIZE AND PARAM COUNT ;* ENTER INY - LDA (IP),Y - PHA ; SAVE ON STACK FOR LEAVE - EOR #$FF - SEC - ADC IFPL - STA IFPL - BCS + - DEC IFPH -+ INY - LDA (IP),Y - BEQ + - ASL - TAY -- LDA ESTKH,X - DEY - STA (IFP),Y - LDA ESTKL,X - INX - DEY - STA (IFP),Y - BNE - -+ LDY #$03 - JMP FETCHOP + LDA (IP),Y + EOR #$FF + SEC + ADC IFPL + STA IFPL + BCS + + DEC IFPH ++ INY + LDA (IP),Y + BEQ + + ASL + TAY +- LDA ESTKH,X + DEY + STA (IFP),Y + LDA ESTKL,X + INX + DEY + STA (IFP),Y + BNE - ++ LDY #$03 + JMP FETCHOP ;* ;* LEAVE FUNCTION ;* -LEAVE PLA - CLC - ADC IFPL - STA IFPL - BCS LIFPH - RTS -LIFPH INC IFPH +LEAVE +INC_IP + LDA (IP),Y + CLC + ADC IFPL + STA IFPL + BCS LIFPH + RTS +LIFPH INC IFPH RET RTS A1CMD !SOURCE "vmsrc/a1cmd.a" -SEGEND = * -VMINIT LDY #$10 ; INSTALL PAGE 0 FETCHOP ROUTINE -- LDA PAGE0-1,Y - STA DROP-1,Y - DEY - BNE - - STY IFPL ; INIT FRAME POINTER - LDA #$80 - STA IFPH - LDA #SEGEND - STA SRCH - LDX #ESTKSZ/2 ; INIT EVAL STACK INDEX +SEGEND = * +VMINIT LDY #$10 ; INSTALL PAGE 0 FETCHOP ROUTINE +- LDA PAGE0-1,Y + STA DROP-1,Y + DEY + BNE - + STY IFPL ; INIT FRAME POINTER + LDA #$80 + STA IFPH + LDA #SEGEND + STA SRCH + LDX #ESTKSZ/2 ; INIT EVAL STACK INDEX JMP A1CMD PAGE0 = * !PSEUDOPC DROP { ;* ;* INTERP BYTECODE INNER LOOP ;* - INX ; DROP - INY ; NEXTOP - BEQ NEXTOPH - LDA $FFFF,Y ; FETCHOP @ $F3, IP MAPS OVER $FFFF @ $F4 - STA OPIDX - JMP (OPTBL) -NEXTOPH INC IPH - BNE FETCHOP + INX ; DROP + INY ; NEXTOP + BEQ NEXTOPH + LDA $FFFF,Y ; FETCHOP @ $F3, IP MAPS OVER $FFFF @ $F4 + STA OPIDX + JMP (OPTBL) +NEXTOPH INC IPH + BNE FETCHOP } diff --git a/src/vmsrc/plvm02.s b/src/vmsrc/plvm02.s index 3d65dc2..0ee3ebe 100755 --- a/src/vmsrc/plvm02.s +++ b/src/vmsrc/plvm02.s @@ -197,14 +197,6 @@ DINTRP PLA PLA ADC #$00 STA IPH - LDA IFPH - PHA ; SAVE ON STACK FOR LEAVE/RET - LDA IFPL - PHA ; SAVE ON STACK FOR LEAVE/RET - LDA PPL ; SET FP TO PP - STA IFPL - LDA PPH - STA IFPH LDY #$00 !IF SELFMODIFY { BEQ + @@ -224,14 +216,6 @@ IINTRP PLA LDA (TMP),Y STA IPL DEY - LDA IFPH - PHA ; SAVE ON STACK FOR LEAVE/RET - LDA IFPL - PHA ; SAVE ON STACK FOR LEAVE/RET - LDA PPL ; SET FP TO PP - STA IFPL - LDA PPH - STA IFPH + LDA #>OPTBL STA OPPAGE !IF SELFMODIFY { @@ -254,14 +238,6 @@ IINTRPX PHP LDA (TMP),Y STA IPL DEY - LDA IFPH - PHA ; SAVE ON STACK FOR LEAVE/RET - LDA IFPL - PHA ; SAVE ON STACK FOR LEAVE/RET - LDA PPL ; SET FP TO PP - STA IFPL - LDA PPH - STA IFPH LDA #>OPXTBL STA OPPAGE STA ALTRDON @@ -1540,7 +1516,11 @@ JMPTMP JMP (TMP) ;* ;* ENTER FUNCTION WITH FRAME SIZE AND PARAM COUNT ;* -ENTER INY +ENTER LDA IFPH + PHA ; SAVE ON STACK FOR LEAVE + LDA IFPL + PHA + INY LDA (IP),Y EOR #$FF ; ALLOCATE FRAME SEC @@ -1571,7 +1551,6 @@ ENTER INY ;* LEAVEX +INC_IP LDA (IP),Y - STA ALTRDOFF CLC ADC IFPL STA PPL @@ -1582,6 +1561,7 @@ LEAVEX +INC_IP STA IFPL PLA STA IFPH +RETX STA ALTRDOFF LDA PSR PHA PLP @@ -1598,20 +1578,6 @@ LEAVE +INC_IP STA IFPL PLA STA IFPH - RTS -; -RETX STA ALTRDOFF - LDA PSR - PHA - PLP -RET LDA IFPL ; DEALLOCATE POOL - STA PPL - LDA IFPH - STA PPH - PLA ; RESTORE PREVIOUS FRAME - STA IFPL - PLA - STA IFPH - RTS +RET RTS VMEND = * } diff --git a/src/vmsrc/plvm03.s b/src/vmsrc/plvm03.s index ef0c3a9..8dec521 100755 --- a/src/vmsrc/plvm03.s +++ b/src/vmsrc/plvm03.s @@ -130,6 +130,7 @@ INTERP PLA PLA ADC #$00 STA IPH + LDA IFPH PHA ; SAVE ON STACK FOR LEAVE/RET LDA IFPL @@ -138,6 +139,7 @@ INTERP PLA STA IFPL LDA PPH STA IFPH + LDY #$00 STY IPX JMP FETCHOP @@ -158,6 +160,7 @@ XINTERP PLA LDA (TMP),Y STA IPL DEY + LDA IFPH PHA ; SAVE ON STACK FOR LEAVE/RET LDA IFPL @@ -166,6 +169,7 @@ XINTERP PLA STA IFPL LDA PPH STA IFPH + JMP FETCHOP ;* ;* INTERNAL DIVIDE ALGORITHM @@ -1108,7 +1112,11 @@ ICALADR JSR $FFFF ;* ;* ENTER FUNCTION WITH FRAME SIZE AND PARAM COUNT ;* -ENTER INY +ENTER LDA IFPH + PHA ; SAVE ON STACK FOR LEAVE + LDA IFPL + PHA + INY LDA (IP),Y PHA ; SAVE ON STACK FOR LEAVE EOR #$FF @@ -1138,7 +1146,8 @@ ENTER INY ;* ;* LEAVE FUNCTION ;* -LEAVE PLA +LEAVE +INC_IP + LDA (IP),Y CLC ADC IFPL STA PPL @@ -1149,17 +1158,7 @@ LEAVE PLA STA IFPL PLA STA IFPH - RTS -; -RET LDA IFPL ; DEALLOCATE POOL - STA PPL - LDA IFPH - STA PPH - PLA ; RESTORE PREVIOUS FRAME - STA IFPL - PLA - STA IFPH - RTS +RET RTS SOSCMD = * !SOURCE "vmsrc/soscmd.a" SEGEND = * diff --git a/src/vmsrc/plvm802.s b/src/vmsrc/plvm802.s index 6e3b918..82caaa7 100644 --- a/src/vmsrc/plvm802.s +++ b/src/vmsrc/plvm802.s @@ -265,9 +265,6 @@ DINTRP PHP PLA INC STA IP - PEI (IFP) ; SAVE ON STACK FOR LEAVE/RET - LDA PP ; SET FP TO PP - STA IFP STX ESP TSX STX HWSP @@ -295,10 +292,7 @@ IINTRP PHP LDA (TOS,S),Y DEY STA IP - LDA IFP - STA TOS,S ; SAVE ON STACK FOR LEAVE/RET - LDA PP ; SET FP TO PP - STA IFP + PLA STX ESP TSX STX HWSP @@ -325,10 +319,7 @@ IINTRPX PHP LDA (TOS,S),Y DEY STA IP - LDA IFP - STA TOS,S ; SAVE ON STACK FOR LEAVE/RET - LDA PP ; SET FP TO PP - STA IFP + PLA STX ESP TSX STX HWSP @@ -1542,7 +1533,8 @@ JMPTMP JMP (TMP) ;* ;* ENTER FUNCTION WITH FRAME SIZE AND PARAM COUNT ;* -ENTER INY +ENTER PEI (IFP) ; SAVE ON STACK FOR LEAVE + INY LDA (IP),Y AND #$00FF !IF DEBUG { @@ -1684,10 +1676,6 @@ RET +ACCMEM8 ; 8 BIT A/M } TYX +ACCMEM16 - LDA IFP ; DEALLOCATE POOL - STA PP - PLA ; RESTORE PREVIOUS FRAME - STA IFP SEC ; SWITCH TO EMULATED MODE XCE !AS From d166b99eb025d3fa55c7d5ea5c7e6388a5b29000 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Thu, 18 Jan 2018 07:20:02 -0800 Subject: [PATCH 12/45] Fix 65802 HWSP state --- src/vmsrc/plvm802.s | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vmsrc/plvm802.s b/src/vmsrc/plvm802.s index 82caaa7..1b71cdb 100644 --- a/src/vmsrc/plvm802.s +++ b/src/vmsrc/plvm802.s @@ -1534,6 +1534,8 @@ JMPTMP JMP (TMP) ;* ENTER FUNCTION WITH FRAME SIZE AND PARAM COUNT ;* ENTER PEI (IFP) ; SAVE ON STACK FOR LEAVE + TSX ; REFLECT SP IN SAVED HWSP + STX HWSP INY LDA (IP),Y AND #$00FF From a3b12f9c28651acdc4b4e7a695a63c4ce66a2530 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Thu, 18 Jan 2018 16:56:21 -0800 Subject: [PATCH 13/45] John Brooks instruction fetch optimizations --- src/vmsrc/cmd.pla | 32 +++++++++-------- src/vmsrc/plvm02.s | 87 +++++++++++++++++++++++++--------------------- 2 files changed, 65 insertions(+), 54 deletions(-) diff --git a/src/vmsrc/cmd.pla b/src/vmsrc/cmd.pla index 34bc0dc..0b8e726 100755 --- a/src/vmsrc/cmd.pla +++ b/src/vmsrc/cmd.pla @@ -37,44 +37,46 @@ word version = $0100 // 01.00 word syspath word = getlnbuf word = @execmod -word = getlnbuf // // Working input buffer overlayed with strings table // byte cmdln = "" // +// Name for auto-run file (must follow cmdln) +// +byte autorun = "AUTORUN" +// // Standard Library exported functions. // byte sysmodstr = "CMDSYS" -byte machidstr = "MACHID" -byte sysstr = "SYSCALL" -byte callstr = "CALL" +byte putsstr = "PUTS" +byte putistr = "PUTI" byte putcstr = "PUTC" byte putlnstr = "PUTLN" -byte putsstr = "PUTS" byte putbstr = "PUTB" byte putwstr = "PUTH" -byte putistr = "PUTI" byte getcstr = "GETC" byte getsstr = "GETS" byte toupstr = "TOUPPER" +byte strcpystr = "STRCPY" +byte strcatstr = "STRCAT" byte hpmarkstr = "HEAPMARK" byte hpalignstr = "HEAPALLOCALIGN" byte hpallocstr = "HEAPALLOC" byte hprelstr = "HEAPRELEASE" byte hpavlstr = "HEAPAVAIL" +byte sysmods[] // overlay with exported strings word memsetstr = "MEMSET" byte memcpystr = "MEMCPY" byte uisgtstr = "ISUGT" byte uisgestr = "ISUGE" byte uisltstr = "ISULT" byte uislestr = "ISULE" -byte sysmods[] // overlay with exported strings -byte strcpystr = "STRCPY" -byte strcatstr = "STRCAT" byte sextstr = "SEXT" byte divmodstr = "DIVMOD" -byte autorun = "AUTORUN" +byte machidstr = "MACHID" +byte sysstr = "SYSCALL" +byte callstr = "CALL" byte prefix[] // overlay with exported symbols table word exports = @sysmodstr, @version word = @sysstr, @syscall @@ -1246,18 +1248,18 @@ def execsys(sysfile)#0 word len if ^sysfile - memcpy($280, sysfile, ^sysfile + 1) + strcpy($280, sysfile) striptrail(sysfile) refnum = open(sysfile) if refnum len = read(refnum, databuff, $FFFF) resetmemfiles() if len - memcpy(sysfile, $280, ^$280 + 1) + strcpy(sysfile, $280) if stripchars(sysfile) and ^$2000 == $4C and *$2003 == $EEEE stripspaces(sysfile) if ^$2005 >= ^sysfile + 1 - memcpy($2006, sysfile, ^sysfile + 1) + strcpy($2006, sysfile) fin fin striptrail($280) @@ -1312,8 +1314,8 @@ syspath = @sysmods // Update external interface table // autorun = open(@autorun) if autorun > 0 - cmdln = read(autorun, @sysmodstr, 128) - close(autorun) + cmdln = read(autorun, @autorun, 128) + close(0) else // // Print some startup info. diff --git a/src/vmsrc/plvm02.s b/src/vmsrc/plvm02.s index 0ee3ebe..94b46c0 100755 --- a/src/vmsrc/plvm02.s +++ b/src/vmsrc/plvm02.s @@ -44,7 +44,8 @@ PSR = TMP+2 DVSIGN = PSR+1 DROP = $EF NEXTOP = $F0 -FETCHOP = NEXTOP+3 +;FETCHOP = NEXTOP+3 +FETCHOP = NEXTOP+1 IP = FETCHOP+1 IPL = IP IPH = IPL+1 @@ -57,8 +58,12 @@ INTERP = $03D0 ;* !MACRO INC_IP { INY - BNE * + 4 + BPL + INC IPH + TYA + AND #$7F + TAY ++ } ;****************************** ;* * @@ -367,12 +372,12 @@ PAGE0 = * !PSEUDOPC DROP { INX ; DROP @ $EF INY ; NEXTOP @ $F0 - BEQ NEXTOPH +; BEQ NEXTOPH LDA $FFFF,Y ; FETCHOP @ $F3, IP MAPS OVER $FFFF @ $F4 STA OPIDX JMP (OPTBL) ; OPIDX AND OPPAGE MAP OVER OPTBL -NEXTOPH INC IPH - BNE FETCHOP +;NEXTOPH INC IPH +; BNE FETCHOP } PAGE3 = * ;* @@ -738,7 +743,7 @@ CB LDA #$00 ;* LA = * CW DEX - +INC_IP + INY ;+INC_IP LDA (IP),Y STA ESTKL,X +INC_IP @@ -749,7 +754,7 @@ CW DEX ;* CONSTANT STRING ;* CS DEX - +INC_IP + INY ;+INC_IP TYA ; NORMALIZE IP AND SAVE STRING ADDR ON ESTK CLC ADC IPL @@ -765,7 +770,7 @@ CS DEX JMP NEXTOP ; CSX DEX - +INC_IP + INY ;+INC_IP TYA ; NORMALIZE IP CLC ADC IPL @@ -987,7 +992,7 @@ LLWX +INC_IP ;* LOAD VALUE FROM ABSOLUTE ADDRESS ;* !IF SELFMODIFY { -LAB +INC_IP +LAB INY ;+INC_IP LDA (IP),Y STA LABLDA+1 +INC_IP @@ -1000,7 +1005,7 @@ LABLDA LDA $FFFF STA ESTKH,X JMP NEXTOP } ELSE { -LAB +INC_IP +LAB INY ;+INC_IP LDA (IP),Y STA TMPL +INC_IP @@ -1015,7 +1020,7 @@ LAB +INC_IP LDY IPY JMP NEXTOP } -LAW +INC_IP +LAW INY ;+INC_IP LDA (IP),Y STA TMPL +INC_IP @@ -1033,7 +1038,7 @@ LAW +INC_IP JMP NEXTOP ; !IF SELFMODIFY { -LABX +INC_IP +LABX INY ;+INC_IP LDA (IP),Y STA LABXLDA+1 +INC_IP @@ -1048,7 +1053,7 @@ LABXLDA LDA $FFFF STA ALTRDON JMP NEXTOP } ELSE { -LABX +INC_IP +LABX INY ;+INC_IP LDA (IP),Y STA TMPL +INC_IP @@ -1065,7 +1070,7 @@ LABX +INC_IP LDY IPY JMP NEXTOP } -LAWX +INC_IP +LAWX INY ;+INC_IP LDA (IP),Y STA TMPL +INC_IP @@ -1157,7 +1162,7 @@ DLB +INC_IP STA (IFP),Y LDY IPY JMP NEXTOP -DLW +INC_IP +DLW +INC_IP LDA (IP),Y STY IPY TAY @@ -1172,7 +1177,7 @@ DLW +INC_IP ;* STORE VALUE TO ABSOLUTE ADDRESS ;* !IF SELFMODIFY { -SAB +INC_IP +SAB INY ;+INC_IP LDA (IP),Y STA SABSTA+1 +INC_IP @@ -1184,7 +1189,7 @@ SABSTA STA $FFFF ; JMP NEXTOP JMP DROP } ELSE { -SAB +INC_IP +SAB INY ;+INC_IP LDA (IP),Y STA TMPL +INC_IP @@ -1197,7 +1202,7 @@ SAB +INC_IP LDY IPY JMP DROP } -SAW +INC_IP +SAW INY ;+INC_IP LDA (IP),Y STA TMPL +INC_IP @@ -1216,7 +1221,7 @@ SAW +INC_IP ;* STORE VALUE TO ABSOLUTE ADDRESS WITHOUT POPPING STACK ;* !IF SELFMODIFY { -DAB +INC_IP +DAB INY ;+INC_IP LDA (IP),Y STA DABSTA+1 +INC_IP @@ -1226,7 +1231,7 @@ DAB +INC_IP DABSTA STA $FFFF JMP NEXTOP } ELSE { -DAB +INC_IP +DAB INY ;+INC_IP LDA (IP),Y STA TMPL +INC_IP @@ -1239,7 +1244,7 @@ DAB +INC_IP LDY IPY JMP NEXTOP } -DAW +INC_IP +DAW INY ;+INC_IP LDA (IP),Y STA TMPL +INC_IP @@ -1321,29 +1326,33 @@ BRTRU INX LDA ESTKH-1,X ORA ESTKL-1,X BNE BRNCH -NOBRNCH +INC_IP +NOBRNCH INY ;+INC_IP +INC_IP JMP NEXTOP BRFLS INX LDA ESTKH-1,X ORA ESTKL-1,X BNE NOBRNCH -BRNCH LDA IPH - STA TMPH - LDA IPL - +INC_IP +BRNCH TYA ; FLATTEN IP CLC - ADC (IP),Y + ADC IPL STA TMPL - LDA TMPH - +INC_IP - ADC (IP),Y + LDA #$00 + ADC IPH + STA TMPH ; ADD BRANCH OFFSET + INY + LDA (IP),Y + CLC + ADC TMPL + STA TMPL + INY + LDA (IP),Y + ADC TMPH STA IPH LDA TMPL STA IPL - DEY - DEY - JMP NEXTOP + LDY #$01 + JMP FETCHOP BREQ INX LDA ESTKL-1,X CMP ESTKL,X @@ -1385,10 +1394,10 @@ IBRNCH LDA IPL ;* ;* CALL INTO ABSOLUTE ADDRESS (NATIVE CODE) ;* -CALL +INC_IP +CALL INY ;+INC_IP LDA (IP),Y STA TMPL - +INC_IP + INY ;+INC_IP LDA (IP),Y STA TMPH TYA @@ -1412,10 +1421,10 @@ CALL +INC_IP LDY #$01 JMP FETCHOP ; -CALLX +INC_IP +CALLX INY ;+INC_IP LDA (IP),Y STA TMPL - +INC_IP + INY ;+INC_IP LDA (IP),Y STA TMPH TYA @@ -1549,7 +1558,7 @@ ENTER LDA IFPH ;* ;* LEAVE FUNCTION ;* -LEAVEX +INC_IP +LEAVEX INY ;+INC_IP LDA (IP),Y CLC ADC IFPL @@ -1566,7 +1575,7 @@ RETX STA ALTRDOFF PHA PLP RTS -LEAVE +INC_IP +LEAVE INY ;+INC_IP LDA (IP),Y CLC ADC IFPL From e06a217f33db3d2a7ea5e64efc1c725f9fc30d49 Mon Sep 17 00:00:00 2001 From: Dave Schmenk Date: Thu, 18 Jan 2018 20:27:53 -0800 Subject: [PATCH 14/45] Switch all VMs to lazy IP update --- src/vmsrc/plvm01.s | 1379 +++++++++++++++++++++---------------------- src/vmsrc/plvm02.s | 8 +- src/vmsrc/plvm03.s | 83 ++- src/vmsrc/plvm802.s | 92 ++- 4 files changed, 768 insertions(+), 794 deletions(-) diff --git a/src/vmsrc/plvm01.s b/src/vmsrc/plvm01.s index 8801fc9..ea4b51c 100644 --- a/src/vmsrc/plvm01.s +++ b/src/vmsrc/plvm01.s @@ -13,7 +13,7 @@ SELFMODIFY = 1 DVSIGN = TMP+2 DROP = $EF NEXTOP = $F0 -FETCHOP = NEXTOP+3 +FETCHOP = NEXTOP+1 IP = FETCHOP+1 IPL = IP IPH = IPL+1 @@ -24,13 +24,17 @@ OPPAGE = OPIDX+1 ;* !MACRO INC_IP { INY - BNE *+4 - INC IPH -} + BPL + + INC IPH + TYA + AND #$7F + TAY ++ + } ;* ;* INTERPRETER HEADER+INITIALIZATION ;* - *= $0280 + *= $0280 SEGBEGIN JMP VMINIT ;* ;* SYSTEM INTERPRETER ENTRYPOINT @@ -58,76 +62,74 @@ IINTERP PLA LDA (TMP),Y STA IPL DEY - JMP FETCHOP + JMP FETCHOP ;* ;* MUL TOS-1 BY TOS ;* -MUL STY IPY - LDY #$10 - LDA ESTKL+1,X - EOR #$FF - STA TMPL - LDA ESTKH+1,X - EOR #$FF - STA TMPH - LDA #$00 - STA ESTKL+1,X ; PRODL -; STA ESTKH+1,X ; PRODH -MULLP LSR TMPH ; MULTPLRH - ROR TMPL ; MULTPLRL - BCS + - STA ESTKH+1,X ; PRODH - LDA ESTKL,X ; MULTPLNDL - ADC ESTKL+1,X ; PRODL - STA ESTKL+1,X - LDA ESTKH,X ; MULTPLNDH - ADC ESTKH+1,X ; PRODH -+ ASL ESTKL,X ; MULTPLNDL - ROL ESTKH,X ; MULTPLNDH - DEY - BNE MULLP - STA ESTKH+1,X ; PRODH - LDY IPY -; INX -; JMP NEXTOP +MUL STY IPY + LDY #$10 + LDA ESTKL+1,X + EOR #$FF + STA TMPL + LDA ESTKH+1,X + EOR #$FF + STA TMPH + LDA #$00 + STA ESTKL+1,X ; PRODL +; STA ESTKH+1,X ; PRODH +MULLP LSR TMPH ; MULTPLRH + ROR TMPL ; MULTPLRL + BCS + + STA ESTKH+1,X ; PRODH + LDA ESTKL,X ; MULTPLNDL + ADC ESTKL+1,X ; PRODL + STA ESTKL+1,X + LDA ESTKH,X ; MULTPLNDH + ADC ESTKH+1,X ; PRODH ++ ASL ESTKL,X ; MULTPLNDL + ROL ESTKH,X ; MULTPLNDH + DEY + BNE MULLP + STA ESTKH+1,X ; PRODH + LDY IPY JMP DROP ;* ;* INCREMENT TOS ;* -INCR INC ESTKL,X - BNE INCR1 - INC ESTKH,X -INCR1 JMP NEXTOP +INCR INC ESTKL,X + BNE INCR1 + INC ESTKH,X +INCR1 JMP NEXTOP ;* ;* DECREMENT TOS ;* -DECR LDA ESTKL,X - BNE DECR1 - DEC ESTKH,X -DECR1 DEC ESTKL,X - JMP NEXTOP +DECR LDA ESTKL,X + BNE DECR1 + DEC ESTKH,X +DECR1 DEC ESTKL,X + JMP NEXTOP ;* ;* BITWISE COMPLIMENT TOS ;* -COMP LDA #$FF - EOR ESTKL,X - STA ESTKL,X - LDA #$FF - EOR ESTKH,X - STA ESTKH,X - JMP NEXTOP +COMP LDA #$FF + EOR ESTKL,X + STA ESTKL,X + LDA #$FF + EOR ESTKH,X + STA ESTKH,X + JMP NEXTOP ;* ;* 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 +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 + !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 ;* ;* DIV TOS-1 BY TOS ;* @@ -165,766 +167,748 @@ DIVMOD JSR _DIV ;* ;* NEGATE TOS ;* -NEG LDA #$00 - SEC - SBC ESTKL,X - STA ESTKL,X - LDA #$00 - SBC ESTKH,X - STA ESTKH,X - JMP NEXTOP +NEG LDA #$00 + SEC + SBC ESTKL,X + STA ESTKL,X + LDA #$00 + SBC ESTKH,X + STA ESTKH,X + JMP NEXTOP ;* ;* INTERNAL DIVIDE ALGORITHM ;* -_NEG LDA #$00 - SEC - SBC ESTKL,X - STA ESTKL,X - LDA #$00 - SBC ESTKH,X - STA ESTKH,X - RTS -_DIV STY IPY - LDY #$11 ; #BITS+1 - LDA #$00 - STA TMPL ; REMNDRL - STA TMPH ; REMNDRH - LDA ESTKH,X - AND #$80 - STA DVSIGN - BPL + - JSR _NEG - INC DVSIGN -+ LDA ESTKH+1,X - BPL + - INX - JSR _NEG - DEX - INC DVSIGN - BNE _DIV1 -+ ORA ESTKL+1,X ; DVDNDL - BEQ _DIVEX -_DIV1 ASL ESTKL+1,X ; DVDNDL - ROL ESTKH+1,X ; DVDNDH - DEY - BCC _DIV1 -_DIVLP ROL TMPL ; REMNDRL - ROL TMPH ; REMNDRH - LDA TMPL ; REMNDRL - CMP ESTKL,X ; DVSRL - LDA TMPH ; REMNDRH - SBC ESTKH,X ; DVSRH - BCC + - STA TMPH ; REMNDRH - LDA TMPL ; REMNDRL - SBC ESTKL,X ; DVSRL - STA TMPL ; REMNDRL - SEC -+ ROL ESTKL+1,X ; DVDNDL - ROL ESTKH+1,X ; DVDNDH - DEY - BNE _DIVLP +_NEG LDA #$00 + SEC + SBC ESTKL,X + STA ESTKL,X + LDA #$00 + SBC ESTKH,X + STA ESTKH,X + RTS +_DIV STY IPY + LDY #$11 ; #BITS+1 + LDA #$00 + STA TMPL ; REMNDRL + STA TMPH ; REMNDRH + LDA ESTKH,X + AND #$80 + STA DVSIGN + BPL + + JSR _NEG + INC DVSIGN ++ LDA ESTKH+1,X + BPL + + INX + JSR _NEG + DEX + INC DVSIGN + BNE _DIV1 ++ ORA ESTKL+1,X ; DVDNDL + BEQ _DIVEX +_DIV1 ASL ESTKL+1,X ; DVDNDL + ROL ESTKH+1,X ; DVDNDH + DEY + BCC _DIV1 +_DIVLP ROL TMPL ; REMNDRL + ROL TMPH ; REMNDRH + LDA TMPL ; REMNDRL + CMP ESTKL,X ; DVSRL + LDA TMPH ; REMNDRH + SBC ESTKH,X ; DVSRH + BCC + + STA TMPH ; REMNDRH + LDA TMPL ; REMNDRL + SBC ESTKL,X ; DVSRL + STA TMPL ; REMNDRL + SEC ++ ROL ESTKL+1,X ; DVDNDL + ROL ESTKH+1,X ; DVDNDH + DEY + BNE _DIVLP _DIVEX INX - LDY IPY - RTS + LDY IPY + RTS ;* ;* ADD TOS TO TOS-1 ;* -ADD LDA ESTKL,X - CLC - ADC ESTKL+1,X - STA ESTKL+1,X - LDA ESTKH,X - ADC ESTKH+1,X - STA ESTKH+1,X -; INX -; JMP NEXTOP - JMP DROP +ADD LDA ESTKL,X + CLC + ADC ESTKL+1,X + STA ESTKL+1,X + LDA ESTKH,X + ADC ESTKH+1,X + STA ESTKH+1,X + JMP DROP ;* ;* SUB TOS FROM TOS-1 ;* -SUB LDA ESTKL+1,X - SEC - SBC ESTKL,X - STA ESTKL+1,X - LDA ESTKH+1,X - SBC ESTKH,X - STA ESTKH+1,X -; INX -; JMP NEXTOP - JMP DROP +SUB LDA ESTKL+1,X + SEC + SBC ESTKL,X + STA ESTKL+1,X + LDA ESTKH+1,X + SBC ESTKH,X + STA ESTKH+1,X + JMP DROP ; ;* ;* SHIFT TOS LEFT BY 1, ADD TO TOS-1 ;* -IDXW LDA ESTKL,X - ASL - ROL ESTKH,X - CLC - ADC ESTKL+1,X - STA ESTKL+1,X - LDA ESTKH,X - ADC ESTKH+1,X - STA ESTKH+1,X -; INX -; JMP NEXTOP - JMP DROP +IDXW LDA ESTKL,X + ASL + ROL ESTKH,X + CLC + ADC ESTKL+1,X + STA ESTKL+1,X + LDA ESTKH,X + ADC ESTKH+1,X + STA ESTKH+1,X + JMP DROP ;* ;* BITWISE AND TOS TO TOS-1 ;* -BAND LDA ESTKL+1,X - AND ESTKL,X - STA ESTKL+1,X - LDA ESTKH+1,X - AND ESTKH,X - STA ESTKH+1,X -; INX -; JMP NEXTOP - JMP DROP +BAND LDA ESTKL+1,X + AND ESTKL,X + STA ESTKL+1,X + LDA ESTKH+1,X + AND ESTKH,X + STA ESTKH+1,X + JMP DROP ;* ;* INCLUSIVE OR TOS TO TOS-1 ;* -IOR LDA ESTKL+1,X - ORA ESTKL,X - STA ESTKL+1,X - LDA ESTKH+1,X - ORA ESTKH,X - STA ESTKH+1,X -; INX -; JMP NEXTOP - JMP DROP +IOR LDA ESTKL+1,X + ORA ESTKL,X + STA ESTKL+1,X + LDA ESTKH+1,X + ORA ESTKH,X + STA ESTKH+1,X + JMP DROP ;* ;* EXLUSIVE OR TOS TO TOS-1 ;* -XOR LDA ESTKL+1,X - EOR ESTKL,X - STA ESTKL+1,X - LDA ESTKH+1,X - EOR ESTKH,X - STA ESTKH+1,X -; INX -; JMP NEXTOP - JMP DROP +XOR LDA ESTKL+1,X + EOR ESTKL,X + STA ESTKL+1,X + LDA ESTKH+1,X + EOR ESTKH,X + STA ESTKH+1,X + JMP DROP ;* ;* SHIFT TOS-1 LEFT BY TOS ;* SHL STY IPY - LDA ESTKL,X - CMP #$08 - BCC SHL1 - LDY ESTKL+1,X - STY ESTKH+1,X - LDY #$00 - STY ESTKL+1,X - SBC #$08 + LDA ESTKL,X + CMP #$08 + BCC SHL1 + LDY ESTKL+1,X + STY ESTKH+1,X + LDY #$00 + STY ESTKL+1,X + SBC #$08 SHL1 TAY - BEQ SHL3 -SHL2 ASL ESTKL+1,X - ROL ESTKH+1,X - DEY - BNE SHL2 -SHL3 LDY IPY -; INX -; JMP NEXTOP - JMP DROP + BEQ SHL3 +SHL2 ASL ESTKL+1,X + ROL ESTKH+1,X + DEY + BNE SHL2 +SHL3 LDY IPY + JMP DROP ;* ;* SHIFT TOS-1 RIGHT BY TOS ;* -SHR STY IPY - LDA ESTKL,X - CMP #$08 - BCC SHR2 - LDY ESTKH+1,X - STY ESTKL+1,X - CPY #$80 - LDY #$00 - BCC SHR1 - DEY -SHR1 STY ESTKH+1,X - SEC - SBC #$08 +SHR STY IPY + LDA ESTKL,X + CMP #$08 + BCC SHR2 + LDY ESTKH+1,X + STY ESTKL+1,X + CPY #$80 + LDY #$00 + BCC SHR1 + DEY +SHR1 STY ESTKH+1,X + SEC + SBC #$08 SHR2 TAY - BEQ SHR4 - LDA ESTKH+1,X -SHR3 CMP #$80 - ROR - ROR ESTKL+1,X - DEY - BNE SHR3 - STA ESTKH+1,X -SHR4 LDY IPY -; INX -; JMP NEXTOP - JMP DROP + BEQ SHR4 + LDA ESTKH+1,X +SHR3 CMP #$80 + ROR + ROR ESTKL+1,X + DEY + BNE SHR3 + STA ESTKH+1,X +SHR4 LDY IPY + JMP DROP ;* ;* LOGICAL NOT ;* -LNOT LDA ESTKL,X - ORA ESTKH,X - BEQ LNOT1 - LDA #$FF -LNOT1 EOR #$FF - STA ESTKL,X - STA ESTKH,X - JMP NEXTOP +LNOT LDA ESTKL,X + ORA ESTKH,X + BEQ LNOT1 + LDA #$FF +LNOT1 EOR #$FF + STA ESTKL,X + STA ESTKH,X + JMP NEXTOP ;* ;* LOGICAL AND ;* -LAND LDA ESTKL+1,X - ORA ESTKH+1,X - BEQ LAND2 - LDA ESTKL,X - ORA ESTKH,X - BEQ LAND1 - LDA #$FF -LAND1 STA ESTKL+1,X - STA ESTKH+1,X -;LAND2 INX -; JMP NEXTOP -LAND2 JMP DROP +LAND LDA ESTKL+1,X + ORA ESTKH+1,X + BEQ LAND2 + LDA ESTKL,X + ORA ESTKH,X + BEQ LAND1 + LDA #$FF +LAND1 STA ESTKL+1,X + STA ESTKH+1,X +LAND2 JMP DROP ;* ;* LOGICAL OR ;* -LOR LDA ESTKL,X - ORA ESTKH,X - ORA ESTKL+1,X - ORA ESTKH+1,X - BEQ LOR1 - LDA #$FF - STA ESTKL+1,X - STA ESTKH+1,X -;LOR1 INX -; JMP NEXTOP -LOR1 JMP DROP +LOR LDA ESTKL,X + ORA ESTKH,X + ORA ESTKL+1,X + ORA ESTKH+1,X + BEQ LOR1 + LDA #$FF + STA ESTKL+1,X + STA ESTKH+1,X +LOR1 JMP DROP ;* ;* DUPLICATE TOS ;* DUP DEX - LDA ESTKL+1,X - STA ESTKL,X - LDA ESTKH+1,X - STA ESTKH,X - JMP NEXTOP + LDA ESTKL+1,X + STA ESTKL,X + LDA ESTKH+1,X + STA ESTKH,X + JMP NEXTOP ;* ;* CONSTANT ;* ZERO DEX - LDA #$00 - STA ESTKL,X - 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 - DEX - STA ESTKH,X - +INC_IP - LDA (IP),Y - STA ESTKL,X - JMP NEXTOP + LDA #$00 + STA ESTKL,X + 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 + DEX + STA ESTKH,X + +INC_IP + LDA (IP),Y + STA ESTKL,X + JMP NEXTOP ;* ;* LOAD ADDRESS & LOAD CONSTANT WORD (SAME THING, WITH OR WITHOUT FIXUP) ;* -LA = * -CW DEX - +INC_IP - LDA (IP),Y - STA ESTKL,X - +INC_IP - LDA (IP),Y - STA ESTKH,X - JMP NEXTOP +LA = * +CW DEX + INY ;+INC_IP + LDA (IP),Y + STA ESTKL,X + +INC_IP + LDA (IP),Y + STA ESTKH,X + JMP NEXTOP ;* ;* CONSTANT STRING ;* -CS DEX - +INC_IP - TYA ; NORMALIZE IP AND SAVE STRING ADDR ON ESTK - CLC - ADC IPL - STA IPL - STA ESTKL,X - LDA #$00 - TAY - ADC IPH - STA IPH - STA ESTKH,X - LDA (IP),Y - TAY - JMP NEXTOP +CS DEX + INY ;+INC_IP + TYA ; NORMALIZE IP AND SAVE STRING ADDR ON ESTK + CLC + ADC IPL + STA IPL + STA ESTKL,X + LDA #$00 + TAY + ADC IPH + STA IPH + STA ESTKH,X + LDA (IP),Y + TAY + JMP NEXTOP ;* ;* LOAD VALUE FROM ADDRESS TAG ;* -!IF SELFMODIFY { -LB LDA ESTKL,X - STA LBLDA+1 - LDA ESTKH,X - STA LBLDA+2 -LBLDA LDA $FFFF - STA ESTKL,X - LDA #$00 - STA ESTKH,X - JMP NEXTOP +!IF SELFMODIFY { +LB LDA ESTKL,X + STA LBLDA+1 + LDA ESTKH,X + STA LBLDA+2 +LBLDA LDA $FFFF + STA ESTKL,X + LDA #$00 + STA ESTKH,X + JMP NEXTOP } ELSE { -LB LDA ESTKL,X - STA TMPL - LDA ESTKH,X - STA TMPH - STY IPY - LDY #$00 - LDA (TMP),Y - STA ESTKL,X - STY ESTKH,X - LDY IPY - JMP NEXTOP +LB LDA ESTKL,X + STA TMPL + LDA ESTKH,X + STA TMPH + STY IPY + LDY #$00 + LDA (TMP),Y + STA ESTKL,X + STY ESTKH,X + LDY IPY + JMP NEXTOP } -LW LDA ESTKL,X - STA TMPL - LDA ESTKH,X - STA TMPH - STY IPY - LDY #$00 - LDA (TMP),Y - STA ESTKL,X - INY - LDA (TMP),Y - STA ESTKH,X - LDY IPY - JMP NEXTOP +LW LDA ESTKL,X + STA TMPL + LDA ESTKH,X + STA TMPH + STY IPY + LDY #$00 + LDA (TMP),Y + STA ESTKL,X + INY + LDA (TMP),Y + STA ESTKH,X + LDY IPY + JMP NEXTOP ;* ;* LOAD ADDRESS OF LOCAL FRAME OFFSET ;* LLA +INC_IP - LDA (IP),Y - DEX - CLC - ADC IFPL - STA ESTKL,X - LDA #$00 - ADC IFPH - STA ESTKH,X - JMP NEXTOP + LDA (IP),Y + DEX + CLC + ADC IFPL + STA ESTKL,X + LDA #$00 + ADC IFPH + STA ESTKH,X + JMP NEXTOP ;* ;* LOAD VALUE FROM LOCAL FRAME OFFSET ;* LLB +INC_IP - LDA (IP),Y - STY IPY - TAY - DEX - LDA (IFP),Y - STA ESTKL,X - LDA #$00 - STA ESTKH,X - LDY IPY - JMP NEXTOP + LDA (IP),Y + STY IPY + TAY + DEX + LDA (IFP),Y + STA ESTKL,X + LDA #$00 + STA ESTKH,X + LDY IPY + JMP NEXTOP LLW +INC_IP - LDA (IP),Y - STY IPY - TAY - DEX - LDA (IFP),Y - STA ESTKL,X - INY - LDA (IFP),Y - STA ESTKH,X - LDY IPY - JMP NEXTOP + LDA (IP),Y + STY IPY + TAY + DEX + LDA (IFP),Y + STA ESTKL,X + INY + LDA (IFP),Y + STA ESTKH,X + LDY IPY + JMP NEXTOP ;* ;* LOAD VALUE FROM ABSOLUTE ADDRESS ;* -!IF SELFMODIFY { -LAB +INC_IP - LDA (IP),Y - STA LABLDA+1 - +INC_IP - LDA (IP),Y - STA LABLDA+2 -LABLDA LDA $FFFF - DEX - STA ESTKL,X - LDA #$00 - STA ESTKH,X - JMP NEXTOP +!IF SELFMODIFY { +LAB INY ;+INC_IP + LDA (IP),Y + STA LABLDA+1 + +INC_IP + LDA (IP),Y + STA LABLDA+2 +LABLDA LDA $FFFF + DEX + STA ESTKL,X + LDA #$00 + STA ESTKH,X + JMP NEXTOP } ELSE { -LAB +INC_IP - LDA (IP),Y - STA TMPL - +INC_IP - LDA (IP),Y - STA TMPH - STY IPY - LDY #$00 - LDA (TMP),Y - DEX - STA ESTKL,X - STY ESTKH,X - LDY IPY - JMP NEXTOP +LAB INY ;+INC_IP + LDA (IP),Y + STA TMPL + +INC_IP + LDA (IP),Y + STA TMPH + STY IPY + LDY #$00 + LDA (TMP),Y + DEX + STA ESTKL,X + STY ESTKH,X + LDY IPY + JMP NEXTOP } -LAW +INC_IP - LDA (IP),Y - STA TMPL - +INC_IP - LDA (IP),Y - STA TMPH - STY IPY - LDY #$00 - LDA (TMP),Y - DEX - STA ESTKL,X - INY - LDA (TMP),Y - STA ESTKH,X - LDY IPY - JMP NEXTOP +LAW INY ;+INC_IP + LDA (IP),Y + STA TMPL + +INC_IP + LDA (IP),Y + STA TMPH + STY IPY + LDY #$00 + LDA (TMP),Y + DEX + STA ESTKL,X + INY + LDA (TMP),Y + STA ESTKH,X + LDY IPY + JMP NEXTOP ;* ;* STORE VALUE TO ADDRESS ;* -!IF SELFMODIFY { -SB LDA ESTKL,X - STA SBSTA+1 - LDA ESTKH,X - STA SBSTA+2 - LDA ESTKL+1,X -SBSTA STA $FFFF - INX -; INX -; JMP NEXTOP - JMP DROP +!IF SELFMODIFY { +SB LDA ESTKL,X + STA SBSTA+1 + LDA ESTKH,X + STA SBSTA+2 + LDA ESTKL+1,X +SBSTA STA $FFFF + INX + JMP DROP } ELSE { -SB LDA ESTKL,X - STA TMPL - LDA ESTKH,X - STA TMPH - LDA ESTKL+1,X - STY IPY - LDY #$00 - STA (TMP),Y - LDY IPY - INX -; INX -; JMP NEXTOP - JMP DROP +SB LDA ESTKL,X + STA TMPL + LDA ESTKH,X + STA TMPH + LDA ESTKL+1,X + STY IPY + LDY #$00 + STA (TMP),Y + LDY IPY + INX + JMP DROP } -SW LDA ESTKL,X - STA TMPL - LDA ESTKH,X - STA TMPH - STY IPY - LDY #$00 - LDA ESTKL+1,X - STA (TMP),Y - INY - LDA ESTKH+1,X - STA (TMP),Y - LDY IPY - INX -; INX -; JMP NEXTOP - JMP DROP +SW LDA ESTKL,X + STA TMPL + LDA ESTKH,X + STA TMPH + STY IPY + LDY #$00 + LDA ESTKL+1,X + STA (TMP),Y + INY + LDA ESTKH+1,X + STA (TMP),Y + LDY IPY + INX + JMP DROP ;* ;* STORE VALUE TO LOCAL FRAME OFFSET ;* SLB +INC_IP - LDA (IP),Y - STY IPY - TAY - LDA ESTKL,X - STA (IFP),Y - LDY IPY -; INX -; JMP NEXTOP - JMP DROP + LDA (IP),Y + STY IPY + TAY + LDA ESTKL,X + STA (IFP),Y + LDY IPY + JMP DROP SLW +INC_IP - LDA (IP),Y - STY IPY - TAY - LDA ESTKL,X - STA (IFP),Y - INY - LDA ESTKH,X - STA (IFP),Y - LDY IPY -; INX -; JMP NEXTOP - JMP DROP + LDA (IP),Y + STY IPY + TAY + LDA ESTKL,X + STA (IFP),Y + INY + LDA ESTKH,X + STA (IFP),Y + LDY IPY + JMP DROP ;* ;* STORE VALUE TO LOCAL FRAME OFFSET WITHOUT POPPING STACK ;* DLB +INC_IP - LDA (IP),Y - STY IPY - TAY - LDA ESTKL,X - STA (IFP),Y - LDY IPY - JMP NEXTOP + LDA (IP),Y + STY IPY + TAY + LDA ESTKL,X + STA (IFP),Y + LDY IPY + JMP NEXTOP DLW +INC_IP - LDA (IP),Y - STY IPY - TAY - LDA ESTKL,X - STA (IFP),Y - INY - LDA ESTKH,X - STA (IFP),Y - LDY IPY - JMP NEXTOP + LDA (IP),Y + STY IPY + TAY + LDA ESTKL,X + STA (IFP),Y + INY + LDA ESTKH,X + STA (IFP),Y + LDY IPY + JMP NEXTOP ;* ;* STORE VALUE TO ABSOLUTE ADDRESS ;* -!IF SELFMODIFY { -SAB +INC_IP - LDA (IP),Y - STA SABSTA+1 - +INC_IP - LDA (IP),Y - STA SABSTA+2 - LDA ESTKL,X -SABSTA STA $FFFF -; INX -; JMP NEXTOP - JMP DROP +!IF SELFMODIFY { +SAB INY ;+INC_IP + LDA (IP),Y + STA SABSTA+1 + +INC_IP + LDA (IP),Y + STA SABSTA+2 + LDA ESTKL,X +SABSTA STA $FFFF + JMP DROP } ELSE { -SAB +INC_IP - LDA (IP),Y - STA TMPL - +INC_IP - LDA (IP),Y - STA TMPH - LDA ESTKL,X - STY IPY - LDY #$00 - STA (TMP),Y - LDY IPY -; INX -; JMP NEXTOP - JMP DROP +SAB INY ;+INC_IP + LDA (IP),Y + STA TMPL + +INC_IP + LDA (IP),Y + STA TMPH + LDA ESTKL,X + STY IPY + LDY #$00 + STA (TMP),Y + LDY IPY + JMP DROP } -SAW +INC_IP - LDA (IP),Y - STA TMPL - +INC_IP - LDA (IP),Y - STA TMPH - STY IPY - LDY #$00 - LDA ESTKL,X - STA (TMP),Y - INY - LDA ESTKH,X - STA (TMP),Y - LDY IPY -; INX -; JMP NEXTOP - JMP DROP +SAW INY ;+INC_IP + LDA (IP),Y + STA TMPL + +INC_IP + LDA (IP),Y + STA TMPH + STY IPY + LDY #$00 + LDA ESTKL,X + STA (TMP),Y + INY + LDA ESTKH,X + STA (TMP),Y + LDY IPY + JMP DROP ;* ;* STORE VALUE TO ABSOLUTE ADDRESS WITHOUT POPPING STACK ;* -!IF SELFMODIFY { -DAB +INC_IP - LDA (IP),Y - STA DABSTA+1 - +INC_IP - LDA (IP),Y - STA DABSTA+2 - LDA ESTKL,X -DABSTA STA $FFFF - JMP NEXTOP +!IF SELFMODIFY { +DAB INY ;+INC_IP + LDA (IP),Y + STA DABSTA+1 + +INC_IP + LDA (IP),Y + STA DABSTA+2 + LDA ESTKL,X +DABSTA STA $FFFF + JMP NEXTOP } ELSE { -DAB +INC_IP - LDA (IP),Y - STA TMPL - +INC_IP - LDA (IP),Y - STA TMPH - STY IPY - LDY #$00 - LDA ESTKL,X - STA (TMP),Y - LDY IPY - JMP NEXTOP +DAB INY ;+INC_IP + LDA (IP),Y + STA TMPL + +INC_IP + LDA (IP),Y + STA TMPH + STY IPY + LDY #$00 + LDA ESTKL,X + STA (TMP),Y + LDY IPY + JMP NEXTOP } -DAW +INC_IP - LDA (IP),Y - STA TMPL - +INC_IP - LDA (IP),Y - STA TMPH - STY IPY - LDY #$00 - LDA ESTKL,X - STA (TMP),Y - INY - LDA ESTKH,X - STA (TMP),Y - LDY IPY - JMP NEXTOP +DAW INY ;+INC_IP + LDA (IP),Y + STA TMPL + +INC_IP + LDA (IP),Y + STA TMPH + STY IPY + LDY #$00 + LDA ESTKL,X + STA (TMP),Y + INY + LDA ESTKH,X + STA (TMP),Y + LDY IPY + JMP NEXTOP ;* ;* COMPARES ;* -ISEQ LDA ESTKL,X - CMP ESTKL+1,X - BNE ISFLS - LDA ESTKH,X - CMP ESTKH+1,X - BNE ISFLS -ISTRU LDA #$FF - STA ESTKL+1,X - STA ESTKH+1,X -; INX -; JMP NEXTOP - JMP DROP +ISEQ LDA ESTKL,X + CMP ESTKL+1,X + BNE ISFLS + LDA ESTKH,X + CMP ESTKH+1,X + BNE ISFLS +ISTRU LDA #$FF + STA ESTKL+1,X + STA ESTKH+1,X + JMP DROP ; -ISNE LDA ESTKL,X - CMP ESTKL+1,X - BNE ISTRU - LDA ESTKH,X - CMP ESTKH+1,X - BNE ISTRU -ISFLS LDA #$00 - STA ESTKL+1,X - STA ESTKH+1,X -; INX -; JMP NEXTOP - JMP DROP +ISNE LDA ESTKL,X + CMP ESTKL+1,X + BNE ISTRU + LDA ESTKH,X + CMP ESTKH+1,X + BNE ISTRU +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 - SBC ESTKH,X - BVC ISGE1 - EOR #$80 -ISGE1 BPL ISTRU - BMI ISFLS +ISGE LDA ESTKL+1,X + CMP ESTKL,X + LDA ESTKH+1,X + SBC ESTKH,X + BVC ISGE1 + EOR #$80 +ISGE1 BPL ISTRU + BMI ISFLS ; -ISGT LDA ESTKL,X - CMP ESTKL+1,X - LDA ESTKH,X - SBC ESTKH+1,X - BVC ISGT1 - EOR #$80 -ISGT1 BMI ISTRU - BPL ISFLS +ISGT LDA ESTKL,X + CMP ESTKL+1,X + LDA ESTKH,X + SBC ESTKH+1,X + BVC ISGT1 + EOR #$80 +ISGT1 BMI ISTRU + BPL ISFLS ; -ISLE LDA ESTKL,X - CMP ESTKL+1,X - LDA ESTKH,X - SBC ESTKH+1,X - BVC ISLE1 - EOR #$80 -ISLE1 BPL ISTRU - BMI ISFLS +ISLE LDA ESTKL,X + CMP ESTKL+1,X + LDA ESTKH,X + SBC ESTKH+1,X + BVC ISLE1 + EOR #$80 +ISLE1 BPL ISTRU + BMI ISFLS ; -ISLT LDA ESTKL+1,X - CMP ESTKL,X - LDA ESTKH+1,X - SBC ESTKH,X - BVC ISLT1 - EOR #$80 -ISLT1 BMI ISTRU - BPL ISFLS +ISLT LDA ESTKL+1,X + CMP ESTKL,X + LDA ESTKH+1,X + SBC ESTKH,X + BVC ISLT1 + EOR #$80 +ISLT1 BMI ISTRU + BPL ISFLS ;* ;* BRANCHES ;* BRTRU INX - LDA ESTKH-1,X - ORA ESTKL-1,X - BNE BRNCH -NOBRNCH +INC_IP - +INC_IP - JMP NEXTOP + LDA ESTKH-1,X + ORA ESTKL-1,X + BNE BRNCH +NOBRNCH INY ;+INC_IP + +INC_IP + JMP NEXTOP BRFLS INX - LDA ESTKH-1,X - ORA ESTKL-1,X - BNE NOBRNCH -BRNCH LDA IPH - STA TMPH - LDA IPL - +INC_IP - CLC - ADC (IP),Y - STA TMPL - LDA TMPH - +INC_IP - ADC (IP),Y - STA IPH - LDA TMPL - STA IPL - DEY - DEY - JMP NEXTOP + LDA ESTKH-1,X + ORA ESTKL-1,X + BNE NOBRNCH +BRNCH TYA ; FLATTEN IP + CLC + ADC IPL + STA TMPL + LDA #$00 + ADC IPH + STA TMPH ; ADD BRANCH OFFSET + INY + LDA (IP),Y + CLC + ADC TMPL + STA TMPL + INY + LDA (IP),Y + ADC TMPH + STA IPH + LDA TMPL + STA IPL + LDY #$01 + JMP FETCHOP BREQ INX - LDA ESTKL-1,X - CMP ESTKL,X - BNE NOBRNCH - LDA ESTKH-1,X - CMP ESTKH,X - BEQ BRNCH - BNE NOBRNCH + 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 + 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 - SBC ESTKH,X - BPL NOBRNCH - BMI BRNCH + LDA ESTKL-1,X + CMP ESTKL,X + LDA ESTKH-1,X + SBC ESTKH,X + BPL NOBRNCH + BMI BRNCH BRLT INX - LDA ESTKL,X - CMP ESTKL-1,X - LDA ESTKH,X - SBC ESTKH-1,X - BPL NOBRNCH - BMI BRNCH -IBRNCH LDA IPL - CLC - ADC ESTKL,X - STA IPL - LDA IPH - ADC ESTKH,X - STA IPH -; INX -; JMP NEXTOP - JMP DROP + LDA ESTKL,X + CMP ESTKL-1,X + LDA ESTKH,X + SBC ESTKH-1,X + BPL NOBRNCH + BMI BRNCH +IBRNCH LDA IPL + CLC + ADC ESTKL,X + STA IPL + LDA IPH + ADC ESTKH,X + STA IPH + JMP DROP ;* ;* CALL INTO ABSOLUTE ADDRESS (NATIVE CODE) ;* -CALL +INC_IP - LDA (IP),Y - STA CALLADR+1 - +INC_IP - LDA (IP),Y - STA CALLADR+2 - TYA - CLC - ADC IPL - PHA - LDA IPH - ADC #$00 - PHA +CALL INY ;+INC_IP + LDA (IP),Y +!IF SELFMODIFY { + STA CALLADR+1 +} ELSE { + STA TMPL +} + INY ;+INC_IP + LDA (IP),Y +!IF SELFMODIFY { + STA CALLADR+2 +} ELSE { + STA TMPH +} + TYA + CLC + ADC IPL + PHA + LDA IPH + ADC #$00 + PHA +!IF SELFMODIFY { CALLADR JSR $FFFF - PLA - STA IPH - PLA - STA IPL - LDY #$00 - JMP NEXTOP +} ELSE { + JSR JMPTMP +} + PLA + STA IPH + PLA + STA IPL + LDY #$01 + JMP FETCHOP ;* ;* INDIRECT CALL TO ADDRESS (NATIVE CODE) ;* ICAL LDA ESTKL,X +!IF SELFMODIFY { STA ICALADR+1 +} ELSE { + STA TMPL +} LDA ESTKH,X +!IF SELFMODIFY { STA ICALADR+2 +} ELSE { + STA TMPH +} INX TYA CLC @@ -933,7 +917,11 @@ ICAL LDA ESTKL,X LDA IPH ADC #$00 PHA +!IF SELFMODIFY { ICALADR JSR $FFFF +} ELSE { + JSR JMPTMP +} PLA STA IPH PLA @@ -941,6 +929,10 @@ ICALADR JSR $FFFF LDY #$01 JMP FETCHOP ;* +;* JUMP INDIRECT TRHOUGH TMP +;* +JMPTMP JMP (TMP) +;* ;* ENTER FUNCTION WITH FRAME SIZE AND PARAM COUNT ;* ENTER INY @@ -969,7 +961,7 @@ ENTER INY ;* ;* LEAVE FUNCTION ;* -LEAVE +INC_IP +LEAVE INY ;+INC_IP LDA (IP),Y CLC ADC IFPL @@ -994,17 +986,14 @@ VMINIT LDY #$10 ; INSTALL PAGE 0 FETCHOP ROUTINE STA SRCH LDX #ESTKSZ/2 ; INIT EVAL STACK INDEX JMP A1CMD -PAGE0 = * +PAGE0 = * !PSEUDOPC DROP { ;* ;* INTERP BYTECODE INNER LOOP ;* INX ; DROP INY ; NEXTOP - BEQ NEXTOPH LDA $FFFF,Y ; FETCHOP @ $F3, IP MAPS OVER $FFFF @ $F4 STA OPIDX JMP (OPTBL) -NEXTOPH INC IPH - BNE FETCHOP } diff --git a/src/vmsrc/plvm02.s b/src/vmsrc/plvm02.s index 94b46c0..884c08e 100755 --- a/src/vmsrc/plvm02.s +++ b/src/vmsrc/plvm02.s @@ -44,7 +44,6 @@ PSR = TMP+2 DVSIGN = PSR+1 DROP = $EF NEXTOP = $F0 -;FETCHOP = NEXTOP+3 FETCHOP = NEXTOP+1 IP = FETCHOP+1 IPL = IP @@ -372,12 +371,9 @@ PAGE0 = * !PSEUDOPC DROP { INX ; DROP @ $EF INY ; NEXTOP @ $F0 -; BEQ NEXTOPH LDA $FFFF,Y ; FETCHOP @ $F3, IP MAPS OVER $FFFF @ $F4 STA OPIDX JMP (OPTBL) ; OPIDX AND OPPAGE MAP OVER OPTBL -;NEXTOPH INC IPH -; BNE FETCHOP } PAGE3 = * ;* @@ -1333,13 +1329,13 @@ BRFLS INX LDA ESTKH-1,X ORA ESTKL-1,X BNE NOBRNCH -BRNCH TYA ; FLATTEN IP +BRNCH TYA ; FLATTEN IP CLC ADC IPL STA TMPL LDA #$00 ADC IPH - STA TMPH ; ADD BRANCH OFFSET + STA TMPH ; ADD BRANCH OFFSET INY LDA (IP),Y CLC diff --git a/src/vmsrc/plvm03.s b/src/vmsrc/plvm03.s index 8dec521..96e20f2 100755 --- a/src/vmsrc/plvm03.s +++ b/src/vmsrc/plvm03.s @@ -14,7 +14,7 @@ MEMBANK = $FFEF DVSIGN = TMP+2 DROP = $EF NEXTOP = $F0 -FETCHOP = NEXTOP+3 +FETCHOP = NEXTOP+1 IP = FETCHOP+1 IPL = IP IPH = IPL+1 @@ -44,8 +44,12 @@ DSTX = XPAGE+DSTH ;* !MACRO INC_IP { INY - BNE *+4 - INC IPH + BPL + + INC IPH + TYA + AND #$7F + TAY ++ } ;* ;* INTERPRETER HEADER+INITIALIZATION @@ -113,12 +117,9 @@ PAGE0 = * ;* INX ; DROP INY ; NEXTOP - BEQ NEXTOPH LDA $FFFF,Y ; FETCHOP @ $F3, IP MAPS OVER $FFFF @ $F4 STA OPIDX JMP (OPTBL) -NEXTOPH INC IPH - BNE FETCHOP } ;* ;* SYSTEM INTERPRETER ENTRYPOINT @@ -539,7 +540,7 @@ CB LDA #$00 ;* LA = * CW DEX - +INC_IP + INY ;+INC_IP LDA (IP),Y STA ESTKL,X +INC_IP @@ -550,7 +551,7 @@ CW DEX ;* CONSTANT STRING ;* CS DEX - +INC_IP + INY ;+INC_IP TYA ; NORMALIZE IP CLC ADC IPL @@ -695,7 +696,7 @@ LLW +INC_IP ;* LOAD VALUE FROM ABSOLUTE ADDRESS ;* !IF SELFMODIFY { -LAB +INC_IP +LAB INY ;+INC_IP LDA (IP),Y STA LABLDA+1 +INC_IP @@ -708,7 +709,7 @@ LABLDA LDA $FFFF STA ESTKH,X JMP NEXTOP } ELSE { -LAB +INC_IP +LAB INY ;+INC_IP LDA (IP),Y STA TMPL +INC_IP @@ -723,7 +724,7 @@ LAB +INC_IP LDY IPY JMP NEXTOP } -LAW +INC_IP +LAW INY ;+INC_IP LDA (IP),Y STA TMPL +INC_IP @@ -764,8 +765,6 @@ SB LDA ESTKL,X STA (TMP),Y LDY IPY INX -; INX -; JMP NEXTOP JMP DROP } SW LDA ESTKL,X @@ -781,8 +780,6 @@ SW LDA ESTKL,X STA (TMP),Y LDY IPY INX -; INX -; JMP NEXTOP JMP DROP ;* ;* STORE VALUE TO LOCAL FRAME OFFSET @@ -794,8 +791,6 @@ SLB +INC_IP LDA ESTKL,X STA (IFP),Y LDY IPY -; INX -; JMP NEXTOP JMP DROP SLW +INC_IP LDA (IP),Y @@ -807,8 +802,6 @@ SLW +INC_IP LDA ESTKH,X STA (IFP),Y LDY IPY -; INX -; JMP NEXTOP JMP DROP ;* ;* STORE VALUE TO LOCAL FRAME OFFSET WITHOUT POPPING STACK @@ -836,7 +829,7 @@ DLW +INC_IP ;* STORE VALUE TO ABSOLUTE ADDRESS ;* !IF SELFMODIFY { -SAB +INC_IP +SAB INY ;+INC_IP LDA (IP),Y STA SABSTA+1 +INC_IP @@ -844,11 +837,9 @@ SAB +INC_IP STA SABSTA+2 LDA ESTKL,X SABSTA STA $FFFF -; INX -; JMP NEXTOP JMP DROP } ELSE { -SAB +INC_IP +SAB INY ;+INC_IP LDA (IP),Y STA TMPL +INC_IP @@ -859,11 +850,9 @@ SAB +INC_IP LDY #$00 STA (TMP),Y LDY IPY -; INX -; JMP NEXTOP JMP DROP } -SAW +INC_IP +SAW INY ;+INC_IP LDA (IP),Y STA TMPL +INC_IP @@ -877,14 +866,12 @@ SAW +INC_IP LDA ESTKH,X STA (TMP),Y LDY IPY -; INX -; JMP NEXTOP JMP DROP ;* ;* STORE VALUE TO ABSOLUTE ADDRESS WITHOUT POPPING STACK ;* !IF SELFMODIFY { -DAB +INC_IP +DAB INY ;+INC_IP LDA (IP),Y STA DABSTA+1 +INC_IP @@ -894,7 +881,7 @@ DAB +INC_IP DABSTA STA $FFFF JMP NEXTOP } ELSE { -DAB +INC_IP +DAB INY ;+INC_IP LDA (IP),Y STA TMPL +INC_IP @@ -907,7 +894,7 @@ DAB +INC_IP LDY IPY JMP NEXTOP } -DAW +INC_IP +DAW INY ;+INC_IP LDA (IP),Y STA TMPL +INC_IP @@ -993,29 +980,33 @@ BRTRU INX LDA ESTKH-1,X ORA ESTKL-1,X BNE BRNCH -NOBRNCH +INC_IP +NOBRNCH INY ;+INC_IP +INC_IP JMP NEXTOP BRFLS INX LDA ESTKH-1,X ORA ESTKL-1,X BNE NOBRNCH -BRNCH LDA IPH - STA TMPH - LDA IPL - +INC_IP +BRNCH TYA ; FLATTEN IP CLC - ADC (IP),Y + ADC IPL STA TMPL - LDA TMPH - +INC_IP - ADC (IP),Y + LDA #$00 + ADC IPH + STA TMPH ; ADD BRANCH OFFSET + INY + LDA (IP),Y + CLC + ADC TMPL + STA TMPL + INY + LDA (IP),Y + ADC TMPH STA IPH LDA TMPL STA IPL - DEY - DEY - JMP NEXTOP + LDY #$01 + JMP FETCHOP BREQ INX LDA ESTKL-1,X CMP ESTKL,X @@ -1059,10 +1050,10 @@ IBRNCH LDA IPL ;* ;* CALL INTO ABSOLUTE ADDRESS (NATIVE CODE) ;* -CALL +INC_IP +CALL INY ;+INC_IP LDA (IP),Y STA CALLADR+1 - +INC_IP + INY ;+INC_IP LDA (IP),Y STA CALLADR+2 TYA @@ -1146,7 +1137,7 @@ ENTER LDA IFPH ;* ;* LEAVE FUNCTION ;* -LEAVE +INC_IP +LEAVE INY ;+INC_IP LDA (IP),Y CLC ADC IFPL diff --git a/src/vmsrc/plvm802.s b/src/vmsrc/plvm802.s index 1b71cdb..479378f 100644 --- a/src/vmsrc/plvm802.s +++ b/src/vmsrc/plvm802.s @@ -55,7 +55,7 @@ PSR = TMP+2 HWSP = PSR+1 DROP = $EF NEXTOP = DROP+1 -FETCHOP = NEXTOP+3 +FETCHOP = NEXTOP+1 IP = FETCHOP+1 IPL = IP IPH = IPL+1 @@ -76,10 +76,11 @@ NOS = $03 ; TOS-1 ;* !MACRO INC_IP { INY - BNE + - LDX IPH - INX - STX IPH + BPL + + INC IPH + TYA + AND #$7F + TAY + } ;* @@ -468,13 +469,8 @@ PAGE0 = * !PSEUDOPC DROP { PLA ; DROP @ $EF INY ; NEXTOP @ $F0 - BEQ NEXTOPH LDX $FFFF,Y ; FETCHOP @ $F3, IP MAPS OVER $FFFF @ $F4 JMP (OPTBL,X) ; OPIDX AND OPPAGE MAP OVER OPTBL -NEXTOPH LDX IPH - INX - STX IPH - BRA FETCHOP } PAGE3 = * ;* @@ -782,15 +778,15 @@ CB +INC_IP ;* LOAD ADDRESS & LOAD CONSTANT WORD (SAME THING, WITH OR WITHOUT FIXUP) ;* LA = * -CW +INC_IP +CW INY ;+INC_IP LDA (IP),Y - +INC_IP PHA + +INC_IP JMP NEXTOP ;* ;* CONSTANT STRING ;* -CS +INC_IP +CS INY ;+INC_IP TYA ; NORMALIZE IP AND SAVE STRING ADDR ON ESTK CLC ADC IP @@ -800,7 +796,7 @@ CS +INC_IP TAY JMP NEXTOP ; -CSX +INC_IP +CSX INY ;+INC_IP TYA ; NORMALIZE IP CLC ADC IP @@ -968,49 +964,48 @@ LLWX +INC_IP ;* LOAD VALUE FROM ABSOLUTE ADDRESS ;* !IF SELFMODIFY { -LAB +INC_IP +LAB INY ;+INC_IP LDA (IP),Y - +INC_IP STA LABLDX+1 LABLDX LDX $FFFF TXA PHA + +INC_IP JMP NEXTOP } ELSE { -LAB +INC_IP +LAB INY ;+INC_IP LDA (IP),Y - +INC_IP STA TMP TYA ; QUICKY CLEAR OUT MSB +ACCMEM8 ; 8 BIT A/M LDA (TMP) +ACCMEM16 ; 16 BIT A/M PHA + +INC_IP JMP NEXTOP } -LAW +INC_IP +LAW INY ;+INC_IP LDA (IP),Y - +INC_IP STA TMP LDA (TMP) PHA + +INC_IP JMP NEXTOP ; !IF SELFMODIFY { -LABX +INC_IP +LABX INY ;+INC_IP LDA (IP),Y - +INC_IP STA LABXLDX+1 STX ALTRDOFF LABXLDX LDX $FFFF STX ALTRDON TXA PHA + +INC_IP JMP NEXTOP } ELSE { -LABX +INC_IP +LABX INY ;+INC_IP LDA (IP),Y - +INC_IP STA TMP TYA ; QUICKY CLEAR OUT MSB STX ALTRDOFF @@ -1019,16 +1014,17 @@ LABX +INC_IP +ACCMEM16 ; 16 BIT A/M STX ALTRDON PHA + +INC_IP JMP NEXTOP } -LAWX +INC_IP +LAWX INY ;+INC_IP LDA (IP),Y - +INC_IP STA TMP STX ALTRDOFF LDA (TMP) STX ALTRDON PHA + +INC_IP JMP NEXTOP ; ;* @@ -1132,61 +1128,61 @@ DLW +INC_IP ;* STORE VALUE TO ABSOLUTE ADDRESS ;* !IF SELFMODIFY { -SAB +INC_IP +SAB INY ;+INC_IP LDA (IP),Y - +INC_IP STA SABSTX+1 PLA TAX SABSTX STX $FFFF + +INC_IP JMP NEXTOP } ELSE { -SAB +INC_IP +SAB INY ;+INC_IP LDA (IP),Y - +INC_IP STA TMP PLA +ACCMEM8 ; 8 BIT A/M STA (TMP) +ACCMEM16 ; 16 BIT A/M + +INC_IP JMP NEXTOP } -SAW +INC_IP +SAW INY ;+INC_IP LDA (IP),Y - +INC_IP STA TMP PLA STA (TMP) + +INC_IP JMP NEXTOP ;* ;* STORE VALUE TO ABSOLUTE ADDRESS WITHOUT POPPING STACK ;* !IF SELFMODIFY { -DAB +INC_IP +DAB INY ;+INC_IP LDA (IP),Y - +INC_IP STA DABSTX+1 LDA TOS,S TAX DABSTX STX $FFFF + +INC_IP JMP NEXTOP } ELSE { -DAB +INC_IP +DAB INY ;+INC_IP LDA (IP),Y - +INC_IP STA TMP +ACCMEM8 ; 8 BIT A/M LDA TOS,S STA (TMP) +ACCMEM16 ; 16 BIT A/M + +INC_IP JMP NEXTOP } -DAW +INC_IP +DAW INY ;+INC_IP LDA (IP),Y - +INC_IP STA TMP LDA TOS,S STA (TMP) + +INC_IP JMP NEXTOP ;* ;* COMPARES @@ -1249,18 +1245,20 @@ ISLT PLA ;* BRTRU PLA BNE BRNCH -NOBRNCH +INC_IP +NOBRNCH INY ;+INC_IP +INC_IP JMP NEXTOP BRFLS PLA BNE NOBRNCH -BRNCH LDA IP - +INC_IP +BRNCH TYA ; FLATTEN IP CLC + ADC IP + INY ;+INC_IP + CLC ; ADD BRANCH OFFSET ADC (IP),Y STA IP - DEY - JMP NEXTOP + LDY #$01 + JMP FETCHOP BREQ PLA CMP TOS,S BEQ BRNCH @@ -1295,7 +1293,7 @@ IBRNCH PLA ;* ;* CALL INTO ABSOLUTE ADDRESS (NATIVE CODE) ;* -CALL +INC_IP +CALL INY ;+INC_IP LDA (IP),Y INY BNE EMUSTK @@ -1411,7 +1409,7 @@ EMUSTK STA TMP ;* ;* CALL INTO ABSOLUTE ADDRESS (NATIVE CODE) ;* -CALLX +INC_IP +CALLX INY ;+INC_IP LDA (IP),Y INY BNE EMUSTKX @@ -1575,12 +1573,12 @@ ENTER PEI (IFP) ; SAVE ON STACK FOR LEAVE ;* ;* LEAVE FUNCTION ;* -LEAVEX +INC_IP +LEAVEX INY ;+INC_IP +ACCMEM8 ; 8 BIT A/M LDA (IP),Y ; DEALLOCATE POOL + FRAME STA ALTRDOFF BRA + -LEAVE +INC_IP +LEAVE INY ;+INC_IP +ACCMEM8 ; 8 BIT A/M LDA (IP),Y ; DEALLOCATE POOL + FRAME + STA TMPL From 4b8fca060f9beb11864cc129b1438f1efc5a62ad Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Fri, 19 Jan 2018 14:12:22 -0800 Subject: [PATCH 15/45] remove conflict with clock cards and command line arguments --- src/vmsrc/cmd.pla | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/vmsrc/cmd.pla b/src/vmsrc/cmd.pla index 0b8e726..8059ded 100755 --- a/src/vmsrc/cmd.pla +++ b/src/vmsrc/cmd.pla @@ -35,7 +35,7 @@ predef execmod(modfile)#1 // word version = $0100 // 01.00 word syspath -word = getlnbuf +word syscmdln word = @execmod // // Working input buffer overlayed with strings table @@ -1308,7 +1308,8 @@ loop // Set system path // strcat(strcpy(@sysmods, $280), "SYS/")) // This is the path to CMD -syspath = @sysmods // Update external interface table +syspath = @sysmods // Update external interface table +syscmdln = @cmdln // // Try to load autorun. // @@ -1324,16 +1325,16 @@ else fin perr = 0 while 1 - if cmdln - when toupper(parsecmd(@cmdln)) + if ^getlnbuf + when toupper(parsecmd(getlnbuf)) is 'Q' reboot() break is 'C' - catalog(@cmdln) + catalog(getlnbuf) break is 'P' - setpfx(@cmdln) + setpfx(getlnbuf) break is '/' repeat @@ -1347,11 +1348,11 @@ while 1 volumes() break is '-' - execsys(@cmdln) + execsys(getlnbuf) break is '+' saveX - execmod(striptrail(@cmdln)) + execmod(striptrail(getlnbuf)) // // Clean up // From fbcebe9df3183e070173cce2eeb24023cce78840 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Fri, 19 Jan 2018 14:59:44 -0800 Subject: [PATCH 16/45] Turn off AN3 when returning to text mode --- src/libsrc/dgr.pla | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsrc/dgr.pla b/src/libsrc/dgr.pla index f50924a..a4758d6 100755 --- a/src/libsrc/dgr.pla +++ b/src/libsrc/dgr.pla @@ -529,7 +529,7 @@ export def txtMode#0 ^ena80 = 0 ^show40 = 0 ^mapmain = 0 - ^an3on + ^an3off call($FC58, 0, 0, 0, 0) // home() end // From f24bb421ec3ca8e2c399f5fccc5c8d76a4f98634 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Fri, 19 Jan 2018 17:37:32 -0800 Subject: [PATCH 17/45] fewer and better checks for IP FIXUP --- src/vmsrc/plvm02.s | 167 +++++++++++++++++++++++++------------------- src/vmsrc/plvm802.s | 165 ++++++++++++++++++++++++++----------------- 2 files changed, 198 insertions(+), 134 deletions(-) diff --git a/src/vmsrc/plvm02.s b/src/vmsrc/plvm02.s index 884c08e..b29a0ad 100755 --- a/src/vmsrc/plvm02.s +++ b/src/vmsrc/plvm02.s @@ -55,14 +55,29 @@ INTERP = $03D0 ;* ;* INTERPRETER INSTRUCTION POINTER INCREMENT MACRO ;* - !MACRO INC_IP { - INY - BPL + - INC IPH +;!MACRO INC_IP { +; INY +; BPL + +; INC IPH +; TYA +; AND #$7F +; TAY +;+ +; } +!MACRO FIX_IP { + INC IPH TYA AND #$7F TAY -+ + } +!MACRO FIXJMP_IP .TARGET { + BMI + + JMP .TARGET ++ INC IPH + TYA + AND #$7F + TAY + JMP .TARGET } ;****************************** ;* * @@ -730,19 +745,29 @@ CFFB LDA #$FF CB LDA #$00 DEX STA ESTKH,X - +INC_IP + INY LDA (IP),Y STA ESTKL,X JMP NEXTOP ;* ;* LOAD ADDRESS & LOAD CONSTANT WORD (SAME THING, WITH OR WITHOUT FIXUP) ;* -LA = * -CW DEX - INY ;+INC_IP +LA DEX + INY ;+INC_IP LDA (IP),Y STA ESTKL,X - +INC_IP + INY + BMI + +- LDA (IP),Y + STA ESTKH,X + JMP NEXTOP ++ +FIX_IP + BPL - +CW DEX + INY ;+INC_IP + LDA (IP),Y + STA ESTKL,X + INY LDA (IP),Y STA ESTKH,X JMP NEXTOP @@ -750,7 +775,7 @@ CW DEX ;* CONSTANT STRING ;* CS DEX - INY ;+INC_IP + INY ;+INC_IP TYA ; NORMALIZE IP AND SAVE STRING ADDR ON ESTK CLC ADC IPL @@ -766,7 +791,7 @@ CS DEX JMP NEXTOP ; CSX DEX - INY ;+INC_IP + INY ;+INC_IP TYA ; NORMALIZE IP CLC ADC IPL @@ -875,7 +900,7 @@ LW LDA ESTKL,X LDY IPY JMP NEXTOP ; -!IF SELFMODIFY { +!IF SELFMODIFY { LBX LDA ESTKL,X STA LBXLDA+1 LDA ESTKH,X @@ -920,8 +945,9 @@ LWX LDA ESTKL,X ;* ;* LOAD ADDRESS OF LOCAL FRAME OFFSET ;* -LLA +INC_IP - LDA (IP),Y +LLA INY ;+INC_IP + BMI + +- LDA (IP),Y DEX CLC ADC IFPL @@ -930,10 +956,12 @@ LLA +INC_IP ADC IFPH STA ESTKH,X JMP NEXTOP ++ +FIX_IP + BPL - ;* ;* LOAD VALUE FROM LOCAL FRAME OFFSET ;* -LLB +INC_IP +LLB INY ;+INC_IP LDA (IP),Y STY IPY TAY @@ -944,7 +972,7 @@ LLB +INC_IP STA ESTKH,X LDY IPY JMP NEXTOP -LLW +INC_IP +LLW INY ;+INC_IP LDA (IP),Y STY IPY TAY @@ -957,7 +985,7 @@ LLW +INC_IP LDY IPY JMP NEXTOP ; -LLBX +INC_IP +LLBX INY ;+INC_IP LDA (IP),Y STY IPY TAY @@ -970,7 +998,7 @@ LLBX +INC_IP STA ALTRDON LDY IPY JMP NEXTOP -LLWX +INC_IP +LLWX INY ;+INC_IP LDA (IP),Y STY IPY TAY @@ -987,11 +1015,11 @@ LLWX +INC_IP ;* ;* LOAD VALUE FROM ABSOLUTE ADDRESS ;* -!IF SELFMODIFY { -LAB INY ;+INC_IP +!IF SELFMODIFY { +LAB INY ;+INC_IP LDA (IP),Y STA LABLDA+1 - +INC_IP + INY ;+INC_IP LDA (IP),Y STA LABLDA+2 LABLDA LDA $FFFF @@ -1001,10 +1029,10 @@ LABLDA LDA $FFFF STA ESTKH,X JMP NEXTOP } ELSE { -LAB INY ;+INC_IP +LAB INY ;+INC_IP LDA (IP),Y STA TMPL - +INC_IP + INY ;+INC_IP LDA (IP),Y STA TMPH STY IPY @@ -1016,10 +1044,10 @@ LAB INY ;+INC_IP LDY IPY JMP NEXTOP } -LAW INY ;+INC_IP +LAW INY ;+INC_IP LDA (IP),Y STA TMPL - +INC_IP + INY ;+INC_IP LDA (IP),Y STA TMPH STY IPY @@ -1033,11 +1061,11 @@ LAW INY ;+INC_IP LDY IPY JMP NEXTOP ; -!IF SELFMODIFY { -LABX INY ;+INC_IP +!IF SELFMODIFY { +LABX INY ;+INC_IP LDA (IP),Y STA LABXLDA+1 - +INC_IP + INY ;+INC_IP LDA (IP),Y STA LABXLDA+2 STA ALTRDOFF @@ -1049,10 +1077,10 @@ LABXLDA LDA $FFFF STA ALTRDON JMP NEXTOP } ELSE { -LABX INY ;+INC_IP +LABX INY ;+INC_IP LDA (IP),Y STA TMPL - +INC_IP + INY ;+INC_IP LDA (IP),Y STA TMPH STY IPY @@ -1066,10 +1094,10 @@ LABX INY ;+INC_IP LDY IPY JMP NEXTOP } -LAWX INY ;+INC_IP +LAWX INY ;+INC_IP LDA (IP),Y STA TMPL - +INC_IP + INY ;+INC_IP LDA (IP),Y STA TMPH STY IPY @@ -1087,7 +1115,7 @@ LAWX INY ;+INC_IP ;* ;* STORE VALUE TO ADDRESS ;* -!IF SELFMODIFY { +!IF SELFMODIFY { SB LDA ESTKL,X STA SBSTA+1 LDA ESTKH,X @@ -1126,17 +1154,15 @@ SW LDA ESTKL,X ;* ;* STORE VALUE TO LOCAL FRAME OFFSET ;* -SLB +INC_IP +SLB INY ;+INC_IP LDA (IP),Y STY IPY TAY LDA ESTKL,X STA (IFP),Y LDY IPY -; INX -; JMP NEXTOP - JMP DROP -SLW +INC_IP + +FIXJMP_IP DROP +SLW INY ;+INC_IP LDA (IP),Y STY IPY TAY @@ -1146,11 +1172,11 @@ SLW +INC_IP LDA ESTKH,X STA (IFP),Y LDY IPY - JMP DROP + +FIXJMP_IP DROP ;* ;* STORE VALUE TO LOCAL FRAME OFFSET WITHOUT POPPING STACK ;* -DLB +INC_IP +DLB INY ;+INC_IP LDA (IP),Y STY IPY TAY @@ -1158,7 +1184,7 @@ DLB +INC_IP STA (IFP),Y LDY IPY JMP NEXTOP -DLW +INC_IP +DLW INY ;+INC_IP LDA (IP),Y STY IPY TAY @@ -1172,23 +1198,24 @@ DLW +INC_IP ;* ;* STORE VALUE TO ABSOLUTE ADDRESS ;* -!IF SELFMODIFY { -SAB INY ;+INC_IP +!IF SELFMODIFY { +SAB INY ;+INC_IP LDA (IP),Y STA SABSTA+1 - +INC_IP - LDA (IP),Y + INY ;+INC_IP + BMI + +- LDA (IP),Y STA SABSTA+2 LDA ESTKL,X SABSTA STA $FFFF -; INX -; JMP NEXTOP JMP DROP ++ +FIX_IP + BPL - } ELSE { -SAB INY ;+INC_IP +SAB INY ;+INC_IP LDA (IP),Y STA TMPL - +INC_IP + INY ;+INC_IP LDA (IP),Y STA TMPH LDA ESTKL,X @@ -1196,12 +1223,12 @@ SAB INY ;+INC_IP LDY #$00 STA (TMP),Y LDY IPY - JMP DROP + +FIXJMP_IP DROP } -SAW INY ;+INC_IP +SAW INY ;+INC_IP LDA (IP),Y STA TMPL - +INC_IP + INY ;+INC_IP LDA (IP),Y STA TMPH STY IPY @@ -1212,25 +1239,25 @@ SAW INY ;+INC_IP LDA ESTKH,X STA (TMP),Y LDY IPY - JMP DROP + +FIXJMP_IP DROP ;* ;* STORE VALUE TO ABSOLUTE ADDRESS WITHOUT POPPING STACK ;* -!IF SELFMODIFY { -DAB INY ;+INC_IP +!IF SELFMODIFY { +DAB INY ;+INC_IP LDA (IP),Y STA DABSTA+1 - +INC_IP + INY ;+INC_IP LDA (IP),Y STA DABSTA+2 LDA ESTKL,X DABSTA STA $FFFF JMP NEXTOP } ELSE { -DAB INY ;+INC_IP +DAB INY ;+INC_IP LDA (IP),Y STA TMPL - +INC_IP + INY ;+INC_IP LDA (IP),Y STA TMPH STY IPY @@ -1240,10 +1267,10 @@ DAB INY ;+INC_IP LDY IPY JMP NEXTOP } -DAW INY ;+INC_IP +DAW INY ;+INC_IP LDA (IP),Y STA TMPL - +INC_IP + INY ;+INC_IP LDA (IP),Y STA TMPH STY IPY @@ -1322,9 +1349,9 @@ BRTRU INX LDA ESTKH-1,X ORA ESTKL-1,X BNE BRNCH -NOBRNCH INY ;+INC_IP - +INC_IP - JMP NEXTOP +NOBRNCH INY ;+INC_IP + INY ;+INC_IP + +FIXJMP_IP NEXTOP BRFLS INX LDA ESTKH-1,X ORA ESTKL-1,X @@ -1390,10 +1417,10 @@ IBRNCH LDA IPL ;* ;* CALL INTO ABSOLUTE ADDRESS (NATIVE CODE) ;* -CALL INY ;+INC_IP +CALL INY ;+INC_IP LDA (IP),Y STA TMPL - INY ;+INC_IP + INY ;+INC_IP LDA (IP),Y STA TMPH TYA @@ -1417,10 +1444,10 @@ CALL INY ;+INC_IP LDY #$01 JMP FETCHOP ; -CALLX INY ;+INC_IP +CALLX INY ;+INC_IP LDA (IP),Y STA TMPL - INY ;+INC_IP + INY ;+INC_IP LDA (IP),Y STA TMPH TYA @@ -1554,7 +1581,7 @@ ENTER LDA IFPH ;* ;* LEAVE FUNCTION ;* -LEAVEX INY ;+INC_IP +LEAVEX INY ;+INC_IP LDA (IP),Y CLC ADC IFPL @@ -1571,7 +1598,7 @@ RETX STA ALTRDOFF PHA PLP RTS -LEAVE INY ;+INC_IP +LEAVE INY ;+INC_IP LDA (IP),Y CLC ADC IFPL diff --git a/src/vmsrc/plvm802.s b/src/vmsrc/plvm802.s index 479378f..30b7653 100644 --- a/src/vmsrc/plvm802.s +++ b/src/vmsrc/plvm802.s @@ -74,14 +74,41 @@ NOS = $03 ; TOS-1 ;* ;* INTERPRETER INSTRUCTION POINTER INCREMENT MACRO ;* - !MACRO INC_IP { - INY - BPL + - INC IPH +;!MACRO INC_IP { +; INY +; BPL + +; SEP #$20 ; 8 BIT A/M +; !AS +; INC IPH +; TYA +; AND #$7F +; TAY +; REP #$20 ; 16 BIT A/M +; !AL +;+ +; } +!MACRO FIX_IP { + SEP #$20 ; 8 BIT A/M + !AS + INC IPH TYA AND #$7F TAY -+ + REP #$20 ; 16 BIT A/M + !AL + } +!MACRO FIXJMP_IP .TARGET { + BMI + + JMP .TARGET ++ SEP #$20 ; 8 BIT A/M + !AS + INC IPH + TYA + AND #$7F + TAY + REP #$20 ; 16 BIT A/M + !AL + JMP .TARGET } ;* ;* ACCUM/MEM SIZE MACROS @@ -764,12 +791,12 @@ DUP LDA TOS,S ;* ZERO PEA $0000 JMP NEXTOP -CFFB +INC_IP +CFFB INY ;+INC_IP LDA (IP),Y ORA #$FF00 PHA JMP NEXTOP -CB +INC_IP +CB INY ;+INC_IP LDA (IP),Y AND #$00FF PHA @@ -777,16 +804,20 @@ CB +INC_IP ;* ;* LOAD ADDRESS & LOAD CONSTANT WORD (SAME THING, WITH OR WITHOUT FIXUP) ;* -LA = * -CW INY ;+INC_IP +LA INY ;+INC_IP LDA (IP),Y PHA - +INC_IP + INY ;+INC_IP + +FIXJMP_IP NEXTOP +CW INY ;+INC_IP + LDA (IP),Y + PHA + INY ;+INC_IP JMP NEXTOP ;* ;* CONSTANT STRING ;* -CS INY ;+INC_IP +CS INY ;+INC_IP TYA ; NORMALIZE IP AND SAVE STRING ADDR ON ESTK CLC ADC IP @@ -796,7 +827,7 @@ CS INY ;+INC_IP TAY JMP NEXTOP ; -CSX INY ;+INC_IP +CSX INY ;+INC_IP TYA ; NORMALIZE IP CLC ADC IP @@ -911,17 +942,20 @@ LWX TYX ;* ;* LOAD ADDRESS OF LOCAL FRAME OFFSET ;* -LLA +INC_IP - LDA (IP),Y +LLA INY ;+INC_IP + BMI + +- LDA (IP),Y AND #$00FF CLC ADC IFP PHA JMP NEXTOP ++ +FIX_IP + BPL - ;* ;* LOAD VALUE FROM LOCAL FRAME OFFSET ;* -LLB +INC_IP +LLB INY ;+INC_IP TYX LDA (IP),Y TAY @@ -930,7 +964,7 @@ LLB +INC_IP PHA TXY JMP NEXTOP -LLW +INC_IP +LLW INY ;+INC_IP TYX LDA (IP),Y TAY @@ -939,7 +973,7 @@ LLW +INC_IP TXY JMP NEXTOP ; -LLBX +INC_IP +LLBX INY ;+INC_IP TYX LDA (IP),Y TAY @@ -950,7 +984,7 @@ LLBX +INC_IP PHA TXY JMP NEXTOP -LLWX +INC_IP +LLWX INY ;+INC_IP TYX LDA (IP),Y TAY @@ -964,16 +998,16 @@ LLWX +INC_IP ;* LOAD VALUE FROM ABSOLUTE ADDRESS ;* !IF SELFMODIFY { -LAB INY ;+INC_IP +LAB INY ;+INC_IP LDA (IP),Y STA LABLDX+1 LABLDX LDX $FFFF TXA PHA - +INC_IP + INY ;+INC_IP JMP NEXTOP } ELSE { -LAB INY ;+INC_IP +LAB INY ;+INC_IP LDA (IP),Y STA TMP TYA ; QUICKY CLEAR OUT MSB @@ -981,19 +1015,19 @@ LAB INY ;+INC_IP LDA (TMP) +ACCMEM16 ; 16 BIT A/M PHA - +INC_IP + INY ;+INC_IP JMP NEXTOP } -LAW INY ;+INC_IP +LAW INY ;+INC_IP LDA (IP),Y STA TMP LDA (TMP) PHA - +INC_IP + INY ;+INC_IP JMP NEXTOP ; !IF SELFMODIFY { -LABX INY ;+INC_IP +LABX INY ;+INC_IP LDA (IP),Y STA LABXLDX+1 STX ALTRDOFF @@ -1001,10 +1035,10 @@ LABXLDX LDX $FFFF STX ALTRDON TXA PHA - +INC_IP + INY ;+INC_IP JMP NEXTOP } ELSE { -LABX INY ;+INC_IP +LABX INY ;+INC_IP LDA (IP),Y STA TMP TYA ; QUICKY CLEAR OUT MSB @@ -1014,17 +1048,17 @@ LABX INY ;+INC_IP +ACCMEM16 ; 16 BIT A/M STX ALTRDON PHA - +INC_IP + INY ;+INC_IP JMP NEXTOP } -LAWX INY ;+INC_IP +LAWX INY ;+INC_IP LDA (IP),Y STA TMP STX ALTRDOFF LDA (TMP) STX ALTRDON PHA - +INC_IP + INY ;+INC_IP JMP NEXTOP ; ;* @@ -1060,8 +1094,9 @@ SW TYX ;* STORE VALUE TO LOCAL FRAME OFFSET ;* !IF SELFMODIFY { -SLB +INC_IP - LDA (IP),Y +SLB INY ;+INC_IP + BMI + +- LDA (IP),Y AND #$00FF CLC ADC IFP @@ -1070,8 +1105,10 @@ SLB +INC_IP TAX SLBSTX STX $FFFF JMP NEXTOP ++ +FIX_IP + BPL - } ELSE { -SLB +INC_IP +SLB INY ;+INC_IP TYX LDA (IP),Y TAY @@ -1080,21 +1117,21 @@ SLB +INC_IP STA (IFP),Y +ACCMEM16 ; 16 BIT A/M TXY - JMP NEXTOP + +FIXJMP_IP NEXTOP } -SLW +INC_IP +SLW INY ;+INC_IP LDA (IP),Y TYX TAY PLA STA (IFP),Y TXY - JMP NEXTOP + +FIXJMP_IP NEXTOP ;* ;* STORE VALUE TO LOCAL FRAME OFFSET WITHOUT POPPING STACK ;* !IF SELFMODIFY { -DLB +INC_IP +DLB INY ;+INC_IP LDA (IP),Y AND #$00FF CLC @@ -1105,7 +1142,7 @@ DLB +INC_IP DLBSTX STX $FFFF JMP NEXTOP } ELSE { -DLB +INC_IP +DLB INY ;+INC_IP TYX +ACCMEM8 ; 8 BIT A/M LDA (IP),Y @@ -1116,7 +1153,7 @@ DLB +INC_IP TXY JMP NEXTOP } -DLW +INC_IP +DLW INY ;+INC_IP LDA (IP),Y TYX TAY @@ -1128,61 +1165,61 @@ DLW +INC_IP ;* STORE VALUE TO ABSOLUTE ADDRESS ;* !IF SELFMODIFY { -SAB INY ;+INC_IP +SAB INY ;+INC_IP LDA (IP),Y STA SABSTX+1 PLA TAX SABSTX STX $FFFF - +INC_IP - JMP NEXTOP + INY ;+INC_IP + +FIXJMP_IP NEXTOP } ELSE { -SAB INY ;+INC_IP +SAB INY ;+INC_IP LDA (IP),Y STA TMP PLA +ACCMEM8 ; 8 BIT A/M STA (TMP) +ACCMEM16 ; 16 BIT A/M - +INC_IP - JMP NEXTOP + INY ;+INC_IP + +FIXJMP_IP NEXTOP } -SAW INY ;+INC_IP +SAW INY ;+INC_IP LDA (IP),Y STA TMP PLA STA (TMP) - +INC_IP - JMP NEXTOP + INY ;+INC_IP + +FIXJMP_IP NEXTOP ;* ;* STORE VALUE TO ABSOLUTE ADDRESS WITHOUT POPPING STACK ;* !IF SELFMODIFY { -DAB INY ;+INC_IP +DAB INY ;+INC_IP LDA (IP),Y STA DABSTX+1 LDA TOS,S TAX DABSTX STX $FFFF - +INC_IP + INY ;+INC_IP JMP NEXTOP } ELSE { -DAB INY ;+INC_IP +DAB INY ;+INC_IP LDA (IP),Y STA TMP +ACCMEM8 ; 8 BIT A/M LDA TOS,S STA (TMP) +ACCMEM16 ; 16 BIT A/M - +INC_IP + INY ;+INC_IP JMP NEXTOP } -DAW INY ;+INC_IP +DAW INY ;+INC_IP LDA (IP),Y STA TMP LDA TOS,S STA (TMP) - +INC_IP + INY ;+INC_IP JMP NEXTOP ;* ;* COMPARES @@ -1245,16 +1282,16 @@ ISLT PLA ;* BRTRU PLA BNE BRNCH -NOBRNCH INY ;+INC_IP - +INC_IP - JMP NEXTOP +NOBRNCH INY ;+INC_IP + INY ;+INC_IP + +FIXJMP_IP NEXTOP BRFLS PLA BNE NOBRNCH -BRNCH TYA ; FLATTEN IP +BRNCH TYA ; FLATTEN IP CLC ADC IP - INY ;+INC_IP - CLC ; ADD BRANCH OFFSET + INY ;+INC_IP + CLC ; ADD BRANCH OFFSET ADC (IP),Y STA IP LDY #$01 @@ -1293,7 +1330,7 @@ IBRNCH PLA ;* ;* CALL INTO ABSOLUTE ADDRESS (NATIVE CODE) ;* -CALL INY ;+INC_IP +CALL INY ;+INC_IP LDA (IP),Y INY BNE EMUSTK @@ -1409,7 +1446,7 @@ EMUSTK STA TMP ;* ;* CALL INTO ABSOLUTE ADDRESS (NATIVE CODE) ;* -CALLX INY ;+INC_IP +CALLX INY ;+INC_IP LDA (IP),Y INY BNE EMUSTKX @@ -1573,12 +1610,12 @@ ENTER PEI (IFP) ; SAVE ON STACK FOR LEAVE ;* ;* LEAVE FUNCTION ;* -LEAVEX INY ;+INC_IP +LEAVEX INY ;+INC_IP +ACCMEM8 ; 8 BIT A/M LDA (IP),Y ; DEALLOCATE POOL + FRAME STA ALTRDOFF BRA + -LEAVE INY ;+INC_IP +LEAVE INY ;+INC_IP +ACCMEM8 ; 8 BIT A/M LDA (IP),Y ; DEALLOCATE POOL + FRAME + STA TMPL From 82516bfe31866fbe5739689743e2f917fdadd536 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 20 Jan 2018 09:15:26 -0800 Subject: [PATCH 18/45] Speed up modload, fix oops on FIXUP_IP --- src/vmsrc/cmd.pla | 124 ++++++++++++++++++++++++++++++++++---------- src/vmsrc/plvm02.s | 20 ++++--- src/vmsrc/plvm802.s | 22 +++----- 3 files changed, 119 insertions(+), 47 deletions(-) diff --git a/src/vmsrc/cmd.pla b/src/vmsrc/cmd.pla index 8059ded..7bd7ebc 100755 --- a/src/vmsrc/cmd.pla +++ b/src/vmsrc/cmd.pla @@ -686,6 +686,94 @@ asm lookuptbl(dci, tbl)#1 + INC DSTH BNE --- end +// def lookupidx(esd, index) +// word sym +// while ^esd +// sym = esd +// esd = sym + dcitos(sym, @str) +// if esd->0 & $10 and esd->1 == index +// return sym +// fin +// esd = esd + 3 +// loop +//end +asm lookupidx(esd, index)#1 + LDA ESTKL,X + STA TMPL + INX +--- LDA ESTKH,X + STA SRCH + LDA ESTKL,X +-- STA SRCL + LDY #$00 +- LDA (SRC),Y + BPL + + INY + BNE - ++ BEQ ++ ; END OF ESD + INY + LDA (SRC),Y + INY + AND #$10 ; EXTERN FLAG? + BEQ + + LDA (SRC),Y + CMP TMPL + BEQ +++ ; MATCH ++ INY + TYA + SEC + ADC SRCL + STA ESTKL,X ; SYM PTRL + BCC -- + INC ESTKH,X ; SYM PTRH + BNE --- +++ STA ESTKL,X ; END OF ESD + STA ESTKH,X ++++ RTS +end +//def lookupdef(addr, deftbl)#1 +// while deftbl->0 == $20 +// if deftbl=>3 == addr +// return deftbl +// fin +// deftbl = deftbl + 5 +// loop +// return 0 +//end +asm lookupdef(addr, deftbl)#1 + LDA ESTKH,X + STA SRCH + LDA ESTKL,X + STA SRCL + INX +- LDY #$00 + LDA (SRC),Y + CMP #$20 ; JSR OPCODE? + BNE ++ + LDY #$03 + LDA (SRC),Y + CMP ESTKL,X + BNE + + INY + LDA (SRC),Y + CMP ESTKH,X + BNE + + LDA SRCL ; MATCH + STA ESTKL,X + LDA SRCH + STA ESTKH,X + RTS ++ LDA #$05 + CLC + ADC SRCL + STA SRCL + BCC - + INC SRCH + BNE - +++ STY ESTKL,X + STY ESTKH,X + RTS +end // // Cheap and dirty print integer // @@ -857,44 +945,28 @@ end def lookupextern(esd, index)#1 word sym, addr byte str[16] - while ^esd - sym = esd - esd = sym + dcitos(sym, @str) - if esd->0 & $10 and esd->1 == index - addr = lookuptbl(sym, symtbl) - if !addr - perr = $81 - cout('?'); prstr(@str); crout - fin - return addr + sym = lookupidx(esd, index) + if sym + addr = lookuptbl(sym, symtbl) + if !addr + perr = $81 + dcitos(sym, @str) + cout('?'); prstr(@str); crout fin - esd = esd + 3 - loop + return addr + fin return 0 end def adddef(bank, addr, deflast)#1 word defentry defentry = *deflast *deflast = defentry + 5 - if bank - defentry=>1 = $03DC // JSR $03DC (AUX MEM INTERP) - else - defentry=>1 = $03D6 // JSR $03D6 (MAIN MEM INTERP) - fin defentry->0 = $20 + defentry=>1 = bank ?? $03DC :: $03D6 // JSR $03DC (AUX MEM INTERP) or $03D6 (MAIN MEM INTERP) defentry=>3 = addr defentry->5 = 0 // NULL out next entry return defentry end -def lookupdef(addr, deftbl)#1 - while deftbl->0 == $20 - if deftbl=>3 == addr - return deftbl - fin - deftbl = deftbl + 5 - loop - return 0 -end def loadmod(mod)#1 word rdlen, modsize, bytecode, codefix, defofst, defcnt, init, fixup word addr, defaddr, modaddr, modfix, modofst, modend diff --git a/src/vmsrc/plvm02.s b/src/vmsrc/plvm02.s index b29a0ad..6dd1d56 100755 --- a/src/vmsrc/plvm02.s +++ b/src/vmsrc/plvm02.s @@ -65,18 +65,24 @@ INTERP = $03D0 ;+ ; } !MACRO FIX_IP { - INC IPH TYA - AND #$7F - TAY + CLC + ADC IPL + STA IPL + BCC + + INC IPH ++ LDY #$00 } !MACRO FIXJMP_IP .TARGET { BMI + JMP .TARGET -+ INC IPH - TYA - AND #$7F - TAY ++ TYA + CLC + ADC IPL + STA IPL + BCC + + INC IPH ++ LDY #$00 JMP .TARGET } ;****************************** diff --git a/src/vmsrc/plvm802.s b/src/vmsrc/plvm802.s index 30b7653..866daf8 100644 --- a/src/vmsrc/plvm802.s +++ b/src/vmsrc/plvm802.s @@ -88,26 +88,20 @@ NOS = $03 ; TOS-1 ;+ ; } !MACRO FIX_IP { - SEP #$20 ; 8 BIT A/M - !AS - INC IPH TYA - AND #$7F - TAY - REP #$20 ; 16 BIT A/M - !AL + CLC + ADC IP + STA IP + LDY #$00 } !MACRO FIXJMP_IP .TARGET { BMI + JMP .TARGET -+ SEP #$20 ; 8 BIT A/M - !AS - INC IPH TYA - AND #$7F - TAY - REP #$20 ; 16 BIT A/M - !AL + CLC + ADC IP + STA IP + LDY #$00 JMP .TARGET } ;* From abfe13a6738fb1706e07c5b9dbc77bdfa7b159c2 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 20 Jan 2018 09:17:55 -0800 Subject: [PATCH 19/45] Fix oops on FIXJMP_IP --- src/vmsrc/plvm802.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vmsrc/plvm802.s b/src/vmsrc/plvm802.s index 866daf8..016aefc 100644 --- a/src/vmsrc/plvm802.s +++ b/src/vmsrc/plvm802.s @@ -97,7 +97,7 @@ NOS = $03 ; TOS-1 !MACRO FIXJMP_IP .TARGET { BMI + JMP .TARGET - TYA ++ TYA CLC ADC IP STA IP From 934c52cf4d7e46fb484c94e445705e9076d7f08c Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 20 Jan 2018 09:52:32 -0800 Subject: [PATCH 20/45] Even faster module loads. Now I'm happy --- src/vmsrc/cmd.pla | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/src/vmsrc/cmd.pla b/src/vmsrc/cmd.pla index 7bd7ebc..0000624 100755 --- a/src/vmsrc/cmd.pla +++ b/src/vmsrc/cmd.pla @@ -649,11 +649,12 @@ asm lookuptbl(dci, tbl)#1 STA DSTL LDA ESTKH,X STA DSTH - LDA ESTKL+1,X + INX + LDA ESTKL,X STA SRCL - LDA ESTKH+1,X + LDA ESTKH,X STA SRCH - LDY #$00 +-- LDY #$00 - LDA (DST),Y BEQ + CMP (SRC),Y @@ -662,29 +663,27 @@ asm lookuptbl(dci, tbl)#1 ASL BCS - LDA (DST),Y - PHA + STA ESTKL,X ; MATCH INY LDA (DST),Y - TAY - PLA -+ INX - STA ESTKL,X - STY ESTKH,X + STA ESTKH,X RTS -++ LDY #$00 --- LDA (DST),Y - INC DSTL - BEQ + ---- ASL - BCS -- - LDA #$02 ++ STA ESTKL,X ; NO MATCH + STA ESTKH,X + RTS +++ +- LDA (DST),Y ; NEXT ENTRY + BPL + + INY + BNE - ++ TYA + CLC + ADC #$03 ADC DSTL STA DSTL - BCC - + BCC -- INC DSTH - BCS - -+ INC DSTH - BNE --- + BNE -- end // def lookupidx(esd, index) // word sym From 3807a29fc96f37d152902d7d6e51d8eeae0c16f4 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 20 Jan 2018 10:30:14 -0800 Subject: [PATCH 21/45] The branch op code I was looking for --- src/vmsrc/plvm02.s | 14 ++++++-------- src/vmsrc/plvm802.s | 2 +- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/vmsrc/plvm02.s b/src/vmsrc/plvm02.s index 6dd1d56..af3002b 100755 --- a/src/vmsrc/plvm02.s +++ b/src/vmsrc/plvm02.s @@ -1363,24 +1363,22 @@ BRFLS INX ORA ESTKL-1,X BNE NOBRNCH BRNCH TYA ; FLATTEN IP - CLC + SEC ADC IPL STA TMPL LDA #$00 + TAY ADC IPH STA TMPH ; ADD BRANCH OFFSET - INY - LDA (IP),Y + LDA (TMP),Y CLC ADC TMPL - STA TMPL + STA IPL INY - LDA (IP),Y + LDA (TMP),Y ADC TMPH STA IPH - LDA TMPL - STA IPL - LDY #$01 + DEY JMP FETCHOP BREQ INX LDA ESTKL-1,X diff --git a/src/vmsrc/plvm802.s b/src/vmsrc/plvm802.s index 016aefc..1983d7c 100644 --- a/src/vmsrc/plvm802.s +++ b/src/vmsrc/plvm802.s @@ -1285,7 +1285,7 @@ BRNCH TYA ; FLATTEN IP CLC ADC IP INY ;+INC_IP - CLC ; ADD BRANCH OFFSET + ;CLC ; ADD BRANCH OFFSET (BETTER NOT CARRY OUT OF IP+Y) ADC (IP),Y STA IP LDY #$01 From eb852c8a7390da2379b1b41cab12c4eb43d0f27a Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 20 Jan 2018 10:37:21 -0800 Subject: [PATCH 22/45] Last branch op code optimization --- src/vmsrc/plvm02.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vmsrc/plvm02.s b/src/vmsrc/plvm02.s index af3002b..2891b8a 100755 --- a/src/vmsrc/plvm02.s +++ b/src/vmsrc/plvm02.s @@ -1371,7 +1371,7 @@ BRNCH TYA ; FLATTEN IP ADC IPH STA TMPH ; ADD BRANCH OFFSET LDA (TMP),Y - CLC + ;CLC ; BETTER NOT CARRY OUT OF IP+Y ADC TMPL STA IPL INY From ad3a0c6a467d01efb9c8f037d6b978c8c8fd6f37 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 20 Jan 2018 13:30:31 -0800 Subject: [PATCH 23/45] Peter Ferrie optimizations --- src/libsrc/dgr.pla | 799 ++++++++++++++++++++++--------------------- src/libsrc/sane.pla | 12 +- src/libsrc/tone.pla | 12 +- src/vmsrc/a1cmd.pla | 3 +- src/vmsrc/cmd.pla | 3 +- src/vmsrc/cmdstub.s | 85 +++-- src/vmsrc/plvm01.s | 85 ++--- src/vmsrc/plvm02.s | 4 +- src/vmsrc/plvm03.s | 80 ++--- src/vmsrc/soscmd.pla | 3 +- 10 files changed, 520 insertions(+), 566 deletions(-) diff --git a/src/libsrc/dgr.pla b/src/libsrc/dgr.pla index a4758d6..001cf97 100755 --- a/src/libsrc/dgr.pla +++ b/src/libsrc/dgr.pla @@ -50,461 +50,470 @@ end // Plot pixel // export asm dgrPlot(buff, x, y)#0 - ; GET BUFFER ADDRESS - STX ESP - LDA ESTKL+2,X - STA SRCL - LDA ESTKH+2,X - STA SRCH - LDA ESTKL,X ; Y COORD - AND #$FE - TAY - LDA (SRC),Y - STA GBASL - INY - LDA (SRC),Y - STA GBASH - LDA ESTKL+1,X ; X COORD - LSR ESTKL,X - LDX GCLR ; COLOR - PHP - SEI + ; GET BUFFER ADDRESS + STX ESP + LDA ESTKL+2,X + STA SRCL + LDA ESTKH+2,X + STA SRCH + LDA ESTKL,X ; Y COORD + AND #$FE + TAY + LDA (SRC),Y + STA GBASL + INY + LDA (SRC),Y + STA GBASH + LDA ESTKL+1,X ; X COORD + LSR ESTKL,X + LDX GCLR ; COLOR + PHP + SEI end asm _dgrPlotPix - JSR $3000 - PLP - LDX ESP - INX - INX - INX - RTS + JSR $3000 ; _dgrSetPix + PLP + 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 - STA SRCL - LDA ESTKH+3,X - STA SRCH - LDA ESTKL,X ; Y COORD - AND #$FE - TAY - LDA (SRC),Y - STA GBASL - INY - LDA (SRC),Y - STA GBASH - LDA ESTKL+2,X ; X1 COORD - LSR ESTKL,X - PHP -- PLP - PHP - SEI - LDX GCLR ; COLOR + ; GET BUFFER ADDRESS + STX ESP + LDA ESTKL+3,X + STA SRCL + LDA ESTKH+3,X + STA SRCH + LDA ESTKL+1,X ; X2 COORD + STA TMPH + LDA ESTKL,X ; Y COORD + AND #$FE + TAY + LDA (SRC),Y + STA GBASL + INY + LDA (SRC),Y + STA GBASH + LDY ESTKL+2,X ; X1 COORD + PHP + SEI +- LDA ESTKL,X + LSR + TYA + LDX GCLR ; COLOR end asm _dgrHLinPix - JSR $3000 - LDX ESP - INC ESTKL+2,X ; X1 COORD - LDA ESTKL+2,X - CMP ESTKL+1,X ; X2 COORD - BCC - - BEQ - - PLP - INX - INX - INX - INX - RTS + JSR $3000 ; _dgrSetPix + LDX ESP + INC ESTKL+2,X ; X1 COORD + LDY ESTKL+2,X + CPY TMPH ; X2 COORD + BCC - + BEQ - + PLP + 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 - STA SRCL - LDA ESTKH+3,X - STA SRCH - LDA ESTKL+1,X ; Y1 COORD -- AND #$FE - TAY - LDA (SRC),Y - STA GBASL - INY - LDA (SRC),Y - STA GBASH - LDA ESTKL+1,X - LSR - LDA ESTKL+2,X ; X COORD - LDX GCLR ; COLOR - PHP - SEI + STX ESP + LDA ESTKL+3,X + STA SRCL + LDA ESTKH+3,X + STA SRCH + LDA ESTKL+1,X ; Y1 COORD + PHP + SEI +- AND #$FE + TAY + LDA (SRC),Y + STA GBASL + INY + LDA (SRC),Y + STA GBASH + LDA ESTKL+1,X + LSR + LDA ESTKL+2,X ; X COORD + LDX GCLR ; COLOR end asm _dgrVLinPix - JSR $3000 - PLP - LDX ESP - INC ESTKL+1,X ; Y1 COORD - LDA ESTKL+1,X - CMP ESTKL,X ; Y2 COORD - BCC - - BEQ - - INX - INX - INX - INX - RTS + JSR $3000 ; _dgrSetPix + LDX ESP + INC ESTKL+1,X ; Y1 COORD + LDA ESTKL+1,X + CMP ESTKL,X ; Y2 COORD + BCC - + BEQ - + PLP + INX + INX + INX + INX + RTS end // // Draw sprite // export asm dgrBLT(buff, x, y, width, height, src)#0 - 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 ++++ - 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 - PHP - SEI --- CMP #80 - BCS ++ - STA TMP - LDA ESTKH+3,X ; Y COORD - LSR - LDY #$00 - LDA (SRC),Y - BMI ++ - TAX - LDA TMP + 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 ++++ + 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 + PHP + SEI +-- CMP #80 + BCS ++ + STA TMP + LDA ESTKH+3,X ; Y COORD + LSR + LDY #$00 + LDA (SRC),Y + BMI ++ + TAX + LDA TMP end asm _dgrBLTPix - JSR $4000 - LDX ESP -++ INC SRCL - BNE + - INC SRCH -+ INC ESTKH+4,X ; X COORD - LDA ESTKH+4,X - BMI -- - CMP ESTKH+2,X ; X2 COORD - BCC -- - PLP -+++ INC ESTKH+3,X ; Y COORD - LDA ESTKH+3,X - BMI - - CMP ESTKH+1,X ; Y2 COORD - BCC - -++++ INX - INX - INX - INX - INX - INX - RTS + JSR $4000 ; _dgrSetPix + LDX ESP +++ INC SRCL + BNE + + INC SRCH ++ INC ESTKH+4,X ; X COORD + LDA ESTKH+4,X + BMI -- + CMP ESTKH+2,X ; X2 COORD + BCC -- + PLP ++++ INC ESTKH+3,X ; Y COORD + LDA ESTKH+3,X + BMI - + CMP ESTKH+1,X ; Y2 COORD + BCC - +++++ INX + INX + INX + INX + INX + INX + RTS end // // Internal set pixel routine +// - It expects the carry to be set for even or odd scanlines. Bad. +// - ACCUM has horizontal coordinate +// - X_REG has color +// - GBASE points to scanline // asm _dgrSetPix - BCS ++ - ; EVEN ROW - LSR - TAY - BCS + + BCS ++ + ; EVEN ROW + LSR + TAY + BCS + end asm _dgrSetEvnEvn - ; EVEN PIXEL - LDA $2000,X - AND #$0F - STA TMP - JSR $0100 ; LDA AUX (DST),Y - AND #$F0 - ORA TMP - STA $C005 ; WRITE AUX MEM - STA (GBASE),Y - STA $C004 ; WRITE MAIN MEM - RTS + ; EVEN PIXEL + LDA $2000,X + AND #$0F + STA TMP + JSR $0100 ; LDA AUX (DST),Y + AND #$F0 + ORA TMP + STA $C005 ; WRITE AUX MEM + STA (GBASE),Y + STA $C004 ; WRITE MAIN MEM + RTS end asm _dgrSetEvnOdd - ; ODD PIXEL -+ LDA $1000,X - AND #$0F - STA TMP - LDA (GBASE),Y - AND #$F0 - ORA TMP - STA (GBASE),Y - RTS - ; ODD ROW -++ LSR - TAY - BCS +++ + ; ODD PIXEL ++ LDA $1000,X + AND #$0F + STA TMP + LDA (GBASE),Y + AND #$F0 + ORA TMP + STA (GBASE),Y + RTS + ; ODD ROW +++ LSR + TAY + BCS +++ end asm _dgrSetOddEvn - ; EVEN PIXEL - LDA $2000,X - AND #$F0 - STA TMP - JSR $0100 ; LDA AUX (DST),Y - AND #$0F - ORA TMP - STA $C005 ; WRITE AUX MEM - STA (GBASE),Y - STA $C004 ; WRITE MAIN MEM - RTS + ; EVEN PIXEL + LDA $2000,X + AND #$F0 + STA TMP + JSR $0100 ; LDA AUX (DST),Y + AND #$0F + ORA TMP + STA $C005 ; WRITE AUX MEM + STA (GBASE),Y + STA $C004 ; WRITE MAIN MEM + RTS end asm _dgrSetOddOdd - ; ODD PIXEL -+++ LDA $1000,X - AND #$F0 - STA TMP - LDA (GBASE),Y - AND #$0F - ORA TMP - STA (GBASE),Y - RTS + ; ODD PIXEL ++++ LDA $1000,X + AND #$F0 + STA TMP + LDA (GBASE),Y + AND #$0F + ORA TMP + STA (GBASE),Y + RTS end +// +// This gets copied to $0100!!! +// asm auxRead - STA $C003 ; READ AUX MEM - LDA (GBASE),Y - STA $C002 ; READ MAIN MEM - RTS + STA $C003 ; READ AUX MEM + LDA (GBASE),Y + STA $C002 ; READ MAIN MEM + RTS end // // Draw 8x8 tile (forced to 2x2 block address) // export asm dgrTile(buff, x, y, src)#0 - 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 ++++ - 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 - PHP - SEI --- LSR - TAY - CMP #40 - LDX #$00 - LDA (SRC,X) - INC SRCL - BNE + - INC SRCH -+ BCS + - STA $C005 ; WRITE AUX MEM - STA (GBASE),Y - STA $C004 ; WRITE MAIN MEM -+ LDA (SRC,X) - INC SRCL - BNE + - INC SRCH -+ BCS ++ - STA (GBASE),Y -++ INC TMPH ; X COORD - INC TMPH ; X COORD - LDX ESP - LDA TMPH - BMI -- - CMP ESTKH+2,X ; X2 COORD - BCC -- - PLP -+++ INC TMPL ; Y COORD - INC TMPL ; Y COORD - LDA TMPL - BMI - - CMP ESTKH+1,X ; Y2 COORD - BCC - -++++ INX - INX - INX - INX - RTS + 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 ++++ + 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 + PHP + SEI +-- LSR + TAY + CMP #40 + LDX #$00 + LDA (SRC,X) + INC SRCL + BNE + + INC SRCH ++ BCS + + STA $C005 ; WRITE AUX MEM + STA (GBASE),Y + STA $C004 ; WRITE MAIN MEM ++ LDA (SRC,X) + INC SRCL + BNE + + INC SRCH ++ BCS ++ + STA (GBASE),Y +++ INC TMPH ; X COORD + INC TMPH ; X COORD + LDX ESP + LDA TMPH + BMI -- + CMP ESTKH+2,X ; X2 COORD + BCC -- + PLP ++++ INC TMPL ; Y COORD + INC TMPL ; Y COORD + LDA TMPL + BMI - + CMP ESTKH+1,X ; Y2 COORD + BCC - +++++ INX + INX + INX + INX + RTS end // // Draw a string of tiles // export asm dgrTileStr(buff, 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 - STA ESTKL+2,X - LDA ESTKL+7,X ; Y COORD - STA ESTKL+1,X - LDA ESTKL+4,X ; TILE - STA ESTKL,X - LDA ESTKH+4,X ; TILE - STA ESTKH,X +- 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 + STA ESTKL+2,X + LDA ESTKL+7,X ; Y COORD + STA ESTKL+1,X + LDA ESTKL+4,X ; TILE + STA ESTKL,X + LDA ESTKH+4,X ; TILE + STA ESTKH,X end asm _dgrTileTile - JSR $5000 - LDA ESTKL+4,X ; UPDATE X COORD - CLC - ADC #$08 - CMP #80 ; OFF RIGHT SIDE - BPL + - STA ESTKL+4,X - DEC ESTKL+1,X ; DEC STRLEN - BNE - -+ TXA - CLC - ADC #6 - TAX - RTS + JSR $5000 + LDA ESTKL+4,X ; UPDATE X COORD + CLC + ADC #$08 + CMP #80 ; OFF RIGHT SIDE + BPL + + STA ESTKL+4,X + DEC ESTKL+1,X ; DEC STRLEN + BNE - ++ TXA + CLC + ADC #6 + TAX + RTS end // -// Draw a string of tiles +// Fill a buffer with tiles // export asm dgrFill(buff, 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 - DEX - LDA ESTKL+7,X ; BUFF - STA ESTKL+3,X - LDA ESTKH+7,X - STA ESTKH+3,X - LDA ESTKL+6,X ; X COORD - STA ESTKL+2,X - LDA ESTKL+5,X ; Y COORD - STA ESTKL+1,X - LDA ESTKL+4,X ; TILE - STA ESTKL,X - LDA ESTKH+4,X ; TILE - STA ESTKH,X + 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 + DEX + LDA ESTKL+7,X ; BUFF + STA ESTKL+3,X + LDA ESTKH+7,X + STA ESTKH+3,X + LDA ESTKL+6,X ; X COORD + STA ESTKL+2,X + LDA ESTKL+5,X ; Y COORD + STA ESTKL+1,X + LDA ESTKL+4,X ; TILE + STA ESTKL,X + LDA ESTKH+4,X ; TILE + STA ESTKH,X end asm _dgrFillTile - JSR $5000 - LDA ESTKL+2,X ; UPDATE X COORD - CLC - ADC #$08 - STA ESTKL+2,X - CMP #80 ; 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 - INX - RTS + JSR $5000 + LDA ESTKL+2,X ; UPDATE X COORD + CLC + ADC #$08 + STA ESTKL+2,X + CMP #80 ; 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 + INX + RTS end // -// Wait for VLB +// Wait for VLB - Doens't work on //c // asm vlbWait#0 -- LDA $C019 - BMI - -- LDA $C019 - BPL - - RTS +- LDA $C019 + BMI - +- LDA $C019 + BPL - + RTS end // // Set double lores graphics, return draw buffer @@ -645,7 +654,7 @@ end // Make sure we are a 128K //e or //c // if MACHID & $F0 <> $B0 - puts("\n128K REQUIRED FOR DOUBLE LO-RES.") + puts("\n128K required for double-lores.\n") ^$C010 while ^$C000 < 128; loop return -1 diff --git a/src/libsrc/sane.pla b/src/libsrc/sane.pla index c168a17..d09fd7a 100644 --- a/src/libsrc/sane.pla +++ b/src/libsrc/sane.pla @@ -565,13 +565,14 @@ asm auxmove(dst, src, len)#0 CLC BEQ + SEC -+ LDA ESTKH,X - ADC #$00 - STA $02FF ++ LDA #$00 + TAY + ADC ESTKH,X INX INX INX STX ESP + TAX PHP SEI STA $C009 ; SELECT ALTZP @@ -585,7 +586,6 @@ asm auxmove(dst, src, len)#0 STA $3C LDA $02FD STA $3D - LDY #$00 - LDA ($3C),Y STA ($42),Y INY @@ -594,7 +594,7 @@ asm auxmove(dst, src, len)#0 INC $43 + DEC $02FE BNE - - DEC $02FF + DEX BNE - STA $C008 ; SELECT MAINZP PLP @@ -728,7 +728,7 @@ def loadcode(codefile) byte ref word pcode, seglen byte filepath[64] - + //puts(codefile); puts(":\n") pcode = 0 ref = fileio:open(strcat(strcpy(@filepath, cmdsys:syspath), codefile)) diff --git a/src/libsrc/tone.pla b/src/libsrc/tone.pla index db8b34d..7440fa5 100644 --- a/src/libsrc/tone.pla +++ b/src/libsrc/tone.pla @@ -17,15 +17,15 @@ export asm tone2(pitch1, pitch2, duration)#0 INY + STA DSTL STY DSTH - LDY ESTKL+1,X + LDY ESTKL+1,X STY TMPL LDA ESTKL+2,X - TAX - CMP TMPL - BNE + - LDX #$00 -+ STX TMPH + TAX LDA #$00 + CPX TMPL + BNE + + TAX ++ STX TMPH PHP SEI - CLC diff --git a/src/vmsrc/a1cmd.pla b/src/vmsrc/a1cmd.pla index 22339c6..71d6841 100755 --- a/src/vmsrc/a1cmd.pla +++ b/src/vmsrc/a1cmd.pla @@ -149,8 +149,7 @@ asm call(addr,areg,xreg,yreg,sstatus)#1 STA CALL6502+2 LDA ESTKL,X PHA - LDA ESTKL+1,X - TAY + LDY ESTKL+1,X LDA ESTKL+3,X PHA LDA ESTKL+2,X diff --git a/src/vmsrc/cmd.pla b/src/vmsrc/cmd.pla index 0000624..53ac7d9 100755 --- a/src/vmsrc/cmd.pla +++ b/src/vmsrc/cmd.pla @@ -161,8 +161,7 @@ REGVALS = SRC STA TMPH LDA ESTKL,X PHA - LDA ESTKL+1,X - TAY + LDY ESTKL+1,X LDA ESTKL+3,X PHA LDA ESTKL+2,X diff --git a/src/vmsrc/cmdstub.s b/src/vmsrc/cmdstub.s index 09928ea..bd8db37 100644 --- a/src/vmsrc/cmdstub.s +++ b/src/vmsrc/cmdstub.s @@ -1,49 +1,48 @@ -INTERP = $03D0 -LCRDEN = $C080 -LCWTEN = $C081 -ROMEN = $C082 -LCRWEN = $C083 -LCBNK2 = $00 -LCBNK1 = $08 - !SOURCE "vmsrc/plvmzp.inc" +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 - LDA #$10 - STA DSTH -- LDA (SRC),Y - STA (DST),Y - INY - BNE - - INC SRCH - INC DSTH - LDA DSTH - CMP #$20 ; 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 - + LDA #<_CMDEND + STA SRCL + LDA #>_CMDEND + STA SRCH ; ; 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 -_CMDBEGIN = * - !PSEUDOPC $1000 { - !SOURCE "vmsrc/cmd.a" -_CMDEND = * -} \ No newline at end of file + 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 +_CMDBEGIN = * + !PSEUDOPC $1000 { + !SOURCE "vmsrc/cmd.a" +_CMDEND = * +} diff --git a/src/vmsrc/plvm01.s b/src/vmsrc/plvm01.s index ea4b51c..6faf1e1 100644 --- a/src/vmsrc/plvm01.s +++ b/src/vmsrc/plvm01.s @@ -88,7 +88,7 @@ MULLP LSR TMPH ; MULTPLRH ADC ESTKH+1,X ; PRODH + ASL ESTKL,X ; MULTPLNDL ROL ESTKH,X ; MULTPLNDH - DEY + DEY BNE MULLP STA ESTKH+1,X ; PRODH LDY IPY @@ -167,13 +167,7 @@ DIVMOD JSR _DIV ;* ;* NEGATE TOS ;* -NEG LDA #$00 - SEC - SBC ESTKL,X - STA ESTKL,X - LDA #$00 - SBC ESTKH,X - STA ESTKH,X +NEG JSR _NEG JMP NEXTOP ;* ;* INTERNAL DIVIDE ALGORITHM @@ -191,7 +185,7 @@ _DIV STY IPY LDA #$00 STA TMPL ; REMNDRL STA TMPH ; REMNDRH - LDA ESTKH,X + LDA ESTKH,X AND #$80 STA DVSIGN BPL + @@ -309,10 +303,12 @@ SHL STY IPY SBC #$08 SHL1 TAY BEQ SHL3 -SHL2 ASL ESTKL+1,X + LDA ESTKL+1,X +SHL2 ASL ROL ESTKH+1,X DEY BNE SHL2 + STA ESTKL+1,X SHL3 LDY IPY JMP DROP ;* @@ -802,24 +798,22 @@ BRFLS INX ORA ESTKL-1,X BNE NOBRNCH BRNCH TYA ; FLATTEN IP - CLC + SEC ADC IPL STA TMPL LDA #$00 + TAY ADC IPH STA TMPH ; ADD BRANCH OFFSET - INY - LDA (IP),Y - CLC + LDA (TMP),Y + ;CLC ; BETTER NOT CARRY OUT OF IP+Y ADC TMPL - STA TMPL + STA IPL INY - LDA (IP),Y + LDA (TMP),Y ADC TMPH STA IPH - LDA TMPL - STA IPL - LDY #$01 + DEY JMP FETCHOP BREQ INX LDA ESTKL-1,X @@ -860,6 +854,23 @@ IBRNCH LDA IPL STA IPH JMP DROP ;* +;* INDIRECT CALL TO ADDRESS (NATIVE CODE) +;* +ICAL LDA ESTKL,X +!IF SELFMODIFY { + STA CALLADR+1 +} ELSE { + STA TMPL +} + LDA ESTKH,X +!IF SELFMODIFY { + STA CALLADR+2 +} ELSE { + STA TMPH +} + INX + BNE _CALL +;* ;* CALL INTO ABSOLUTE ADDRESS (NATIVE CODE) ;* CALL INY ;+INC_IP @@ -876,7 +887,7 @@ CALL INY ;+INC_IP } ELSE { STA TMPH } - TYA +_CALL TYA CLC ADC IPL PHA @@ -895,40 +906,6 @@ CALLADR JSR $FFFF LDY #$01 JMP FETCHOP ;* -;* INDIRECT CALL TO ADDRESS (NATIVE CODE) -;* -ICAL LDA ESTKL,X -!IF SELFMODIFY { - STA ICALADR+1 -} ELSE { - STA TMPL -} - LDA ESTKH,X -!IF SELFMODIFY { - STA ICALADR+2 -} ELSE { - STA TMPH -} - INX - TYA - CLC - ADC IPL - PHA - LDA IPH - ADC #$00 - PHA -!IF SELFMODIFY { -ICALADR JSR $FFFF -} ELSE { - JSR JMPTMP -} - PLA - STA IPH - PLA - STA IPL - LDY #$01 - JMP FETCHOP -;* ;* JUMP INDIRECT TRHOUGH TMP ;* JMPTMP JMP (TMP) diff --git a/src/vmsrc/plvm02.s b/src/vmsrc/plvm02.s index 2891b8a..c9d7ca2 100755 --- a/src/vmsrc/plvm02.s +++ b/src/vmsrc/plvm02.s @@ -660,10 +660,12 @@ SHL STY IPY SBC #$08 SHL1 TAY BEQ SHL3 -SHL2 ASL ESTKL+1,X + LDA ESTKL+1,X +SHL2 ASL ROL ESTKH+1,X DEY BNE SHL2 + STA ESTKL+1,X SHL3 LDY IPY JMP DROP ;* diff --git a/src/vmsrc/plvm03.s b/src/vmsrc/plvm03.s index 96e20f2..ba7650f 100755 --- a/src/vmsrc/plvm03.s +++ b/src/vmsrc/plvm03.s @@ -131,7 +131,7 @@ INTERP PLA PLA ADC #$00 STA IPH - + LDA IFPH PHA ; SAVE ON STACK FOR LEAVE/RET LDA IFPL @@ -161,7 +161,7 @@ XINTERP PLA LDA (TMP),Y STA IPL DEY - + LDA IFPH PHA ; SAVE ON STACK FOR LEAVE/RET LDA IFPL @@ -273,13 +273,7 @@ MULLP LSR TMPH ; MULTPLRH ;* ;* NEGATE TOS ;* -NEG LDA #$00 - SEC - SBC ESTKL,X - STA ESTKL,X - LDA #$00 - SBC ESTKH,X - STA ESTKH,X +NEG JSR _NEG JMP NEXTOP ;* ;* DIV TOS-1 BY TOS @@ -432,13 +426,13 @@ SHL STY IPY SBC #$08 SHL1 TAY BEQ SHL3 -SHL2 ASL ESTKL+1,X + LDA ESTKL+1,X +SHL2 ASL ROL ESTKH+1,X DEY BNE SHL2 + STA ESTKL+1,X SHL3 LDY IPY -; INX -; JMP NEXTOP JMP DROP ;* ;* SHIFT TOS-1 RIGHT BY TOS @@ -466,8 +460,6 @@ SHR3 CMP #$80 BNE SHR3 STA ESTKH+1,X SHR4 LDY IPY -; INX -; JMP NEXTOP JMP DROP ;* ;* LOGICAL NOT @@ -988,24 +980,22 @@ BRFLS INX ORA ESTKL-1,X BNE NOBRNCH BRNCH TYA ; FLATTEN IP - CLC + SEC ADC IPL STA TMPL LDA #$00 + TAY ADC IPH STA TMPH ; ADD BRANCH OFFSET - INY - LDA (IP),Y - CLC + LDA (TMP),Y + ;CLC ; BETTER NOT CARRY OUT OF IP+Y ADC TMPL - STA TMPL + STA IPL INY - LDA (IP),Y + LDA (TMP),Y ADC TMPH STA IPH - LDA TMPL - STA IPL - LDY #$01 + DEY JMP FETCHOP BREQ INX LDA ESTKL-1,X @@ -1044,19 +1034,26 @@ IBRNCH LDA IPL LDA IPH ADC ESTKH,X STA IPH -; INX -; JMP NEXTOP JMP DROP ;* +;* INDIRECT CALL TO ADDRESS (NATIVE CODE) +;* +ICAL LDA ESTKL,X + STA CALLADR+1 + LDA ESTKH,X + STA CALLADR+2 + INX + BNE _CALL +;* ;* CALL INTO ABSOLUTE ADDRESS (NATIVE CODE) ;* -CALL INY ;+INC_IP +CALL INY ;+INC_IP LDA (IP),Y STA CALLADR+1 - INY ;+INC_IP + INY ;+INC_IP LDA (IP),Y STA CALLADR+2 - TYA +_CALL TYA CLC ADC IPL PHA @@ -1075,32 +1072,6 @@ CALLADR JSR $FFFF LDY #$01 JMP FETCHOP ;* -;* INDIRECT CALL TO ADDRESS (NATIVE CODE) -;* -ICAL LDA ESTKL,X - STA ICALADR+1 - LDA ESTKH,X - STA ICALADR+2 - INX - TYA - CLC - ADC IPL - PHA - LDA IPH - ADC #$00 - PHA - LDA IPX - PHA -ICALADR JSR $FFFF - PLA - STA IPX - PLA - STA IPH - PLA - STA IPL - LDY #$01 - JMP FETCHOP -;* ;* ENTER FUNCTION WITH FRAME SIZE AND PARAM COUNT ;* ENTER LDA IFPH @@ -1109,7 +1080,6 @@ ENTER LDA IFPH PHA INY LDA (IP),Y - PHA ; SAVE ON STACK FOR LEAVE EOR #$FF SEC ADC PPL diff --git a/src/vmsrc/soscmd.pla b/src/vmsrc/soscmd.pla index 769d876..2a9d18a 100755 --- a/src/vmsrc/soscmd.pla +++ b/src/vmsrc/soscmd.pla @@ -153,8 +153,7 @@ REGVALS = SRC LDA ESTKL,X PHA INX - LDA ESTKL,X - TAY + LDY ESTKL,X INX LDA ESTKL+1,X PHA From e1faa30970462cf70a4e6fd6d8ed2e0b4a4ae4c8 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 20 Jan 2018 15:54:05 -0800 Subject: [PATCH 24/45] Developer Preview 2 --- src/samplesrc/rogue.io.pla | 12 +- src/vmsrc/cmd.pla | 217 +++++++++++++++++++++++++------------ 2 files changed, 152 insertions(+), 77 deletions(-) diff --git a/src/samplesrc/rogue.io.pla b/src/samplesrc/rogue.io.pla index 8f8c882..ddf40e9 100644 --- a/src/samplesrc/rogue.io.pla +++ b/src/samplesrc/rogue.io.pla @@ -4,14 +4,14 @@ const modkeep = $2000 const modinitkeep = $4000 byte[] initstr -byte = " ( )\n" -byte = " )\\ ) ( /( (\n" -byte = " (()/( )\\()) )\\ ) ( (\n" +byte = " ( )\n" +byte = " )\\ ) ( /( (\n" +byte = "(()/( )\\()) )\\ ) ( (\n" byte = " /(_))((_)\\ (()/( )\\ )\\\n" byte = "(_)) ((_) /(_))_ _ ((_)((_)\n" -byte = "| _ \\ / _ \\(_)) __| | | | || __|\n" -byte = "| / | (_) | || (_ | |_| || _|\n" -byte = "|_|_\\\\___/ \\___| \\___/ |___|\n" +byte = "| _ \\ / _ \\(_)) __|| | | || __|\n" +byte = "| / | (_) | | (_ || |_| || _|\n" +byte = "|_|_\\ \\___/ \\___| \\___/ |___|\n" byte = "\n" byte = " By Resman\n" byte = " Artwork by Seth Sternberger\n" diff --git a/src/vmsrc/cmd.pla b/src/vmsrc/cmd.pla index 53ac7d9..4e04939 100755 --- a/src/vmsrc/cmd.pla +++ b/src/vmsrc/cmd.pla @@ -22,6 +22,11 @@ const resxhgr2 = $0080 const modkeep = $2000 const modinitkeep = $4000 // +// Prefix commands +// +const GET_PFX = $C7 +const SET_PFX = $C6 +// // Pedefined functions. // predef syscall(cmd,params)#1, call(addr,areg,xreg,yreg,status)#1 @@ -123,7 +128,6 @@ word lastsym = symtbl // asm saveX#0 STX XREG+1 - RTS end asm restoreX#0 XREG LDX #$00 @@ -143,9 +147,9 @@ asm syscall(cmd,params)#1 JSR $BF00 CMD: !BYTE 00 PARAMS: !WORD 0000 - LDY #$00 +; LDY #$00 STA ESTKL,X - STY ESTKH,X +; STY ESTKH,X RTS end // @@ -195,13 +199,6 @@ end // CALL LOADED SYSTEM PROGRAM // asm exec()#0 - LDX #$00 - STX IFPL - LDA #$BF - STA IFPH - LDX #$FE - TXS - LDX #ESTKSZ/2 BIT ROMEN JMP $2000 end @@ -773,6 +770,88 @@ asm lookupdef(addr, deftbl)#1 RTS end // +// Reloc internal data +// +//def reloc(modfix, modofst, bytecode, rld)#3 +// word addr, fixup +// while ^rld +// if ^rld & $10 // EXTERN reference. +// return rld, addr, fixup +// fin +// addr = rld=>1 + modfix +// fixup = *addr + modofst +// if uword_isge(fixup, bytecode) // Bytecode address. +// return rld, addr, fixup +// fin +// *addr = fixup +// rld = rld + 4 +// loop +// return rld, addr, fixup +//end +asm reloc(modfix, modofst, bytecode, rld)#3 + LDA ESTKL,X + STA SRCL + LDA ESTKH,X + STA SRCH + LDY #$00 +- LDA (SRC),Y + BEQ RLDEX ; END OF RLD + PHA + INY + LDA (SRC),Y + INY + CLC + ADC ESTKL+3,X ; ADDR=ENTRY=>1+MODFIX + STA DSTL + LDA (SRC),Y + ADC ESTKH+3,X + STA DSTH + PLA + AND #$10 ; EXTERN REF - EXIT + BNE RLDEX + LDY #$00 ; FIXUP=*ADDR+MODOFST + LDA (DST),Y + INY + CLC + ADC ESTKL+2,X + STA TMPL + LDA (DST),Y + ADC ESTKH+2,X + CMP ESTKH+1,X ; FIXUP >= BYTECODE? + BCC + + STA TMPH + BNE RLDEX ; YEP, EXIT + LDA TMPL + CMP ESTKL+1,X + BCS RLDEX ; YEP, EXIT + LDA TMPH ++ STA (DST),Y ; *ADDR=FIXUP + DEY + LDA TMPL + STA (DST),Y + LDA SRCL ; NEXT ENTRY +; CLC + ADC #$04 + STA SRCL + BCC - + INC SRCH + BNE - +RLDEX INX + LDA TMPL + STA ESTKL,X + LDA TMPH + STA ESTKH,X + LDA DSTL + STA ESTKL+1,X + LDA DSTH + STA ESTKH+1,X + LDA SRCL + STA ESTKL+2,X + LDA SRCH + STA ESTKH+2,X + RTS +end +// // Cheap and dirty print integer // def print(i)#0 @@ -783,21 +862,12 @@ end // // ProDOS routines // -def getpfx(path)#1 - byte params[3] - - ^path = 0 - params.0 = 1 - params:1 = path - perr = syscall($C7, @params) - return path -end -def setpfx(path)#1 +def pfxop(path, op)#1 byte params[3] params.0 = 1 params:1 = path - perr = syscall($C6, @params) + perr = syscall(op, @params) return path end def open(path)#1 @@ -863,8 +933,8 @@ def allocalignheap(size, pow2, freeaddr) *freeaddr = heap fin align = (1 << pow2) - 1 - addr = (heap | align) + 1 - heap = addr + size + addr = (heap | align) + 1 + heap = addr + size if uword_isge(heap, @addr) return 0 fin @@ -1087,31 +1157,36 @@ def loadmod(mod)#1 // Run through the Re-Location Dictionary. // while ^rld - addr = rld=>1 + modfix + rld, addr, fixup = reloc(modfix, modofst, bytecode, rld) + if ^rld + *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 + // 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 + //rld = rld + 4 loop // // Run through the External/Entry Symbol Directory. @@ -1192,9 +1267,7 @@ def volumes()#0 for i = 0 to 15 ^strbuf = ^strbuf & $0F if ^strbuf - cout('/') - prstr(strbuf) - crout() + cout('/'); prstr(strbuf); crout() fin strbuf = strbuf + 16 next @@ -1208,9 +1281,9 @@ def catalog(optpath)#1 word entry, filecnt if ^optpath - memcpy(@path, optpath, ^optpath + 1) + strcpy(@path, optpath) else - getpfx(@path) + pfxop(@path, GET_PFX) prstr(@path) crout() fin @@ -1234,20 +1307,22 @@ def catalog(optpath)#1 len = type & $0F ^entry = len prstr(entry) - if type & $F0 == $D0 // Is it a directory? - cout('/') - len = len + 1 - elsif entry->$10 == $FF - cout('-') - len = len + 1 - elsif entry->$10 == $FE - cout('+') - len = len + 1 - fin - for len = 19 - len downto 0 + type = ' ' + when entry->$10 + is $0F // Is it a directory? + type = '/' + break + is $FF // SYSTEM file + type = '-' + break + is $FE // REL file + type = '+' + wend + cout(type) + for len = 18 - len downto 0 cout(' ') next - filecnt = filecnt - 1 + filecnt-- fin entry = entry + entrylen next @@ -1263,17 +1338,17 @@ end def stripchars(strptr)#1 while ^strptr and ^(strptr + 1) > ' ' memcpy(strptr + 1, strptr + 2, ^strptr) - ^strptr = ^strptr - 1 + ^strptr-- loop return ^strptr end def stripspaces(strptr)#0 while ^strptr and ^(strptr + ^strptr) <= ' ' - ^strptr = ^strptr - 1 + ^strptr-- loop while ^strptr and ^(strptr + 1) <= ' ' memcpy(strptr + 1, strptr + 2, ^strptr) - ^strptr = ^strptr - 1 + ^strptr-- loop end def striptrail(strptr)#1 @@ -1295,7 +1370,7 @@ def parsecmd(strptr)#1 if ^strptr cmd = ^(strptr + 1) memcpy(strptr + 1, strptr + 2, ^strptr) - ^strptr = ^strptr - 1 + ^strptr-- fin stripspaces(strptr) return cmd @@ -1365,7 +1440,7 @@ heap = *freemem // // Print PLASMA version // -prstr("PLASMA Pre "); prbyte(version.1); cout('.'); prbyte(version.0); crout +prstr("PLASMA Pre2 "); prbyte(version.1); cout('.'); prbyte(version.0); crout // // Init symbol table. // @@ -1404,14 +1479,14 @@ while 1 catalog(getlnbuf) break is 'P' - setpfx(getlnbuf) + pfxop(getlnbuf, SET_PFX) break is '/' repeat prefix-- until prefix[prefix] == '/' if prefix > 1 - setpfx(@prefix) + pfxop(@prefix, SET_PFX) fin break is 'V' @@ -1441,7 +1516,7 @@ while 1 fin crout() fin - prstr(getpfx(@prefix)) + prstr(pfxop(@prefix, GET_PFX)) strcpy(@cmdln, rdstr($BA)) loop done From 82f8a30b420fb0451f00226e3dbeb3fbb4a0941e Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 20 Jan 2018 16:03:08 -0800 Subject: [PATCH 25/45] Developer Preview 2 image --- PLASMA-PRE2.PO | Bin 0 -> 143360 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 PLASMA-PRE2.PO diff --git a/PLASMA-PRE2.PO b/PLASMA-PRE2.PO new file mode 100644 index 0000000000000000000000000000000000000000..1db17090dc2fc33c882a2c660d88554e42b4ca38 GIT binary patch literal 143360 zcmeEv349b)ws&<`C%q(HUA;gzdl?}lY({i6fewj*1dB+SAf86;rVzg2XX)ki~RlDF{fSL4rsKTPXIu`upGN1ksr{-}m14esA9Q zKAUvct$WWs_ndRjJ@?#mZxx!%Fzp%rm!*@Uw4o?{K`uVV247Afw#1#*SnHO?gc*V6 zDMQC?p&YkxpWExp^0@=QsCAdUVr*-G}+0jJ*F_B6(Ym%k; zf=<$ga$WPUO|JBtJEn!E<%ScZCi$*_Zb`1FHKtoCYjaz*M(OK9_Ds4Q<)pCzwl+5! zlWu6N&GluIpQ!@n%MA=%GHuC2jZ3DJmYk%e6?q+b1f zGw$GeJ|VAfa_Ax7l*inZVc_8LQ>H$7YS*^a(>|=O81C|VJ~0Y!yM>rr&;%*Z)2F!E zmjeCkW*W~u#YhcsXwd(`Y_O0u;HV04=x+9$)mN2}k zzMw%E5wtc*mk(;BvlYX=q3m>hRF_U0OliY>w}qzWhO!^Y&Gk(%`ECzQ@eQpQUjKXp z_ldD%Xvb|Gw}ojWKPhbRhO$h)JHYClp*wstGxy&vJHon-JN(*>cVu$&jiH$??g^u` zFYxS=S%$RCjkDw}E<>Swy1ux9y-5A^`AGtC3DDHVnVt!EOrJ1n=Bz2B<9XK&zLue= z`0u`<=0qxya%s8;$`!fA^i&GqY z9IR!v)Q-thrq8$v&hmT@*bp=gY&Q<305-ClHXyxo%5;i~t*7)R1Pn$~QnHz`uvVMh(W|%9 z)u(U2{sRUM;;u=#cJPqYp=tl^Irxdd{~HN-61lDu*MuhV&!ljNhtxcuQeBk7rKX3k z4NyXik42`(BAHSe5@IYOapIx|ZqAT!VkkMClW31SrRIf{>S9s>#r&zu;YR>bv+`nl zqBK!xAJK5p0LYuuW@f3-UAk5iuiJh zoY)mpJR7e84zVnfZh)Y+T*D_dhzaYWnbJ^Ezb@*6D3jJjHBuijc^!fn1rke0X^b|= zH;Nb5MMuaZQJdE^@OL#3f^{Z_(ru=6l0G+2P4IU%@Kl4WC$%n13Ah-w{PGBCy|>`u z6C*XHDb+8j9fKkbDLQeDoB)Y?DUOP4_*05BU0kS5x5(M9c^bYzD_qAf)S_f#L5g%k z)lx@5i!esmlmx5ajWk|!KPV*%_j7l4#F=6@Wpfm+kHWeBY(@@(en!309`an$cMr!aE76wjU4iVF?VZ>4d_ZG6!n-GuA5B$G5sw3wuHkugQz4yW+FOrqJuJ4`5SVoj12 z*G(>yWQ1@zM3mk%)I5A`{lnLmSL&Ojv$E3nN8um{U`upIU}JRC2GcUbkH#*I9ET=x z@2P`b2T!2~tZFojCDAY+8@A!%w}h;@epA#a4-|Ahw!<1=h1l(^^i^doEALFVpf95a z|E923ex@>*Sj#?ejmad{7dEk{0#suyTULOfS9aXEsX!~qLI6>_<@4;kjxf`hV3Ho{ z=6DX_`0+T$|MDY_<;3XS@+?(2gzr(}Y@=)vsfOqq63w#>5CZ~hl(;NKN(8pKeNDlk z^~;S!9PHVQA=NsQFf{Y1&XhY}XR4}eR|^oz%SeLqG#JZ7JpySN3c_et#nCoKx2zAW z4FqeNTbp-m*c?=)7eGjj`~~8fB+mBv_O+W4cSGQ9?e@<%5CD|_Nd7I|NYp|CP({%N z&@YWvgU--tKs!E~o^^3IG=}=Bi5UIMCN{Arg|tlEdvCo=Am?0|6T8!Z91&k= zz@Ha!xnyDqGv#Z9g7!qYpODplNV3!nyx1JI)Qo?2mW+pSNaq+qa zUfVz{v@ye%97@VOnBYqaYd4x)UNNJAPbOxATcU8+U4*gao>y8hYJ>Xv@u}r&bm*Vp zfcmMaKSBp(MH;HxOo(ytbw^eH09{s#=M<8Bz-PX<0&K(=JR|le7*40!8YU|dlM3uFh zHU(6$=D_w1%^S9VxnX?`k#^4~NG)|N?X{F`D!D!)F#PIN;WM9=W6~f0C{_4eO@;5r zfEW^uh417)ObzI3S=iz7w185}rqfY6Q@V|#(_Mz#kX17KY?%h}`ZU0aqtp0Rsoeau zG=Kjlf_uyARQy%1PVKC}AyPIvQa?IUc0;7e#jPE>(HgR*>t))rE479Yk$H4=s+{7Q ze|?0%KGGR5*Nu+23Hazpe);G~XJPT`)FZ1?{ha{{;3#mXKRZ1mVv@A^jZN$^W5r(YlmSB+$cK~QHO6F}cKY5{5uP(ccX zF}c?^RDC84|lgj1#;TT0Vi6pDsa#h+%(%jzknuOu)w9Igm zhH*#IJ)_gH{qXcK?yg~;igc6;)C#AZTv_U9lrDDk+US%{ujnls$o=}>{__9_3?P?h z&Sib9U)y2zhU^=9`IDp(A=?IrpOyxDS2&lu=GuLB{PyzoBGn6PZKaOo(z%VjHrh8j zS=k$)LQdI2avP=d9lbh`D;*E@mW^uG`rgu6Z*{`(!de%%aG01doGTyZKZZ)U4-b>A zQCiXmv?vm2QgXnXpI_lx(MO17dMnr!R)Na&*18~p-TL8v{cg)}f1(U4blmHD#yPyy z<#o*kuwT=-zMo&ap|8)iq>tB~PFLpV=2q2j7*?2}%gvR}r_)|zTAy1@Y35s#hV>aw zuDJif)iBID-ZX4L@-R|9YyiIT@}6stQTf}e;VIX}&oXvscTjHkDT+G9Ql~W6pK=wr z-9fDpp32^QAC>RZlA@P}6Rl_rDlMs*>9KSw%8CrtYHz|{|u7huz8iD6KG}3i_1hz*YX3G1YNytA5m*{G6 zV@eF_R!uCgr<>SwBR`>~TPm^zhP#0d&~@ACG93etL{Ru`^zr~x_8DC$T`2yH4(RK? zq{~uBnTRS66@NmPtfiT?w78azM#83OBIcW7+B1=^;`VC|;k=^g*09dVN{Rg92J#2U z2HIT{p~;#enQx#W;|LAd%Gz5?C)SQD%_@{mlNCmU&PQol*vP-ofIse2t>+t>{5}F7 z9cWM`3>U892lW!*fz0KP(n8F0h8FAT-0%Q2=bPl4AVz4I%q)=UyUj;B`BvXJxgROS zEh)r3DFmo$T(dgHcTDhd*VEiO(r{0cm8G|qjw_VTd!sr@C+H<6YVm&+q_CI!fIs2j zOplMwJZOko{fP&yo$OhvvOyyy7P;mbBwJ?@G2I}1xvVW*?wY@rHgOGCqYm4-o9KY0 z?lZdd)YNYt>NXc7~d|#Gpo{oPLi3#&4zC0qn8gZw!1gK(5q_H-O zOp&f%XQdCSs?FNH;Ii~2^4$3PCZJ+~s`p=(`)|vVeo?>Ra&)fDm{>=6KyEtCY4&&) zedD1cTw(-?+<6+`MDCMsND`>HiS3Z;vPiWh(x6#xcq;FWNPd-A9&w9rM%+d20HH>r87D^Lz87qCs%PPY~a58 zCQPTfyrfEKQo8J$1oEru*$BU1skcV>4&|}^%ArGtyuOK1tv`|b)#dO=Z*F)*kgor8 zMCy%oZkF7){LhiX+N|m7obn-{;11voXaIB?zQA!)l|TWw{Mm@h z8=ArwMoONK6cVl#ogGzN@q#Sw(6ot&GQJ}Y!#`s;^95~IlV`UP}E}uk;fKA9$ON5 zY-xnIMDp`ROC-}cf|bfNL*9zyimwQ2Ys;uRZK!-XW=A0Pnp-=_*lh7R6W)eP7b?)k>ofE2nnx zl}bsKvZ+J~|Ew0SbZ2AqIyo!)kYAhrAWFL`6)A!IBu7WdUqv(g$K-UGzSG zQ>Kswe{@8p!s>vgsS_3C!zCq3l~}1n*>HP_sMJ&`$gL3-snjJ_1DW_*ME=|hZv3Wd zYM12Uj>KGE?zR2Em?e!9XDI1XjwIbs4Okkmm6=CNlxTzhl`8IJOw3XE7ZuT~@P0*n zNa0JBI%*ftH+D*ATwY;Xrq`v)Adifv84&#!ijc)OVS#ojye~ijU6riMiOtiN=E=Pq z>#1F(dFe9D?sd|cPU%>qa9wGh%d4v6eNkih9``{i_mM{);TI{D`K?roG@&l3g`0G# zW{V;ZT{^9^b7@YUrUh{|akJvf^|>)DT3aQVL7+q>Fr&f+dZV!cFUhOzS^Z z0M0%CtyrbF=CLS*e4E()FrZ%UfzI&QASGzI&4+6iDt=34y|qw_+1BM@j?j{T ztc+xCO=s9D+%qDiWS9WSu?K}w{()}p(zp4IrFqeNB(|}pLIF>uc_1~U2=`=qQ5zjy zU8NvVn%CL51zmp%w;;}%M})^!?GNjOshQqrwsZl@q^zh89cxBh4g_bP3MYv#D6-zO zZXf9^@g~K5vjX|&Wa8+KJ2chJ1rAl^`=;jmvWvp)ytb{FZsS@Hhj#`wtFp_fwt8*b zvTOtnI*ZD+ZROPNPU$QuUJXPwH!FnWOhstJp(&lKNjA>EMe(2Q$O)gsNh^D;`{~xp zrS8V%IWFlWsbujO_6bxKu*MO2xz+oyp35qGP${xzRTVbqr4vO`5)7F?QvNRx?^(i( zfF*z+L8%8|6ve#_=54T;hj@ziDhQAIp` znSV?{l=ERl%vJb*Rm5ou|2u^!eY^a#;K2GBO1Z8LP32_px;DfUj$bZ!wAG)wT+Si) zcu-q1SE=_XiuwLxOxn|ZHN{E*_yUNV(%mew_iDA8nvTm4Yscu6lw}ST{o{b;D}_ z^&7G!J;>iMRc1+}E0I+*O$DwDXzC^@WkcGCPnV_eDQX|yDeBtN1L)&W7+DH>Oq6tEeIYN#yij?m-<5nT?@>g$jh{~RAWs2$F8@HLObe5} zLbjKC=z#nfoE$ge36j(qu!7a>Mm`rD_@?rZ@9x9l!QzlMv?ivu@y{#bHEo9uiH^1) zl{w6>=`=|f+7o1*kP8!2*5PT{A2ikXZz~_8_HK6vkRBh}R(=!7^NJId%%erhJPNdg zvO!yDDo8_=Yofvzbq^+=JA4D7Niq{w(zv>gE?l{EOV@J>%mGHjZdh`*6O#)`=wTJ4 z6E5$TA|+Ek4>fhob^HI?k>m2O<_Zpkanvp_vFs*v#|0P#K1Tte0SzorXT7bpY^qY< zx3z4FQkPAY3+=013j7%<@(NIDO znMVk3x<(|)R3q(Mo}qCGcX@*p!~^Y*w)^#nV3VmECR^7=*gg|C*2i7m9s*$S{r3R% zpmM6U6W$Z|r~Ton+>Hmr6UYFvRJzRzm8v=&%wsDtZ27o?Q_Lb5zvZ@8jNfv5Ybd+C zcWY>Bxw91`xx8fsLp1nQf?mG^HIf3KAHY89VU${nrsj@Hbh zOGpDpeTrWTRdQz{@=`~&$uxKAU>&tvy*5fmN4%i0HdHeIUXd}kAIdyhOop%5)Z3lJ9@KDqUY$rz4e%@`{y5dcOQi z3X-E4y|c3ZtzeWCLC;@R5UvB; z1LODnt4j4UB_n|_o(>ecw;UGNHxWAQh7d6(#n;H-UXH;nE&sqBrWfogNL%sMl4?Sm z;VIt~n2E{o^PzV^;`8_>U0EMNOBX2tZN06fG^?|*AwfC~@}@(Rbja`Q%!DVf9DTLB zR|`Uh9ZiMHb2QT7>P3)5OS%GW7TS#gih(jjOz*C6QAu!Hr^(Iy-VAJG-I0COn2jA;o?Ewi-v zM|n|1^3M|B%360v&NjD{6s08n#vFn6+;9{}!!cWJ%;79u;q3$njX%-@I1zy31kJ`A zVC`dQDKoU>=5qHP^^f6lj)GZ%s)Uz@P;8ER*_Z<}QCXTxa;B-5jnmLSweF2M80Tk> zhSNX{Ff}#?wRN_Z@@JI#*Of9`3w#IJ70UH_&~&F~^Ay?e>#ylpSl3yoB-lH0viD3a#f$;P z2d*x2Tf8vhLDz<;VO6VP>Yfh(fuznE2%rGrhqFNq-*5_@i|4RX@~cZ+^S$A2H7HIKr*U(Np(Ek z;L9fM6p=gb)Wz^%u4AwGN~Ek`3sf6Hqv1lV%+Z4VbE@oh;wx}B9r5>f6Imp+$cfzT zmylFR%ZGJ?B76t?s0?hyWMV8Rx3&^MswI#>;th~ikpd5nU#wKtfH4~Vi$cj~NINrU}E zNOQefj=rvtHC?$<*SqED8)R|EzonS5q+y zKRTmsP>V}8W%7Sf>P#(sK&gIRA;YkyT=5o31~4Yi0@+Qqp3=PV^+j@@rbg*xXnMyC z!UYX3I;KyVChuJ{^Ev{Gc`7l442edaLeDM7Yds_XqD&7c(uPLK^nIlfuO2UcU0I;% zEGbtEuH|#{e0kWZnUUs2(|KTM28i@@>?N|hE-vMnC&84Ti+VDp{@gQ1VSuomxCqW* zOKC1#5w-<396S5iDr%DhIxObYZY8TawNHT$nt@n>7J-I%w1H&lTZj*~NO2KU^tu9T z^h}dd{-jcrqm^|CQgqfoskCASNR)IiP$#@x{)zfOC}q7`>YpJ-3y{b@id=5!3H(B% z%KxDF6HyB=DC&awP{*LRTLZaSP(rP$gjw7zr{E`CrDA7~V;JoxOb;e{q?aGY(S=;; zQt=Xn_rV!G7)~bnI@!!Uf70)8b2pvH2fHK>;luq~bHPKkmJzXkPdwlnr znL|jAvp?+d)RTXwpGhYZnr6b1yTsR(p6=%IE~I(6?I**N$iSk(0@61V7Df}oD?utq zR!Jw66QV63nrY#l#U$s+QOBbOwq-<@Kk6m*CXh}|ZgG>EWyvj=HQnI5%-qslF+g?X zM}Oel43{iTHcLbYU%? za60Vas!yp=EG>L_Xd}GoU1E(QkM?rr)8SEsDFm`^zZAX}%O*&HYKb?G^$CpVHv?NG z1I%dpvoNDBZ+H|zB@O?+IW&_%n(5Vz`;dzu*T4*S?Dd;HU!4Y7H42GRo{XE%J$3zC zGW3Mg1#&aFbh|7&NV?krY3!a|z(lzl!$3MiJhUq@1p$jhgd?h_E1PrSZ*H1~D3TiQ z*nJpr1MbcJgeg}G0xJ+L{|hBZk-_szr4vq#5nWi0V2pI6E}=!;Gl9EBVmD^^TQk%s zNncXEe@ptaW&K+a`+x%~B@hP`%YlH#4fYdV`QXW$-|aoJ%y;;-im|qPrZ_-G z;kUr1Iwb1&#kf5a&;?;BU=nb1HmJp*-~BowxsnUPtZokx#l2dZ3LCWH)1JHwq@&)d zP-Bc0xl73a>-KO+J!jl}ATvnStL{!C_>@j@`3Er^_|?RjwK6f*ar%~QsKN84DQT$ zgYPS3D7acKf1p5<8#{|I3my_{RaXEI(0<|{wx373$18hX$tj3CWn`xF>#Oq9iZTsu zZtNNGdF2*6JaHeo*Hu0=v9QQ3AJhWlTW%sF2C?Fa(X34AUO^^78j4r#88jFC;}@C5eJJbEq57ZZs7UwJj^**sUT>s$Kn_B1I|fsW6vW4QOOK4VVoj( zCdTu2Q*8#Aio{}p1nko!W2cI|)8(xe2$IbC0&D@AV{1r!wv7Zy5Cmxhm03{Ms{*sf z5q&2N9)#B?%nW}^oVP3(V=x1$kjRs4h-Uc_MUsvZ0@k8|PpMtYpQd(^28aOS-e0<0 z)klqkwo8%=VfmVe)Bs>|^R=ymMzdb;Ws8%xQ z>enJcMCU-(RFFly$J=_k7E=|1$Zi~w1EB?QlJkh?9uFw@CA$IdtGfYVbyUlsT<^Jj zp2(W7Rf5=oDX+x}=mK^eKT^655MADKKnXK7fPY`%1|AC280xUOP=(DTa=K-*vSpG2 z4MzO5Djy5NsD`Xr#SfIH9j#c=iYt|;d$nRg3-_~stJl98kvcb7U{3@sSWzMpOO}t} z8xW_%en)B>)*6IjUe`v#nf(z8jA{@al(hbJr1>OdbO#H+^Qx;7_j1+I?cahkhW%Ue zEAzb=Ur`QcZpa2qmOn{dCU|l$daM_P0)CCc{p-c>gVk%4O&==q?4TaO3q+6lAar3w z{G$9bg`9*!nbgq;X?(1Z9QJHs@fszlFR3H@3BK$BpDFU1`p>#)w{h=Z44VnLhMGD6 zw`RQQt^QDHJmwV=7csrqJbM-2v5up;)`Ha-5 z$Ng1xYOd5_y&@rwR7@uo2UmZj$ccqg|LWBk-(}S9M(F~wBqQ$2s5aa|i@fMP^q~h) z|FBZz#+@6|jL(tSrKj46T2Q-T#jvXT=3*v9c#wrgfD#PC_|g>-bf<7 zVXEd8fHxw1+_M$o6%Rlys^mm~0UY!cfeI|`YqP4N1{kAH!sC3?3Zc)r($6~aY2yBH z>6Y0MDeb#y(#f8TKC>fbvm?kkL5wWbVk%2&sR~Uie*$X?;co02);}KMH!Jl|MEEU= z7yC>`O6JgAPejTekJM~I5Fw5@CkE8ObYzPn9dmh$;;|%m5msVQl+cW*)*r6;>~ZtFK%h>%*8N=JKqcx`0_aKB^+a; z;k;q}eIARB8E{$=+f$E+<4^}hVK3l34vf*lHlGGg3+2;R2I<0Ds#J@^PaT>Lx=A{o zk6l%)1J50bpCS z1z8+x&}lWvW>+6P0y2;t#1*{!3V8s8JPkt5U+!4DeMiqRTb$t}DE=S&q)ke{{+7%e zMrPhJVdhNFlsNTAE>WIo5u8o%PTb|8+dbxXs`{IM{Ezz4c@5xI5f06~!SIylqX_!g z(*l@=zb_wj!9V!?ozm%4yPSZ-^-_{}I)XF7GES8=&rFY8Mh4jtm8 zFT<&U1k%O zIPQ%vxvzE@gid||ayHLt=I1mUOn7MncDCw^8q#D_T0qbFfcb&}XNwZWyPLV>ZE2DP zM>u@V;)3RkGpH}$kFrN|F|Erx16jrMnk&X}%bWdux6Es1PYFY}Jkl(U5$|nwo93}< zvBXqA(Y)#2X4yh=mz%ie9r-}(ZxkPI-h5B9^m%AvuHVL8ZVuNAl$6QO2Euy0H-e*f z`n!bT(ox*<4d8wl-U;D3E1CEwnz zvAgk`=FMo-1IOdhX0*)zx;gXcZ<^(s!}^?9*S*dDgn7!Adz&{u+U%#rN1JgVL0g&0 zJ-4myx6OpvUpKpetnN?brt8sWsUBAs(2!SSj3ckcs2Jy^bg`HrImS9%Fis7zSbq*? zad6s*j2mOI%v-Z2yFIa)ch0`w`^$WaV>7;~I!q3KJr-N=uTSCnr&z3DNvyEg|H|?= z1C&9R99vOY9SeWB=97l?jj`A!X-7+2d+fW;Bl4+pm!M~_YANb9487MeBHn<7EZ1tO zw=`PnZCXoJ;6Z?QwHoR@jfSeGHI#@`Wi@zW<$VoJeE=K15+?OSEu~$hp|q=MO8XI| z)z-mGe++Z|S6Zw6gwkm1wHocGu-_3{qy2)SwVSoHc8iAAZl!50rUT8FT1vA^Lup!R zO7j(^)qJhhYTEEL!fslt`G(SH_FxLwuhC#q(r6A)wC13e)*RB%n!_}$If7$uN3|5) zrJ-n?Z=+98TKc3`OP|tc>C?29K0|5fvsw*(9<#^=T0>u?X!??trY~bsQD~a}kv03r z1M)wqRFjc5m>W2tfByv|Qd0(zg!(F!t|yuiNL$d1HJ;Sv4O}XIw7C&Scphz*?^a(~ z65S~sI}}e+`H2+1*)#j)oceC3e-FlRukwuw?CjI`D!K#(=Q=cO2!Z-?{kTM<05gE zz+I)2y%@h3w%&?yIFwi1z{xw@`MZl7u=+?VgkaqvauO~#YDm`)tIGFg#w`F#d-m)U zsb=38oUMAXVL)+1KzGQU@6P8A>@1Yd2|KxtokA7)5%IG;aJK|6s(DUqdsRKXy<%KB z%t&!Vp>#MjCP2-h*z`*zKj@9;*AZ?GhQ`XXLgVELxuLP~?9i=;8pEzRl=a8Z)<$Hm zAOE-6{_SBZY!=5-aRh|EircPgC_uUM4;`vozl}S%v#~*ktt=Qf5axBc^HBv{c}WN3 zsWlub=QF-6zW&S1gLjjz9r9&yYEQb~m&N_R3{-*Ybh@g(eVe=PZj#C$(12uhJQ>*L zUY--H!rn5Jbmxl6g-gbVCiAm)%1lnIvUYOg?UUow`^L)2q4Bx3ll?UEe76Q-wJ7o3 zwqi>0T|0|^wX?B!@y_B`b`~$+S^VD4ig6_m>@0a2sP*a(_(U3!23_ z&FKrOWDD1}LpJry8PY*7W*;p73mWPdHPkO@s9y^HCL*-MhO#TBmfYPe8=E9u)aA!E zfXn;$M{moI+*&-n#of~VY!IFkA`c8P$Fe4*B7o9t(~XsI2@MD-DeBh;uorZp%yXEdA3gJH1ITb z+QRp9bv9u*e~!@9bjlX?;K0bW+_Df3GawUtTSDmFgi7pVtg;TS%s4MP`Q9YdC zYm%px6ll8&v=9giJTJ3=tT1+dXYn&Z3d>M(Cuu7zO-qfQMyuzKEC|`uWecyaFfO&g z))gG@BsSZnTt*w-8Ur$NsOV_gB2L3^Gj&o>g`4ux=$+y+UU6g74T6!JsoAP=%O z-~yWbx_r-Xt!d#4cm&WlxPF}tJtSX74|$CR9{F;}NP><&v(S4U<-?|Bt=VV5)&RtX z<7xBkzQG~9-^(>GfxGV__aV4mRgjS&ypKKxg&+?JPBhZFKwk z=74s?4m?E`(6(;isdd`}8=BVzcC7s@&@8Q8w}I!?NBmrv%*ivSSoCmYG~n4&Z3`40 z^9NRTELL{h6BmU5N39Dwp?s>McR}lkuH%eNJJIp|2;WF-#eS%IyC&SN)BE{jL<}3y zCn<4N?l(_c1tI=Wl{*2`*kKF*Qao(q&)9r>p{wU@X#IkXtFeWr$F=n+(N<(@d^l<8 z+voc(bSy!J&T`hla>n`4zI4U6Zv~3hclq^|OOAK!>)5C2>rv?Isd+lzw`gTcJB8>Q zaNgE&9J-n=%b#yN21S*LqOSQ~QN@bR_JVM~WnON2x1t_~qBf>mN)LB*N-uhDQdRAU zEqt07h1r(`Cwc}?hC8_NHtt;;qPXf96v!9^u?Ku7LY?wG(O!P7;P4%S%u;-u(A#&7 z?^<+V$AOK9q_YG}9);VA1M<*~2SP)lT4~V66GCsPx0>1cU1!*`l;ro4^c^SA;?c`Q zxgWRnXf~9*qEk+e^73#faubxg7Rv6z1b*^0_8F4G=z(l9#KElYx6Sna2 ziUZ&k1&y_bRc${Q*Y*Q-UW(n--9ek;9fYL@Y>(PGs(K%>rG;y|1+ffdsXAV_is<;! z%h)2qey#6Fkty}al|SEM!Qq;F#CHU$e%N;qs?Ps0q2fSM=Kd3ygdodR-V7EB@W+JE zXm?;3H^G+g8_m6A1BsxI6Kv}b5_Ok!LK(&n1c9-3+UDK9VaLwxTRsjn??1AC->JYQ zqUj$8)^#2Te0l5$ZlU}i2R_@o?=WTQ*V5`@RPFEIt^LsYo`+ngPMG*@hM3>L`*)>p zr;S;=8ZmyfkweqSsA^ZSyaY%=>JxEY1a{LG79 zDmQ0(?u0qhrp%f(Cv|$xwC;8G-=BJZ%KdL5fqg%EW80J6bdmSJB~W<(TQXKf^w42b zJX5CMF>2C`$?5 z`Wb!)BbGA!PDXr*;lE_WLWZ4>r=jzGwD=qoHOL%lYs=nMYioUpA=;eNXvi0glK*fBQ%UGWO5p$(fK}IzAph4b!ByGMIFD52_^8`8P8W#Nbe3MV#m`h z^mlUuf-ldw z-GY-KLJc?Sy2WCAU%^lUu2>RYe#UL;v#fV3m2H;UeS1FYQR5Al1T|3 z8AetT4iGY?%DRU&?z)FGZf{;f{9iONnz&fMSpTHqv~g5YQ_=(Wuh^;9V%sy09{njO zXlPK=zQlT?)?IJVy6bSQ!xbEZZxHJJJ7v0_vYuLiUakV8x=)Y#zC;{_Npu(Di-38N zTGj*H4Z4hZm#JgEV0JNIGshX)(#tZ`($74{{IvNU^E&fp^DgsV^I`L8bIfdH?92dW zD04kCmYKrLVCFEtVCFNwXQo)5u#{QWS&mwq>;(3AtiY~h>)FrQZS3>R3k=WfL3f~0 zevAd2@wZqAaYjO%p+e0cr{>>gfvarbCs;xTeyk;A#X zo?9G)?=2Qp9~iY8$06gk9~S6Hfr`TPzd=C}$So5r(i-BYKhJn>paos`RnvWCaditc zfh=xgO1@^q=MnK4*~ai~jMxT6`I_jIhLn5bl?%ud!$5|sq5G;L!#zO;4K88=_Xm4% zyEWa-e$d@4u4)Zj)f%{7U85hV0fGATkf$&4dvRjyB$gTwt@jGC=_+Noe$DV-GdRPA zU(g9LwlQ9DA;}aMsl<=9_zV!N&xq=VvR)R9_#hjwaGNyT%enILAqFE*tY9!2xl4361gfRR@u$e#%zX+@1XxnQ1Q-jd}cQCagz$#QY!= z9ffHXGi^*}kxTSxIr7SNo_EP0>ABya!=NFUCRhljiR72wsBt`E3JyfC<&lDqY6Q#p{Kmao0GR>P{@sqn`Rl*`>uJ1@EJq)nm z!vQUKUIS0%;kfu84w%S2PEr#>iSiHPo-~1#e8@c?QimD~LtvALTlb1;nTXFLcLIf~ z>{?aXai{9MNK0EVdViqO-Sc9}E~dDJpaUuD^zkI-fe|f?e3ksvzLZjkTNQ&6XiR98 zP5R!9_gH=}Yl_44CoqH{2|>p||G1UXFGx@;gQ!Gxsu8T1Q8Ag4sS!gy6+%HjgjhwpEoc*q7oLkJoQP0Cc**K7#z?Zs9?EH&6E$bz2a=r z1kTS)hyDK+1_vm*dnobW?xDE4a3U?c2*1!e*iLi10(HHQ3KSQPNuW{-?GU!xCR02E1V@rk%yXQ~B$hWxd=5sUZy{q%=B=y*o zZa%g_8&w0Y!#F4UOca}FC+vMUd%A!P8E8V%L+gIbDj7$?hfyjgLA}ls1MYb#88}rP zRZDG9U4k0J2GZ!(To`6J^%dPtJ=8&!$Cl(MC97sUDd9iMX=cX;|e&$+3HN4vQ)NW?axC^oIH1+fwT)#$tVXP~1-BA0QV@vM; z>iqaAmo4WGecb#Sos}H>blG2iz4Sff4={ar@3iIG1@4`RSq1u!ULEz&@6MXCzHjGB zD$r|`S=CQ(-FDXbo7yWix*Je01wA*hXRoAUv1enkp1T(i`TKjHWq*_Z z?%(9pA?J&$a(5y9^;P$AynFs8=lI{`(3T(5(Ccq3ooPk(jf$+r@-G*#=@fBBc& z-%oDXa^^K*z0&VpDxy#tFcra~W zm5{Zy{o#8ieh}McY4uwJ)5;gz^t!Ci(oy0A7lzdgY+fE4-+FBG$`;SlFVb20E7vUW9lg0EA#2Ua zIn{spbj9X`th+bLp1a;mSg%8!?|I8$UK(V7Y-~`Q^@MxOh1=#dt^@6@r*~)O*DRv5 zdH^Zvk#CnT95H6|%gXqNfBE%;wM&P!T^L_f`^cG7!Hnm7G&OIrS*@Yq6wrVyOmf80 zz6LfDF8^c;KgrT#kdqQ%tM}-*Us>U2O(IUfOI8nSS5$&!w9ZCX-evgIJj z%IKNBh&lQrncGyOtdY9S&Q*=!Y30e5#^RpVmSJ)Tj>eQt{6U~smyHd?UhT#dGs!X^ z4vE^%eE1}jEnZ;vd#i zyPN;G>vhH9;>zjo9ggd*IGqj-Z9U?Liufe^3gFDQE>s zyL}z3_z(q9b9&Z%QQu@B5Uf+xM-p-9r0eBf&en`G%moSF9vbrp62~$PA!>^tV?X4XS*Cvr(=t z5AH>xd%;8o7HbTW90G)1hZU%BtZ)P!Z#&*{lsn#ZlsaB;6gr-BEOq!COB{fAPQl_mO>- zeWktD{*L`G_P6cj_EP(c_9ga(_Q&jx*yq}R`CstwA-mW9p#A6e2kiIS@3P-%zr#Mu zKHZ*cpK70CpJ<<8A7{VKKGuGV{bu_J`!IW&J=NaV?zH!|+wC?xYiI1qc8&d_?Sk#B z?TqcD?S$=^?SQSrw%_)xZLh7}_Kj`3ZJTY2ZL_V(7PW1(ZLoc2i`YK4t+uVQePFA# z)!0N^l})f!*xs?dWqZ?BW_#84vTccNv8}-NtnH7sKiGb6`4+f3U;+XP#d?H1c;+x52VY}eR0+dx}?TVI>OrnPBom#i19XRN2Kvh|p? z%ZhgjS`S#iweGdHTferpSa({tTen#y>lfC~tsAWCtZS_iYrXZa);jA)*45UP)*5T2 zwZi(Qb(!@g>xkHOG>vPtn*2UIE)`iwTTYqnT+&a(tu=PG`o^^_KvUQSmob?v# zjn*5iqpjClGpyHHM_ET&M_7kjQ>}xnHmlj1WWB(iXHT%l*ba6-+s^J_x3Z1wTJ{rm z6~i)sb{Sj3zQ7i-&$CO}#q1(>AzQ#c!~ThVnth7>J^Li$q>r=n*~i#N z*+@V2|*?ZYJ>@3#9PGQHfH?yPJ;p{LrolRi}u>;wDtc$g<3~OeS z*(BD)8reiPfz`4aR2fr ziCETHYAsckcPwvOmRVl0yli>NQfeu&@RlOW^Oi!(bC#tRpXJY%XDolPJZ)KEdCc;t z)6E-!jKC+j5WPZp&SkJ1uuuW?62x%(P6mcq~&bS(aNYnU)(Z zBP}BkM^3d2u?)1hEKZBVl4LPj3>J-rvcwpLxy)Q*&NJtjv&{OWty0E%%_M?f5d#qtYm7L_n8{zJ*J8gm`cR0-(t#`SD2TXBF4u& z!~BW)Bl9HlJLWgcqs$}BJm#0ogUrvF`vZDXtq%UGCXCW$dJ21d^$Fk0pUV&JFD$IM-bh95E?G=FQ} zZEiDvZEi6)o41%hH-BcXH-BROtNCN|N^_N2Fjt!2HLpMnJ!t-m`E@gIE;RehOU#SS ze>Oj3e$xDF^8)h|=3ki~GJDMrn(sH?XTH-s-Rw3`HBU6(X1>+@GxI2Ox;fQ+jhQnK zGWRz-&8*pCX3R#j!JJ^$nlB|^Og@u*`akjC;-vXW4yae%SEv7fQG(Q0Ik79(R! zG8&AD#sni}Ja0H-IBk#(U52BEBZk9JQ&yl<#B z2!=|-yM`5pzZhOOylQySP-uA8@RZ@VhQ|!QGCXLw*KmiyW0+zXXSl^M+K^$m&M?A| zZb&l>HKZ5@83q~#82TG}8CXM-L1&;1m-H9)=k&+*hxB{(U+H)0x9h*quh-Y>SL@%` zSL*+we_Q{mewn^R&+CiyKK&AG&-_XMNBvX!U+W*y&((YNbM$xWr|aGN3HmJkSpALq z>-1^*YxI5fc0Hrl>nZ)^#50M<5<3(3CblQGCT_zP&u5ACi617eOq@->-FJ51+CH!K zDeUujpEq1fT=% z$4#O%s_)%%pV)mLhv!syEAnQVZcg+h_;tV5P1Mb%GiiqYPWy%SjOHs%6cJ~g=C3N2 z?|*vsg}=}FDfQ2kz^%898=o~{;-tw_vZuQ7teEGYNz6}e|5GHOp>_=Tk2c&ho_p*< z&;5VZ^{4Y6|Nfr)!TAsJ{(4P*`XF9(R_4}?aq?j&-WcH=5qA1%&m>I-jfX|>A3$(Z zaIAxz%s?zZ?34^4olhG|@X-s*oGn2xj6_~8*QJTWh+$`Lcx2lT_b(S1+ z;!H3#vc}0Db@E4?Q5_D-CrAdocMbPPoj@XXkpl4;xfKUE-C}=y!%mZQlep3uy(IUF zUdI2AvBrsuK6**Io?E8%Bx&*ceV!3_q2vvH{T-fd8oU|6Oo}eaJ5gl^0{I_0r`I|8 zPo34Gv+i*1YE&QSGd*c6!+%kWc*B%gnxU0pvk?mLkZEBogy|_|wPnlC}pr z-F0Bli_qsC`5m~@8krH z$E88R`%d*bvdUSB9g6yu&hmOEo|DIRnHgI+#tPFa)3Q{&2#XZ1ah9+AL7{7vYZ>1D z*i-n!nxwF&X1%j~%@1m(u1Z~o7lEAjezLN6@dy7#&$a}qlEcoD_njs6P7rPyby)p+ zgW9F3%TlpdtX|P^O#-znRk+O8JH3L&{Js-hAt6C)&}G=TSMz&r6>^L2udZ{-+CV{Z zwXG?5x$vn#ST!op|J3Cx6VJcQ!6DLJ5_G@2*f*O9t3O{HXoVZAXtAfV%VTUQu267UIlPQj3FAxEDRhWdv3 zcMAze&pR^=aw7h-6M!B00E)gbRmd7LRMt-c1X0N}9N_NdOY?f()#9}vI{vh?5x-}g zF7b?${p||iO}9voZZyi@2%7n)ohTQm`DdJf@PF&_&k|2N4^qekG_Gfyp`m!|F3p|R zRiwIBr4Cz0x(F}u)mEh5gv3R>^Rgm!mFss9FOEd{69Jf+I+U=|VesRv5-xw@3Il1f zB9*}S%>vbgM`*4<`QJuE8Ah}!>l!%!!q8Aes@~OxQo%F7*12UZsN)-)e8kC3G62+k z+9_$g@u7~_G8}Q%uk6i#;1mx#d7046pLJ&7_0~0qo$^@mQ>T>Ju8~JdBk_WpbZHn~ zQTxBx`xE%4s=VHBE2RG&co=h#1PHV#EzmDC&f&R&0{3e#O_CY7XyoaOC?F!G^q*o_)b3!PP-39UFVH zEMb1IVp%~r!Hm_N&uMqA*6v)R-TAymwq987EB#DUZ(Jm%`)94Pgi6?CZIvaJE4L76 zp7WemvC6W4z8_(bnf}FoSw=5tue_jzw^^6?7Yg$Cxn;h;NttQiyfyX3lcBau@ObvdN$N zYO%j*;NoJnIy9Isp?xW@7eDfC$3ssnO0$mt=tmgvNA^#$F8rZy@r>d<$~?>BHYpFy zqRmP^KF%arZ{#l)J=FkLldH*O~fu2}dGnPtlgnBmMq*=XFLG@b$ct z_Rp>j_6?@KnO8`V_GP9b8u&{4{+YpL)8+?zETS{Ld96&rJXYv^8NSnw_or5AO*uwE z^r&|pOb4{mOU4beB|&QN!E{$5n_H@2Q;-c5Khd@*P3G_-CHx2tW^w1x1*sDjnfC7v zHhsT!rhWfr4si;Ky}{JM>A_{#}xk zR@1e->A+H&w*Sffwf@~o}~7f{$(cahzyf9R3Yn5AYFHCd+3qqC#fUm@H5IXJCz3Y zXQ?l+4;@_W-{@Rv=7ukEayMkJllop(#u@g7Ol-_^Epf{Gm@ep9GJ)*t5~PQy4bC=h zsD~%ZN}F*fd72nEc0p>>Vt;B4x0UK9Yx!F0+5wp+8KZfr+KDRc;3GMw2$C3jOwRR6 z*+|qsNGIP3?pH`?;MdN;N*0yQ2nM3`sEh6MgTx}AWB=fr!U$&%IebW2wx+)IFSfJ& z!xGZigPUpR>0>-^jOb-mH=?IfEu{X=urJQtSUgYm6S7h{=}K0*q=u?0HU1z4;XeZ< z&#PU0Me^^jbAnpUc?pU_hp z&4Ma@s036pEi-JUjUq2+ZArJ(uGPj1BNqpkhHhPGBJ)o*YE9-qxs$VD z*7ER8Th6obIj7v&^fz+8rp2_M9g)@L+Pt1dd2#mRxBcw%)D_DK6XTZll&+Rb{Cl0; zO<9ea4%Yh*I*mdxe0uT8?MWvuo1T^-T$o3$(N*y^OnG{>HkYg;ESA2#p9UUsveBYH zT^D$)s|Q!C)tnR8Y7-l@iH#cd?;)q`s-E{PT^5i7p83HU_Ec9AO6kt9%O|3&nxrnc zGKV6c@6Yz8vhC+kH5M0d>^u)=q*)IBQeQ6#&T~^SWX+xDGe#1|&?9ZN*nTnQv(!gq zO=kyfx-qKFVtWy$3W-TSbn{9^L|xXWageX<;-R^_WqfU4UW*z)Wyq`)JO`P<596X zFV&aJN%*lWYe2?zjkdjB3w24IyyAIn`!m|S4)pRbXxpFF<`t#d(%|a-yPfl#DRr;2 z$xg@nk7d(R*1i6w<;!~YwUb=#WyP|Eyd?#0c6DiJ8Xw}Bx=b{&Pu?>5IAE+h*rACyo)@yT~(dIm>1HK34or>tbyx z=%R2y0q-NZs)cTn0h=7(pH(2+b*Md!VzFhyv(nRIX8ad5PauG2wAm8~s$Qd(Q#(T4 z7nx@UUtF!pPUf4XDkl>h>csa`V+fML*;=9Nd;Z@2qvm7@O z)age&+5FTU*=E)eh^$`gw2|J#nW1s9`w9VW~_4T^ZracGVIS9wHXe^gbmaSE^FnO?HMJVledSzA%VPZS<63R= z*7^3-fo09a61v%l!o+LEVtdN6*wIwYMhI)QS-3Q|D9p5)%}eYl>juX>mPap`;gAoH zQ~cwCPd*WxDTk7>(=2K#K*e)}Ux$gO;O3M?wlf|e?=CQUebzYJnk@2VL8jkAW#zFv z!$AxUrj&gla)Je@Us~>?5l-3f;BX@VuGwIE(VIrOTt6F&1W@?Kgb`DL5axO?)z>B4-2 zg((W_9!t}4slXmfN_*jX-!>j4`Me6|%AU!(xbv22vg4+0^M0{x+N>m%fFH&bOOWfv zP0CRpOe&=Hn+l`#8tShqm`ov7^*G|lWp0B<(e%!nrw57JN8$2X)~KaQd0+7CF|Tw} zuskT!rcJ)t&ZYhpjoP+i# z`I7}7TNYZ93R56koSd*1nx~8(K@b&3zl(mZrMxQ+@UU6&rIwNfb3o$`d?{ZonHD+x z)shER`qeVv^YvJPPdA>JK*0Z;@3fU3UMDA{4ZhJP7-k`@$Fg=z2GDJNr>V|m?Ql&T z-|?FNt@hd1^0j`&ciLy)$oF~_q~crVmPo+2+Ctd^c@Iu1Pi{u>6^c1OXrYcN3wLtZ zLK8mb9@JzrFQJHxH|RF0Hq>xm_H~)Z+u^Uv>6hUZ=@;N1G}Rh7&k_EzFtF1RC{Y6K z+<{yr{azgSt9zkox^vd_+{MABq2F+Gy4dD?FKa`WTPbVOu_3sb&TO9SrPyNs6#_G_ z_?~XsibThLMsy5br3gGygw)FmMd2VWUVKA_FJ~3r zkS}SATra*$;7lpJi}p)qGbu7khw@5?HSg23pX~fuI!*6t(wjU#g}~E3GSNL8E>Y6C zINV1%7t)8EkoylZnVGMXsgsj=={XNsF=YbrEEr(SWz3NsW6TPbHK;3l%9D2+>?{2* zT`C72i^S5^V>D(cHgidRJ=0$?@Yba-jY(V0N?XYb?>8SX2rOP?O1;e>Np&rIkp4U{ zqw@@hY%4Q@GdeHpFvIbLzriw(K^SjEi|jnGOj`pt`(~w@7(*?xqhwT-zOK<0nb0o| z%FR&bqd}y-xQB)Ls=819}8X*x;wq)S&$Et7cQf!_D$n zG>9LjH4Aj|_g0&@Rft<}Wm_zE;$m|y_Q*0Tw(qQEjvbDhTsOJaI-ggbSAL({mhb;h z=B4spQclZj7E4WYOgEZlnqF0I^o(?mMWR56M$^5fKbW?d#588!A=DUJFQ)aHwyt58 zm^E$IG!r~0rkSmdJhf13vrt&pZfQIB^vz=7Da)?-;FRygv;%>C_1%8cOXwd>Pj+1& z5$fVy`#T@#Bzir2!J1AB?wcmQRpuZ6(hC7ma`oSj3k@7Hq(oY4pX~quL|d!`egI1KND; zPVF}BS6V`wrd_X1)~?nnv@5jH+U43Ptz5fU8>S7_hG_k@e%b|EFYR3I9PMnar*@Xs zLpxJDLpxqOPHU&-X)evF_^$EAedBy%d=3z_9ulFAB-AJp=^WNp1>z(7h6S=k7 z-rEhiwJPsb-ne(1H|D+4I~J+6f!-e8GreaZpJw%bS-7w8y~1}2-zeNv_}juI$dWx$ zczfYYq`F2GURKz#uq{$s#f5%Da;pHjt$ZZ6@{rwf6j}@a?)l8~mgmo&*F8It(s~&Q ztrtBnAfLq}%kz|Hc}6~Kq32N~v>x^>@Z9Z5dggiV^4#H>jeOQ6o)O4nb@H6xIS%Qo zwjQ6y;jw!DQSdipuAVAbUN9Y*sc8j03cgVfs-LPKse9FTk$rl|kZZbCtwXM9ygCZW zrIG3->In5BwZGaMd8Omjc1SEO%U_DT(W3mv@)zbmnvpiTGk<#iZTY{-zcGI*>qjRd zWmK6z4(XziNEHpvKR3T8l0;|Z=OZ^{&;Q>2T}Ddi???yjb${S~m({9ox!-iZ?%wU* z<-W*0#C@TAfct#pdrn5W$M3edP3|A^zDHu`OC)wa%iEv#5vy6(<-LTI&Qp2I4GEpB zbk0M0_vOvYyDM)lQaX3$-I4dJyz7zBsmZI(yE-qHcV$LKXLQ~rdFSVq8PYjt<@Lxr zB`=hBa$ad(*SwOv&Uu~k+UFgIoQ^NAFs}ePoxD6(UT&TfNuBRq2V9@I_PYM+df)Yq z>(8!TuI;XEu0Of9y0*ABxz@X0bp65gd)F%0O4sjPPq~)69z&k@e%D;rZLWmtMpvDy z+;y_6o9hHuJ6Bs*8<*lbn0p}iliV%2&*awUuF8ENcW&;S+}XLe=ho&<${m|KCimjp zNN)e!e#r2go!cY#%-qv*Ps%OL?V79ScFsLMH;}94dXemL<=S#Bxj#C;a5Agt-0s}u z+~|DLxy-r9dB5{M=X7Va^J?dC=P>8_&R)*5oIRXpI?r&P?mW$TlC#ulb>=vQv)QrV zvCr|I<6Xzwjz2rLJGMABJ2pCAay;jF!tto%9>=d73CA?Yt&Uq9H#_Pa*E^;-CON7d zS353qT;jOcG0bt1BjOn9kkUni90QRs>hCxo`J%HNXJn*{PH}_`38Su#pd;WYM!G21 z;dD5VEBe}g!2XeaA96%{?H}0xYX1xJMDN<)vA=D9%l@YQ4P=Y9B3HD@-e6y4f7(9R zKGPnxUu2Ki``9nApN;fT5Bur%)9j}rMbypS)vnuv_7m-$>;Xf9sMzkeYj&R@M`W{G z?Ky@tkz)VR_Jgg-_7B^~w*9t`Z2N2<+Wu<$i|sw+ie9sAw!Lh7-nPcJ%C^$B(Ds0B zf$e@nx=6|uO+%_^3Q|QAY?ZdlY$02ztqYPwC)zq8P2{uX+g!Fgt^fMJ+1B*G4%QD0 z@ttja#h0=~|H}Q(%Ku3D9xIQS?00-A|09t2X7p@9D(5q9}Bhb0gPKH_$+1sp}suj$7bQZ3-h$#y028A{0 zET&itlgTj!ACn_FBC@+V6c^>@kqUu!uTWeQMYKRIS45S?&`#!x!6>Cb6-pdxRgst? zL~<%j6C!b2OTtvfUOQfXW#b!Bdt61eY0HkCQ9JH``TMVzfUz-n^uO-^7oY#POW-Ys zZ2vyhB2vZa_Mh6;xO1==nPU<)v~u05jIA}t&Ee-{`;MC{dWWsF`SKiedTCi3Om#&W z8#l|}-eH>vNz2G2p_i1=`fWmwWv=nGV~gRK-$Raj3q6=|RGGO}m6aSGGSM9J*|8;_ zOnf1|d)z!(SK?-RDRVl_qnm4#NdIP;9Ha9o6%Ew$xF{7VuAR!2k*XqU?Qt=7qSNqU z5jAd6>xw($mQLYk>~W{e;8aW8DYK@VdWA=dxTQi@dWF40$C-@J>6)yYYF&{go3yeR zR_?>Cb{kf0dWDMxsciA3#4UKOaYyP6d$r6b(lM#VWr`8(S7zPQV&Q3J@vd19l(o{Sr2t9Bp*RrgRH&d>clK+Z{*6^81+*+Yq%i3k!r&DFk zlFCf#|2wX>D=>n2?}!kW9*;`>>XZaKm_eZ!~dGVlc^z0DEU zZCd%h!KAl4!n$26>vEIsJ;K`C%KB`R?mNQT*UGw`N%tRN?QdoMqo9-zFSTB+tltyd znZvDnx3XR<^Z`d$4`^k*Q0V=RuaaR3OjHe^{F(bjdWOLrwCD-9jPkCg^hS%V%z zpDYcgW(_(EeTp=w%NqEEKB9~k63rT} z=ynFpr)F+dSkEZrJ!{u1+?MAdMVG!cvUX6tyg+qoY186Ls3=$Y^{fo;1UZXu@Ryp%0OF{^uVcCD@joAoTFDon&fWqtI*0 zPBa3I$zCg6Px+g$%QuS|`1iGJb1BJNU+5rY`pD||Y-a2G-Ja?E6@Vz42VQ{v7# zl)M;CiCb!&ahIEnz2405#2s;oxIH`iz%$Qlqot?)$pEAlZ!&;Pu+m>Tj8}QyGk&pT z1BmqdI_54{gWsw+FBO4NijViH58zu>BtI3!$pfNIVzWgghFL|TlT9Rgz`d{x{s5|7 zB-+?T@>0if$rwBciyg-$UUP`#E=PN@W#{gf`>MtAx-F`<5u0{w-1uthFWYuT)#Jpg zsa;#PZ+UCuUv_T1NNxXrdsO`Illl>tjQsb>>@PVzsstW0%lE(Cs$ZN^n3?}Mk%i7@ z7DNl?7CgX||8Lags<2G6h@5FT!aB_=n9MA(EVY#6EX^sgF141hkTSxj-AGOnfKek^#8@qKt%pOncT(@2YAya|T$ zc{edsZsxU`nnk%~q}?LQ?Yu7v-Va;-R*D80Ug=1AV35GiC<2L#%79R&b`qtReIHjU zJ2Lrd*crjZ*@XMLZEFBB~;Fp^Yya*I)EuNGxo@b*p1y4|;_b|scGS{q|YlyMN z7FTL`Qq(&1+e)mYzC8Em?0%KCGl@!v&~r*e^s9nUj1tq^;mOFe?l%gIAH7(rWJ#vW z?N}MsP1122=~xz=;X{|+GG=j$;x^3VRzsni(NP**J*{p;@HSPtVOF6JcMZQ064KWb z;t7hTB&|uOl6=bvOa^IsA-C1a?XMNVnbN<^RYCA}HTqUTNa$YtS!5tWPG|NA2p0tx zQ`(Q!$+!@~;jJ{0cbh{P$YM2D660ns?+ho4;BK|9Kn=d5))lJ3FVwmsHJDdWr>Vih zg1TZgSX@xoRt zgd*T8bD|j90-q8R9pHGTVLuk;{*$&Sb>oOw2ZkX%V($9x~xj}=SuQ_Mbx1JDdEvq<{P1&Ly=CverxB5@Mx?q*ZsT-3eb0_X<=Aq+!d z7+ee^;W8KvV;}~TU4$Oml;65hQ)BPzO!1l)Vo452)O(L~> z*9FWvaoIM6DR-{JnR#2^xGk(Y#m+Z(8me5eedG3>8>6aRAO1i6_d|{{E?-0nZDL|k zrvDfJ!@Ye0+XIVP1rKz5^3>=1Y`gf~_}{N@76lzo?Q?Pb`dJS=`TVwb|K2?F!}@hI zto1u)*kq5tbd_~Ra5F!h>l;TjED3SExCoUj`H+J}D{#3UmpgIUIOC(kUH@^NeQJHf zpan}pxL@+&SL^<`Zo^0OK5P19NEdyhWWefQ@2D`7S7mLzjF|~A6rBACl~Jvh+a!R+-FTG`)ptBs^1lQ zclVBYZ0@lWsbRFRd9~dAR9@x z!mp>o@1(-7qr%_lA8!xUQsEn^@Dpe3liI81zqWWE)!n_=I^Nb&+xs3?+t(pPYwYuiqiVkXrH{df7lLXNH>kDyr{LY3oFr3c|}9$(9kk8%J^QP zo4mE6G};gsN(G-#b(7y1|DnqFPGuOYjMQ?N8?yFeh{WvjfwVyvb9Ps1T(Mk!^J30e?tt(D5zl9CgBe(bnFedE5_2JYWU6xI zMW(7C<~%%AaZ7hn;f{WHbgFRcro;}Vs=!rSK&oU=GF6msOR6Y5f+*KUc2a`Z5ft}C zsR+)xYdG(dO!)J?b$LF2Wy~l-tDdVoWZv2#S zu|Ry%lt66Kbz`f?om4$(%D8L0<;g*-N`(=;e)J17BK(Spqfx<^3hJIw`YWJWAr$D1!v`m#QAVxj!2HlDM(atos?rrK9XZe{1NkKVGXvnJI zXTL^8mD=`d)IMLTHgDT9#J*OlUYDxxq-x!^s6AAGV%L^!eeE4QX%z=u53@fjHJi3< z3)?@Ds_n0C=xdJ@?s{XFp_){P+0M_5!O z(q&>ZXJIrItg>zitW?HVbh#C6>T`KQMul#p6U;np)j@K?z*Me8&X&^*2sEKJqb-%% zkfF7q<-0Z?UJY$NTAp3ZMGWE#yxsw!CLYRm<{qM=phl^BKy_D}MbF8?UG=aUGb1L| z+&g>)!V`QONE^g0UOsp5NWv&`j%YFUrB#z-X5H4N>V8#`4`9XvLkgKM(zDujc={OW zDr-5yqFT{SJv#~{x+ z1ckUKBS;r{yE#PB9dh5{F!w{!j?-m2Ir3iGu`r_dO`W4w-KDze(|f8^!iUtjXg@Yu zQyBUCA!nn%_Wr!HC$i40X2x$8#6=MHGbZoKts_U6V#CAtk(DZ^7*Rc3zg5qx@`(|l z*zgjwKD5e>p~9!I5+%Aq%@l=A>S_x48Sfz}B&_`ueq59$7sgNAcD)+~98&@ql)jTg ztz6k08(!ri;Iv7Y0T)2vlXg`)@zsz)?t47iDN)&F_WSP~NQl-kkN3=?Q zWJ5E>U?jS{{IEg2!yIgD+=5!BWBF7$AZ!<+#u{*Kqjgj z8I{$DDkqlH5><|j${x$fM3rMiWtYQUqRJuO$fHO}L^AR8KUO@}it2wJW+uRAsDMsc zG3Wq2qVjRIYPmWY{pjyyZ5)-h8B!w1Mdd=Z{n*M!Ri$pZbX76+akcV^tb5%eD|yB} z6|QowI>aS1_GAmaK25g0Y!q`<*VMV{sOSy8s%2{BV`_ADQS=_4)c1EPOn=Qwk0laZq2U`KfOr z8}~a#+(bE7)-nBU!k8{oFwfBb1?_cG`zu5H4qAG8(q{yCrSV3`xS<*IA=12IfUNh^ z`gIDQCo0p{CmZI5_Y}^KliGI;?RKiaUB%#e_?` z=6>NGLiUWp)!w+Y$2cw+$KWO1CG)7scJDG*CfQC$HEDPI(_e{KmbUGIDGR!mcf9`KDKRNTnqbqb#^(}xQqfkx1+ zgCzR&Q;0Z^N+v;36-el)kr&BEBjfECUMNa3LGld!TS2TP{IL~EbwpP38*vd6ihN`k z5sy8js-RqAk(xsRboB6zsZ|oPUSz4HvzZMgeMO?>utI4mgqFmXUzAR*E84Y9_(|EM z!nG~&Rn$Z?e&5QWIQd2T2FcvxNp!StK7qk70OtXBl}#MnD4%uak;Qwp*S>)1uQ937v6j-dxGW6A)A>L?g1`_pN2r4x53ZIO1;L8jl9$w_CSqE^=F zh$<~(N+0?JBNz&A7^5=O%H(uT^v;8rQf!?EGWHmWe2iY2;9B?k>4p-imV;YvQlE6- zvU`YA$dq}e;EW5E_)scYAyT8r2oIGNPvQt)#D&iNZA0eb!wBFgCsm8p5popGJs;Bh zr^3A2m_e={-9L;phfzb^n_Fn@JEo}y+Jt>tIEpnnspCOf9v`8D1 zzCbE#+C=hA`h8NlwN1og(r1>PBzrU2Q)T)W2B1GTn3buc@4l;ymzm$HwCs><@9X3< ztD`ZYR@mbTnh+2xqcw4US(J>tnd7?icIZBg(t(g%#EPd1l1=Gm@_!5WjG8{6g6y z_Lp_06LPS-CEUm|#7t@~peO`pgNIz! z9P4eo5X1)(NC-&1AwN>V6O{2dcV8}~;022&LV@6dUtB&R7 zoJX8S6QN=Z=|vICRF2|@>1Mu(M@JQPYa0olKYZ}{fxfZvHIt^421bmVa_#s@69cDo z3mNm&+~VG*VAyy`UW3nxrsyI$^Prz!#=M0odaBn*iL5@6{X!px%ysnrRn)+qSHRKgntsStayKsQGbI1-)Qv_piyYGmh>Q`UPc7tC*rU z1wxTqn4e*Q7dKTYR4chKWq@2bK?p9{$A&D7oUFtnhfUGXiW!RO7vYhN3iLlqzH{hD$CqxvaP%A=tu3D{O^dw62mb?AR{sa{stY93mFgG5@i@418U$2 zcn!XR4ql<03a`PaBB4~mYTyM*xd+z60kCL7=>k*XDQJWrpujJb0dP66yPonic#DPd zI(!CQ+Yl#gg|=;lvIVBK6Utg3(aKFoTwQ-W@+=vqfe|nU=EK9tl01d|bEq3oZ&BQdZCqbf)Wi<1yOlPHx3T*x z>iw8~!u1QxzQIh&oG8e9*pV^GHMX=xR>i=xL<eBU zw7i4{9iW5{H)S~;l7n-U1h<1C@ z;@yekxE>FkpcF!I2Al=wz!f`;&54uIp9Q_3ALc`xp2S6{qi`8q0b`*OCc$+u6>fxE z;5L{Ex5FHm2lHV8VLd`vkD-1No`zNMEUbYSVFSDje}Y%wO?U_1hrO^LJ|UdX3FiRn zui-oR5tLk!uz~~f!2^Ei03D$ePKMLqEI0>-!No8NuE-V1c&;Zg0rh0K4(i}$mRUlpb{p+6sUz8;3n7ze}dNt z`)yZ2Vh`#MU_X2Ue}}K(JIK!?P0$fa;N(1!JT=dgI2-kO&>Q-~V7LgPa0!fpu@Hyx zPz{q{3QUCr%z#;NC)@?g;g9eVY=l1%*Q>;}8}*y;4(x#s;Zyhmz6ZrE5;kx_KKP+6 z1Rw}HoDALJbm#$R!}%~2M!^`UglpU)d7aynxEb{{xD93jM`R`*hK2ArEP>_lG^_%S z!Axv|EwBxC0Y_mb-h%gGKYR)Ypc$O`^m7n^u5bpN4}3mJTmoZZ0!)Ql;a6}6%!MS} z2M@x-uoRZV?_dqAhb^!jUV~lm7x)`|24CchTicL=b&H z%m*SrI~4UWk0p7D$Cem{`U+1`g7H(L8m7R_a2xy@X2V@@H_V3xun-=HWv~X;!aCRp zo8c9Bn{Yq&bV#@gX#>y(&V+NJ7Yv5sg(5k!P)S}^Xii>H7)VYkv?Qwmhb9YslY{m)ryo%%3`8s>52;X@p!_<6xOY!mh@ z$3Hp>1+%qGK1?<~VzWgAN?x6rv#2%eFB@|KS4wPpKI%%G`1lOUDi^~^T&cyP#*uL< zLvYFj6O}!aoEo#JwTN1){+bbCC~nEDxv69E4(<*QOc2)QY_u^4p%IQbovl(~ugzg; z4G!cK73qrE2rF07E$P%4%Wi7zqQ==O3>!;t9Bev}4nx%BkQPy6Zxu*Rxq~#ztVuC} zbOF_v^=(Eh=|Yj84mo7bCcW%uxCnMLmi=67Ec>~~SoZT5RW9ODj0HdU$OS*a-xt(%P=g;A z)E%z|PxI8Bpa$o8>P}RHzw^{}R)ep5>bj`GW=~yLHFBC<8pL9v5k{yDMtIj4Ar*O~ z@9~E3);^d)W&Y+Y=5Fc$*%akN$YcKIBzOom!sl=f^Eiw%lxJZN(1ew4xE%r4!adLc ze*p#eavta!xCed@A43uTP6IhFG!K3UuR}9qlL7=q|H=BH1dH1eCqifF0$mX-9V~Ja zh!iBNxK7|Yo9i6x9zeYU^-8X*g(vX>*Ei6=&Gmbco9txDO>|~Xr!Ut5Tr0U=&2=`{ zIn4Lmk9s-kr@6kwwUO%{t{-6c8ETi3o5*MW<|M8m=5BhR9*cS$*W0tYDv zaMwE0LA8-V^_6QpVumcNM{e>%R%+G}mrsSVwU+xrQ ze&QDHZ{i`@sc>(fz&#(hUsWF{}kgE^(o0^zeZW2 z0TIiUt7{xAmm&Ewd)Sra#iWF6WLI-67ZEw`XRaQ?e6k@PsWWsdu`$0pLds1dws>X^ zqJ~!11jX%qJDli|Az9gDES6X6P5a0#@x?`nM}CzxWG!Pp+~_CahW)-2*W{8mq-S8S zF#Ev_WEl(+llnxiX0CCr7On_0PL3<(XBtlV=!nxH8K+}1PNn`Rr=ebaQj4{bOP|=% zsg0|q4OwXuYokn#{H;0GMy>T@=~rsqu{I1Z{h}Y4P>_N;Uc_8+cORU(sK>Ib@-cBs zH?CTL9b9?^+;=lJCJMCQni*?UK2W58dHB zxIk$qCxp@im_yS)vhz~g2_}YqFZT&8Qa8S_>-Tb14`KfD_cJAML*0!x-F(Zf(-J>p z_lwd0`z6rcE}#GV)&68Pz5Yiwp-m~;jCfPqul}UE3py3_L^9`3+79h%&kvqCh3(nh z{$WqI!nK7%y(#Y+&xPz%e>FSezwN0m{IT#3@7LZ33tlLQvrl}fC)YE?<1PvoomVun z=$fM0MGqIPELvX_^qu8J<|2=882k56Wk>%!$ z8YpelwzaDk)1sd>)qd8rxV353KDBC(TJ=}8YOl(w%{qSns@CmM#i+Dd+WrWepYwBz z5sL2QVSa4CGPJ$)?}j6pcq87U<7nkhPRL1Tds-5f@s~9)9Q@N1u_A~4Zj2%3Qq~DTiWf<-1ja@O{Y1zmg!+F%u-~^)XAx zbSSo;PY}KjIr+~gNOvD2J-RHmV(MI;eL(KT~9qrJ2w2|j%BUy^wvpLNK)~2;H*?44A(EXUUx{aAW z)kq<0x8&PFYww2}wU;3tZX|;{!brBlBaEy^85z~>@StQKj_~I^+DKO6BV5^!HgX+p zbePAM;*fnP#eqnw@iLVu4x@zWUonmrd#F;a%Eh=L$FMW*-%)lgkp+k;ljm|J_=Fm5 z?;RC<+PEOLDQZoIG;O+8vzW!)gH8K`uNOQ!6kVyx3h_n)Z7BJ58G8)AFPkg2`V6A;x^{)F8QxSGk}A7BoX%k2>iTn-PT?}mOY3`L&;K5#1+ zqJIajM!ygExUE#9{}Jv$|1~^F*e?KEJ}A?m6gPZ?SB8KaVZ$Jt2P5Gcm<~p; z1Q5@HH&K5I&EP>l493A!xC0)6Rj>hGhmYY0$R|%7;dB@PW8h|Z0P5j=(p1dkcN-?G z+X1^>CIZkAIzbRhK!;N31|eWux5R0{nwvxq=n3aQ8T5kQ&AW(a0^U>U%_;k z3A11}+zE4G9^4K0!hNs+9)#b(Bd`z_F-iZaXqP+)-$FB3P3@9S@IYJW03~n=oDOBs zA1;I_Tn=MQ?GjfpVP6FkU@}|_wQvL61PPc9zXmoVGbaD%alHrbgNNV|cnqF^-@=oy z0#?Ew_!#h<$&+{ybpx!2O~AokiESV^GedYZu^ZmN?Yp@B5cPie1pW@6!vXjjzJnhD zaoS`K!lW)f67ZoR;ejGx6SPDCPJkes1o8vKsc;6I1yV5eJm?L531^VvNnWh9OI(h6 zEHAxr)RVBA0@uM*xDjrF1Wd=>uW@r1*L!il03Jinhm7RYsDF?88PqRv-NbbVX0O9v z(0`2nOVnSZ=H!=z8LZ#{HdRaHg9nQE;Nds7O9Z%{Xl}>H4_?aApM(B9)EA)ck9sKA zOSoQ%*;OzZeI5GgsAr*064t$NKRgHz!$No*mf&s~ZuoGKdDAyFj?9qauHT7vb0MUqwa`+>WNSSU7;JC0;j>5xa*0V^SSoJ{U8{QeiZsE zP+y7qD%6v>^2Ip$E6irXUFa8}Uxa!I>faI8@1Y)^gXiH00ovp?OZ&tw{QL#s*}r1{ zDe5mV`<|;40onYVc8MZ{V*Lokw#}i9pg#e1XRh5aKLzz^nD;<`4(eW9`(r)`^bv|Yfz$54vqhE^pDOiR6 zIrPt?UJD!0OX1yDFnbOCZg>kbc5g}UMZF(BLw^AM*Qmb-VQrVNA>8YJ{vfPOOS8n^-dH1xNj{x#f*{vP!A zp?(k^MZX07GSn;J_vlxne*tv^Y()Pj^sk`a0e?pS9{TrDe+Yj=kHB#90P1hxNAwmO z!jd*7r9ic{OK9lZpl%N*phrMBc@pYV;0*NVqVI*e4}{SVM?VtvC>V=ABN&{Vg!)>9 zb(wij-hkaL=x3luFgSS!>bp?ije0(I52Akz{S)Yai+VZgr%|uMZZ)ifO_*=P{8iWq zuVcRl^A9nX!ofd)mHnRc?X(wrs|mHkr_qp{%1omnI`zxn|5GI}!8reEf@)+cyLHOU z57*4x_r$){!j!abPJOe_wy2?ApxmGOX7-W~=Qqqx$?aCsyC62su>bM3&C?x=8rYJ> zK3_;jn;c8_J@~}FRrUvj3IA;4W}V-#*oHSM()x|5s6AKRwRs1dD4mgx`2VRQ{XdnN zQ*CnoZ)ss3sZP)TW%mAgp=fELrnS{h(7I-RHU5N{X`OCcXy@SOuN4k%u6(j`=^T4Q z$$|m12P{+;eT~|vA@`;#E32ED>r(^j8wSk$FwoSTF|J4()xS2NzHz|*W7^d37*M}% z!2W;cpnm6o`t>+F+}$4=>Qgg6v`?MmXehl+{vWVlKtSw~>1;_w$#>*oBR)bE({qf&pk|6>NQ;zt7d;pl+Y&-qTN-#O=drT&;f{?jm5 zd{5Zl9UZn&=Kt9OzHP?LUo+JIuG8}tj!&>svj$WmezAr zK(wA6|4psu@UUloxJWEKb+zz4(A+%x0pXjae!1jBX&^9|rGCA&0!?$XVe@rHDKKYm zQQ4%8L^aA@;x*YzG|(ss-vOt&ge}mo^b(P#Ef&u?Tm9*os;an zIc3>*?!F6N`AJDNZB2b9%W%nu6-@bvs;=sYP`CWy=MU){=sWewag%FUfO{@e0<0Xi z8!{8!l;h=M+^Q}(#L%LQWk%G-m*26aCX+n7jSuc@KcqV?6XhW#s1%Fbnp5s+BPDCQ zkF`u`F?6%T*oV#dZS4>l3h9bzQ$jt;`Co8eZX4O(ghVhB1&WkVWob7lLQsHBp{7W6 zEjuU0&6#!EA*t?8O8MG6R!)!Avh$am(+ZKG0Mi)8ewlo%@64eld)NsqN2WRY*TT5j zQk#=8iuNx=Rcn@88JWAcI3cbOn}zk~t3)?v-*Df-!@FHDv`^n?l&w|SGXDh8t=KRP zRF5A!Wz3Wt0uv|IunXsP6Jy5KoAQ&$Nh$&N3I}mtcNseg)IA}8L}Bn$Ln;&5Ok_HL zFJ(F-CrCGY3ivTeH(flzRDqQH{9A!^lPlfG9p;#dj_&oc{8&yrSDm1aD7Ubeg#|%W zX)HImkn_=1Ct_j6!pelUv`{k^acfm)tn65EP=UN_Lo`#j-1I@M+3eMwq)H1i=r=0M z&*x8Wp^?oXThs4Q<>vDTRVlsN)sSATF{D?!6-rsveuc=Y>N&xa)#yQ0o|=`pHBGW` z^h%0)qR>xM>imV&JFce|2Hl3okn|WS!cg9N5j?>#JzJU*dEGeU_g3R~q4B$!>C?I{ z1XEX57#w9JYLbzt+f^x2`=p9ctWm*9&0sY;Ni~{9@R}l7*t3dcVLw(Rg=~w}I?lsc zTFB1&Y4^0C<7gO0J1SSY6&YnC@A>$N<7>u`sUBZ9E+(4~i{7K(`Q#Z7T++9Ot8pi| z+LafWP-OLt!hlF=3nxHV_$y{nCNTGcoS2*ikHL37R_-uC_A|Td|D1GeVg-{L>&=$r zHgisLr`eKtoks+{x$%u!rf7D`1Jj*1*CU^_| zyO#XK0j|Yt(JEKxc7+g}4n5#(V2Qi2t!p2ya$;d9MB!2x1y{gW7zdSbHCzX`!kw@H zm^euM0pzx?JK=SBlZk+DiC3_~)(Lr_LLvB|7}`Mx=m;l533P=JoXU%LPpc_8!0Jv! z(2s=6U^I+@81~iJU4yy?u7^6f8JHAkSw(z1>O0{sxEt<=-@v1=2o}RqSPoCaD)=Kj z3ok(En>Nu zqX4)JRCA1FPum-JT&TLzE1-UMZB)zZC#h(Rs^0ASrgs10SY~e@c8P4|hv{MC@8nJ= zx^u(_o%0+_YFavLefkfJ_8m_1NdNsbTX4LJB2Mnq&Mm|TLY0c!Md7faeX>sE^`|>< zcAM!)XD1FD+W+FdhaCQNr*Mh~)gzsCHJn{Aba3zUjfj7`PvnU6tw%cRY&aX(l8c{y zgR|4q&Q2h0;xKSj#+os=Cs;2dz|2djQqS6Q@RI-$UQPLdO4WT?cIZJX~y;+GGQ^f z(-IaoWukfXkNr4J_QF2$yxF)-W#7h}xI>wkBh7R4u4!|JibUpp#!heqP@Wr|h){>Z zPjZTIaD=rfIYYRU_X}6@LDY|nyktG<=TJAI{!o|_|KPL97sAeG6H~&>rv|GjCz;Fn zDPhi3xripl=F)OsYt9dmDo$R@kqWs*H3zn#k{eU24w2cSnv+B@lUr1)xl(0pQB6mJ zQf^VL<{5@^i)vO|isOy@@8kZzrl#Nj*T4G8mZ4%Kg1qL5R=sVnpysXSf?Emt5tW|Ie}6yVKcZ|I~R*_;+-7TF&br1V{DfxML7(G zJ?=~^oN;^BDx+XQPuhfo@3L;vzNi)>5E~AKLbABsk%??hIR=KqV9s!Ik8UAYan%u?pUHDE|5Em8l`+5NnL8F|JRs7%mn=|*WdC9x)xp)5mZZdv}{eP(h)LhyB_bF}{xqVU1Le zxnUfipEG|s1FCB(ds>DJ>)+EdbbNJBOaJOvPxFQ2ZZP+&t`VYhUjHfM#?_3Uc-6Im zOU6u@GM??G@&bYDX`q4e*9LBwblsG|#4!`bIr3=PlgCUM*RB2eQ^ra2z_r(96xWZL zSRHa2*fY>|%A~8V8<)rH zIiKAPk$a)0cX`&Q={d5u3XRg8y4_H5ZdrPNv+U7y&K~*nuiazvX@}s2+?mB?#gtjB(yo~-p?hxAOMPbw>Aw2}2IE!-I!mI^qC=Tc+;F^jzZR_>RUT`R*ni}Kc* zp{+I1GUWKB;Abs?vphRyX0N!(a&e7ZgCPe#YzxgI2Kmg+YBQ!4ieb+B8V)Izb4Qbz za$v>D6efF`0Q@pk?(#Au^QYey~tL< zCVQ-?;pWO&CpNL;u3F?UBHF(|_x9tg7p^Y$Z_PI*L5x&Z5VjHhSdR01Nlu9PEr|9B z3wz4+lk+9=3|@wQcHR(KjbrRwZ84TpU?-PRVCPKRar&-a*eCAhrz88uigJJ4#pe60 zq2SjOm#ag7P-UFim5Er( zd&qWsM(C0C&5?^l+!H60Ub*fS1p{2UEvaGDk8K;V zk-M2n-!9xRF~!wYV~(&hbK0<<+))ricY3RTnMGRNv6|1JW>YBZphea}i)(W9;{sVl zh>fUw$>0c`dA*JzD3d~<;Uc4%S>)!V92BREODHNf|4i3^Fi6aHa z*bkRAPLK7IcQ4kjWB6P{U##3DO^wPL0jT&Bt(DK*(s(oGL# z7jiMRT$Q_0o|CzUrDe3ba=8gH514WuFjz+pJb0fLK6Bd!oI zH8z^mRBsEo=4gy)Lj^HL!_T&zZ;h0=<^T588M zZ^vkTQCeTggY{CG2wgh6X}CJ1SVUvqmPXFDzStX|IifaCbfs@deRCC|GRZF=L_$`u zD0w03LnT4F=__QRPiRK{|F!oua8Xrx|99>T!!W#fhd1#JuYx075k^ZRQ^OF&LPQx; zk(3Ol5lvlGGNp~F#;n$Ic5~DAX_rUCmC8-ZsjLjpEVR@?dC|6iYo>_1)sio@ZMFQr zzjN=rfL7}NdH$d0+3tn!oZor*otNJ^_uPBW%kMz0CeD0{n9#QHOR6uR(IRS2y z;WiEQbhx22bj{|29CKjW;eHRyrEp&c^M2SLgz3aFsV?5cj#7oHOGhP84g3kHf&bfl zykkG;gFqv23ivDV1#k{X!r(Khs~iE`1l$aa2k7|JDHy0;rj2)0fOdjj2bxy%K@EYc zMH}JzLTh$?59oAeSE6pPYbY=R7z<2|yEj)2t-cC5f)^#i~oz>^rP-l9vusjVc3qaptK$$_`11yDo1^iZmb^>dG$KkdfZlsR!_rPYL z3fKns?Qq`#`b}UT@IG)1_%rY^{697HceH{247dRN6K=+kc$W~;-_a)ot5<;(U?eaa zmqJP5b)!p=MDJgaBbc6adwcj^4lkU=WZ5426nD3)D%DFa|r)VZRBO2;2tb z!p{ozjWb{t82dSjVBUqWHe;A$0sI%izQj1dQ3_g7E$LcqjCVW;yAxOoJPteoxDfWY z#(|Dap#K1Rt1-p#0%)j~biHEa9j}7k1=Pa6$JoR5o^h~Gwd4`FH^cqU;5h;MGXN?j zU0)k@q*BuLy)nq4g(^pVsE$-hy23))(2;U*Fr9#>%n~R{)JS96PfiwGdRm@;)9eR_ z>)*i#KUAe5#)I`9Iuj3T{*L-B{kdk(J3cRw`(Xcj4NXmlkL+#OmoE(9-Z@g=N)ZfX zRLlOO`wlhjZ<-|}U`FD-2CFcLQyk1Pu^(K6xg&?h3(1t^`?m-Z_uk>A!^dV}vbE_j z1}TSnM+#K)zgGfJZ`_1c{Oa{{l|UTM|K_+A*rni|l~e}%yu*N;Q53~;02h%~MlrHb zOiET<#lkt{P60$Qp>XaUUQ!elGOdujC_tJh60MN1F>;J3;$L9{aS1sWm+YFhWbTqe zL}4sPL}SD>L}9dwX$c7l<#0A;j2S~@c{z)0<;s;A2tlbOl*<7WQY7|VDdExLQ2dQ0GD#E%iX!R|0Sa%w{dR9%6i)VLat^yF0CS;e zj7i{_GiU73p<_acoG}ArTG|uBcS4Ejm?_9=UohVmq?>Yg>HKJY0ftW(%ufoMMq{LT zQzCDVEQ~CU#D{u3J{jo49RrcwiFog*=}dz%w8=hXFo7h6%cCpG7;35^f8l~fi$rl0 zUfkgu#6ArqXy{{6ry8>7--&T%ueaXoty8?S7SAue`#!ICun_ddl zvjRm2xKH$@>+{d6>$FH=$_R35j|s^O?zUqXyHuQ(ykapsxIr2Hm`3AB-4xF)pT~Z(=RmF?0m+;;7D$IQ_58=D58T2X8pM$;tT8jlfVOZc3sTJv{0M|g+leMBN9p*T= zXM>&rx(IYB!rY566|g@B`bp50pkF|kdYJEM<6RBf7}qgvKYVZXa}Ch-bKHh+snx(* z9p{~TR9+nYuYU9n#$NmI4i?Wf96p$ZEgs6Nm?*!B4NzX*3=1RKTO3~A49g($0sEv6O~+;l$@;iv9QFG z6y6`f<|Zd6;RkOAa!}?CD?*2hkq@s|6OpUEhQ!>K@MQ0_yd-nH#=w2e#{_~LlYabXsoneBuFtk3O zreREC{+Lc-3)3k4gF1MjDY=Ux_Mi%7pZADJ6?{0k~r)8k(Oc{k!d{>nTsPunr&{!0!WRfNy{v z7!Z#IEWk}T10V%k;R}H~0Xwh|>)O_8^o~8CKL-7YCfxNo^z!}#_J6^y;d?mrc$tdf zLtWPc`9LWEoxG%r*YzIoDeyPEc+sHrKLM<^q%G=riPGaGig)z|1^{MY2#~Hdx~#w~ z=;tj)xVy2EdIfk^0;_>v0uJC|;1S?zbn7a5bsamw_Zsj9up6iY_5$w$`+*OD!@v=s z8Njx6-DLjU;TK)DAV2# z4j;`jj5ZzG*GlUL4VW%euYVf}{O9H^&sA;xZ{hh4<a|7F#ezmg z!i#J%bb%Rm*%Hex;*ecnr48P+#TzF9Xi(T7lq^J#+(j6{7#`IlCMLFLWL&T4-o5+u zjTZ+bBqR>%XYQXgP?CnE3{4ws8J2wAb=QwbO&@jB@X=$&-aInnh8r`-kItGfF?-T& z<8p4vosyN8H+5RR_15XP&zxK^`;I&2%q^N%JY&9X*4_5P1tkj?;XCZErKQVOlr6Y- zB`GHT<&s}GmOu3Hy|hR9(ffb(z`BYjA9VfNiPg%#efqJDk3aJtPdxkk^_Bnm8@Ugw z-t_$MUU>0OFa2Rh&C4&pveW(QYp-v6#^e>{`n(XpZasU^xbx?TtV5tjk@%Y)8Qz|po$<)kBwHr6~RfmZMvkOZ9z%; zZTh6(ZNYguk1j9B6O^a-=<|Xv6NL0efMJt@wf6nnJI zfH72-KW1n0=*fmzqjig8u#6H*f-|67JVwA#uVpcL7#Pp6#prNo%yOvlE)M6VBwGH2 zCCa_YaZxWRHhm-t(n|`%pa{P>ip#b|Nf}rs+K)5e5MA60TYGx*B=sm{hPTD=Y!_$V zd)QKh9HOcqjxaL$^cmq{HbdC*2;|*VOe^KMv0HG;&Z2O09JE35Md^p3AP?Jng-GP1 zh%d_7i7!91Xd;_VE~?oAHR13p^A>qg4_fgF6&hfK&(gd}s5*s~r2<{(H%BkRs=w%* zpY}gp&EgJ_BB7@P`+}16lKbk?*NkATpN%F-Jd{G8g*A| zQc{UvRiz~IlQpF#_=Lf)V&sHv+g-&NJrWixoyHFYsW;;+1>l&(W*`&U;}=xDrm zRJWQ!T`2dITqZuOtJJ$S)$aF{!qk=L+G^^G%XbYm#dpo%RoB#Q21$G6J)gHEig5lL zdOo>4-WvPK`$@U)m=F}EYwh{2xNKKdOP9^yRo7CLUeaA_E$ObJmLmLjQ6`fv zd}g39UEbN}c|WW!`Rcf;T2h)$zytJJ?k8n0%a(JN;>dzNP+`QrOYn_G@#5>0J_jdY z(#fXl?yk^pG-iV+?M?dU9Ak{gy0Hi9X1h^OYC9ocN1NaR13Mz1- z^t|f^eSgQT*ku4+wxqVkQ3o7gyAUEBA=m|g5m?eA>lg%F2S8^m+hH&ZW)ZLwco295 z_zgh23tj`>0vZ75c4a#YI$)A+R}EI~_W)=&K{7A`z)l^E$aX(NE>;zr|_5nwM{{wsud;@S1 z&ARsfURj`P4jfk;eh_XP$3LxC~C zRN!`C9q}uqcPj7Z0a!dit%siFbs(a*wkSt zj0xP-Vb~a>Z0a!di6zRnsl$NIS-t*kB!IaRnkxCXDUVu^tCK)c2+jZINA}`|^-}ad z)7fwDdZx>Ipnftoyc_&~xD5U@o{Z_^x7-jn#&7v7roe9*5PO5xsGWVo9psb}n;r~H zx?;I86qXwmOIiv^!46jt-5~&K}Kta(j;L0n1p$GEEyDJUf4C(zN6|zKzWeg(Wj7J30T3%Gk`< zh~U{tnaNY~@7UclKURPxKY3CvEY?^=on%cON0xE1;7J;nY$eN_c<{_jnv*;WmYjIv z$w{6#9G0wj;>k*$GZU8Fc<|&TdWNin3`e=jLH+RzU`b-GCjuvqUfw(J zEm~9S%?D#mqbv*wU=4`2Fu)JmJG{ALe1U!}$!`Asc#Y7pi$rxcBPNnGeW5*9PJ)!R z6ok*jQu;-7K+|3MiZ!|jNrbeLNM}Lb0Zi3J zD(oTYH)3LB9FBFO^PT+hAe=?&De8LNh=Zu02pB4iFr$Y|Xi|mI z)ADk~%sUs|wPMko%a@dnwJw6HkKqz#@3_?9QTb52v~U!2lk{-JayYW^!&&mFyp?v> zAg}DyMoTJRpx9;kr1G;Adyo=-CbLIlV^EY7#-$oYO`d~bXv?+LYc;nHdalU$LEM1+!QLe2n= zWz2GmoUt(E6ncFqPyGdcshmeGm4s&ZH5TaY%^QH}wnaRg(qkc&{?MC*(E+GB3gRpU zT2k-`FN#M>4U9&s2xK%C+6vOpTWHF6fPlgwG)m^>8M;y=9mBAa(7Kh~TX4BiJ`xpB z9P4BZQxr)M^$l8v-UvN{rQ$uTwTY$k?_RJBn+Zl)&C%3;Ezp2uO^>$mn9Sy-5S(#74BbPK zG&&kvgC7;l`JJ> znZQAb3@nStf`ZN=%Y$S=L37Bmm@Fu07Fkx21qIEef|in{TR{iQ1s$do)V5%yxOB+^ z=v^ybaQA}c%aW#!nF{S|$x4akLPLS1##><8M79#$9QAd&h?N-v)XAXO1L&meIh`xx z1<1!bkD4wDOKnPruEZWM{S`HFQr=0oX(2Ru!py*05b0)ioZS!Hwo<3! zJ6sCo=iUATp|Cgsw>-PQH+SYegj<|)lp8~B$eXX!(A(#iE`us|(ULlns&_l|-Ndp! z0!yo(#HiK{ak8F}0T|s%0cHW;0;hq`;9m(d7Yd~D@Z|HcoEkk7{|J^+zYBz7l*|mI z1KGf2U>=YQJ|yJW0mah0fdfD*a0>Vm_!kh0<<)V(AYeFfGmrz!0&D=Cs#XE41D*l? z2kbi4RbrpJ-p~T3inT7 zo`d;4%m^&Y?xhu7=r~;?U`~KJ9i|OtIn0N!1p2pF0=-E~``h}vUet`#45bqce#JNTW zi8z%@=b9GO-*G4G3vsH~a?m(+%T*5A0eTJSM`8X3qk@}&XMsxKdEie#4X_J%3#did zcMx_z=p%rlOxy7h=)b`4WDriH1KkdE0OtW3Y5Wd68jLI&fe63^L<2oB(%4%c>F5XA zt7O{(`bHoVmIq0ZV~*T=}mCvZQDJbi{y(Jw(?0KNt~;bsi(@9GI80>gl@!5BHkh-NADq^touS_esBBP5hMS#njWnZq$ zEM}$fN@?MgkT8n<$-an9;iq!JSCJJWgsk8oXOejmFU2EU!sP_X?(FXVE1j z453)*f_?Pp(G(4M!ih29f}|71(nW4&IxtMV{?|+3&9`>HU0YYb=YM@c)B;?S1my0) zoI$;gOylMzLU|^z-XowB2qdimT@&MGo9fYxfr&aCfO-_~C9^6XWHHM<4E&iFbAYXB@tQkA0jm-nGK&UF{z@2sGDGB-C56N9PH{=}W1b>sRx(3s5_E44$M#X4-`2?La~I) zubBRHeQ%746N`r;QL4b3lx#wDc#ma;LO^e`Lnr4AMwydSqSRSerrgYw1FASLbD*h| ziLy|@A|Pf8K$kCSu**zTL3Af8k%25g@F89X^1`1tcS?_Hrqok>OkQS6L5@eJm~D#O ze}GmZp`20b^o^pVs+e+P@LFKP8#y5cx?~3s>=6koa*7a$7N%UY2!u{#ls74OjAE%E z9Ca?rl!xNP#uTP4M&1XkE(7j|=alk8%WKQ4djN_&(mj&4q+ujra= zpiO3%+aK#YDMI;v^)>_f?XOG1ftDX=wA3|Gw-T7xlm)N)++ZMLD{Bk^!zh$#)SQV@C|#6T8IjV`nM)e&px<6{ODI z!`T;sk5?w-H{eUs>*|0JExMF1ioh6{3`hV!mIr_4SuB2jRu#<3qWA$Z_}K#sfEqxJ zph~Fs^2ZS%az@faYMM7hDn;OXf>8y^>0a{de+BU0GAtJV;GOae_eaer_ADdHTQp>z zYFw^$$`K330+29pc^#NJL=NeT9B)<$7(|nw+=)~xN^o=6&odTJ0c+B@Llfl@$AZM4 z_dwR>e?7CAd!kdbePeC1WxvI9({^+1L7~=T*gm-SpsBWF$cw{jcMY#iKEMB!j-a)| z1xxQ;*VS$sUfZE<@Lb$3)UGqvZa3Ag8(e#6SZ&Hfb@;EYb?U1{XK*F=u%X)H45`t( z3=N)d+Jf6cszUak@cjK@eRZQVxJJK;6B<1K5V_j--V$G|;H%S)SMVLWhD{(d+3#fb zJDz@jRl&=#@2cQ8oo&Q{+c{x^rh;GATyb>$(N~U6Zz^hfqUq_TtftLPHBEI*hnqfb z;+rdvrZ!ufZ*E@K{7y?n^9#+pn*Yw--Q2+~YpOo}>hZ^qKXd#q$1WV}b^ONTA;*)C z+m25htLDtqiY zC~W#Wom5^KxvN#!9aN-viw3P#PZTGc0G3@(A-*sv$ zcpRCl<2aFndPxlz6F#grJ)>}baMm;tiZW+q-6qb;9Ve!apPVU9%$<~-Ow z=hurkPfA5yP6hjYiv4c){Ftb(`mXu+VYs^f@5mMPf8QL>NB{TMhaU8QkF-43(xWxG zb#?3SF5CaP>*7|_Z>V>BRy1yC%=tU#u1~*M2Ycg1k8H0qj`Va5^6;rj!CgP8)7j>3 z#P6AEZbSWqGq$!JVH+CVb>7%w>qdIkdd_TUeC`yYt>!4&x@r#5dWsN(shV@PInTH~ z$raACLXddoXxmwLqY%;#>Ok9Bk1nRZV^D1U$i}tnzcII&&s4QF*HxXl=vg1)1bwm2 z*_J+%d_5w{QI0bXyw>#I5s z|CI-X8$^qzr4D3u=XA<>=XB(peCkIq`HWEHQy;^uFy>Vy# zQ;n6}Q}t&J+d7QydLw20pBw6#Xp}I*&c>(e>nbX_^_sO$HKtR@Fn8nrijuPWwVr<{ zVszKVcsls%&Pkmc>Xh8XG$NehyrEvHvlvfIJv{W)or==|cm0MscO&CDfC`hjt2RG zu}EYO#kuOFv#sh==b3$rop4X7dq|UhcC!Hs$R_1@|{FG95om^Yj>G>K3pgg$IKHMJX88kGm z2DSf`2co{zxdDFNeUPS~ho0(zY(7tgQ}%DLm}<@)h?{?cWHJAfOGWnyvi0z(Z3k*t z2qnn?w+48~`A{6G;7V8|!SdeKhj9dWIosgxE$;zefyuF(kH5@;o=U+O=jEdH`!jxT z5U-rw^(1Lm+jFPdsSgQ|zPsMl*5GdRdda15*SStScgmtg*uW+RtKYxD?fL0I0g|CO z6&_TXzijS0Z`OVwy#N6r4rJCtnZ2^W-t;dY2WvXb^`1U%PjjOu#&)`k$bNm~1 zo=V5tj2rZ#Cy$?0Av9UeP$0MGVk6lt?+C4dc44RGJ$Jo7yyZFJwRZR6m|9Q2h6d!k z>zxa$?D^@&bllIlk?4LsQ`3gK>Kv*Qx7GQzczJDi*EZLA-gX~u_H;CRUX`sMFl)8v z9cFbOzUUGD!-B->nro4}!@`r6=c~@et*CRJt2)2J<2*0dp&}2e-0Z6J3%G1?&4+g9 zdAsu*y-8PUkea`S{Grgws@k)Y5SYDbqm?O4c)?~&-j>zw=eacI%LM8g@ul%DYU8Rt z$*ww)ja*IYOsCET?@O$6anjA((ZjgS?OE$O;jU}PujhQFRxSc=dgn>H>7Ae2ohR(h zPn493z;uaU(T}|YU8`Spy8ml!v#=)cYwdvNT=jSG?e7eJ_~gTZ?|(U*kTWM9uXVVL z@m%n@>DDRJrswK2Cy&pcm9NX2Ze>4{h{_DYPfjk8x6n_vZeo@-lYa7pty8AwhZ za@OShEGrp^END{x^odsXn?=7ljLyl@c>yIee#s?`pM%mvnP!YMxK#Gj*fn! z1+DPDFxzxgSZ*35JR2zqn1Wf7F8gui!BvC zj=4*?J+@qUDt4{liTSlqZ`veWFjWe(qP7adqFxjhM!hU#Mdb+Yp7}y!&)0CIeoao%%Jw590<1*?PKKUkSdaJV`}pp$LN4b^IQ> zpv4=ydymuLKH@y^!NEg^J&i{`lry3J{>&s0va_y3_m!uTb9*}a#NlykXsPRnXy^#u zaW386xTB*j#B;I5hPdB$>fMK&!8>;& zwu5*BVuL=qwve{qmffB&TMl|YFLLi*L7@+>K=?RVh~?l4Fufb{Zg6F%dv^!_)j?vU zS1}zqg7xoU{acZ{-Z`3{5@X$s&M|mS+>F+H3tDgHn$u{|>7r>b8vfSPl*#IKo^W?v z%EnrYR&0+7sc1(4jEBI#h^R244pef<573QKgmUAC!Mh&DqdNLJ+YqFoM(^ha=R0kl z&%o1O z7DbRBxYeBtIJ|%3sf`$whx8A*DWL*5Wf#$-9a%_O7x1$0K{OC6M%o}HJp_c2w;KKa zisT0xT!tMNH{!+0(9R0mJzP5l?1K8BtNkK&h`5Jt9S5c z`=bl;MuDD578{~4bVN4lJy8wD9T#d08z4UezR~Ctp{T|nV3_cmjd2UK^9@eJ`Xgvf zhrrp^P7Q+2aYRLh!0!q*@&mH(&46uWxM&_8fhRYB?aY`i=>BO6wcqR_t{eYV<3PIz#Nq zf@c_&1CD!~Z8e4!N17Yghv8$P4?Y{~cf?ekL7S{$cjW{eE zib^P5U8$t8@x3F;^kmb=hAqaiRQxZ&X7I8>DQSTb*+qat$~6fdnNRup`2Sc)%y204FnK;9cL%p1_)3m6s{FvA-#!yE7t(a14EU8bCL zkvHHaqCr5)Qmwa;KH2CXVp6c06NhG0RFZF63WTl7N6Er)K+LB&4~Dtgcycer4>sDs zo1>tzcqt0(z{P)&^@0h%Hf||e8EYrxHyo!z_`SIzgn+9rNE|HK)H^DAu@0I{ZMqaL z%=&fIVtsC3PI6F#)uC>F6=jibM!N?2UZiysG_V%LaRqTyKTwFPn}_qzaMBHGSG4I7 zGip2KBP}+UrL<^m`mj5}d*8%X&T_%b6`hP}Z!k=^#o6n;LA zpudl^RiJ&xuF5gl9)zOXhs(ljYsw;$)`DeVQO@<8ZJ=Dx+&)~fWPLIQdSxZsK7HNaBUA`=`Sh7Wu8e~>5p1U=ty;IH; zY9`iN+S3+`C>F;dh_0+REYKC)*JiZ!CY{B77bljPZRR5MOg1x4J1aBio$Iuj!^+I| zjkS^`TC!y1;AnTv@*%cFn_g%AV{BQpO<&d*XZvz+)58Y4uFL?#sDq>uizGe+M-~-> zA#9$_$R~-`>*Fl8M2b8y??fj;U?-j}&ej|HcN4AKqsxS{$i;BPZbvYqN5L+@$ayw1 zShUn8d-Am9j&$+b;;p68w#ZU%WNzfNC}#q4UY2AtE5crEE|Lte3@tO*Q2iU=ou}V2#2i2)G}h?9e8pbk?HSHnb7C z1+d?pUk-6<(0i8g(mtF>!@6Oz>bOOEsRx}=Z`0vyb!duS3IZGHr8Ihu=#=|OC!rPV zNM*JBc$kb^qX@ll67Eji1GH;1iI?89PKmLghh_I5Oxzi_P#J@%!4^zLEoTcv* zo_Tc)elv15b16EpY*KM1dKi0xxO}`lQCyx?GDs}D%{HlcJWpPWCKP9-mm-IgiWW`G znadSVL`D~7+a@iwO+s3dxO}2*5;BPVW9yTYwtQklS5mqe3~_+5T)~-g#`$zb(R-YTo0d$~hB#1P8a zFN30GaeN}%X&;6sEDwROevT`OKrfc}5%rMr0qa_`6luUXb3deRei?`xj!(u2PK$6%qi(TaCVzrb_t%jp#wDs-2;K=DmaTk%p zWl~_Fih0JztvpuCQGrut)^a$QsNN(UUOBT?(yUxk%bt5dtOb;EDHRkungD+F{pc6{ z4WBa$xj{|O>7-smYhBdOrp?Jh;s~w;Uf0*oiBe8RiB?Sc;){&LMBLOY2lgNlSq;lZ ziBj|+DLkkYAIN~ct)P|djLNx*p5A5jTrG>ilLvZ8b4+Eu;I{<5l1S>m zZ9VCs6@%Nx7KO((dp_BEq5EZBX&=N{qNnG0YFJ**xctfEMC>#kE~0hWb%OPqNGTO< z#I7Y0EuiF9(>!zlWFTE+zybp{)c!o&^hD|SRkxb*T08Nqkc*tE!&iSA9vK!mtqKy% zp~9+Q!5k()Ugco|lvm&e2qOpf2w52_F!7@$ry4QBAWoQ;l{G4nZY@uY^*rT*g8=NE znw)pJlunKH`hM27C~4|g1805Rl=m1XWsVJF9*_00Hc#CzW3H41UPthaULLERaE;T4?+BC|4+_yWXR&u+N#0~?SH*WBp-_F$u zUu+lZFzzsafT+VH96puI(^bKoOBnCv6%dPaa`^!@wTj4 znB?QW{V!Zi5RMV30avw}z&PN=t65EO#=n~2cvHpEM~^;xwBu;!(HTv1n{t}&Zu&*j zeNB$0N1HY_{pRTNP470n)^xsUfAiTUL$iR{w4+TOTv*dvtp{5F)aq_cZM~_rptYE@HoUp6PUjA(hQ}m3s^l zny=vhBlDd{*)bTbiq)T=p#-`#jTg@dyUtw6Y7$f6YLaIEYLfp+s|oB4Z+CW<2d*Xf z9a~HAy1JI2OQi=`uCD)!zoPzc>ajV;-aYo+v2p1CHaEZC{C#s|%ea=Am+k-Tad&AR z(qO`Ai#GjJ%|lwu2HA~Xx6Q&9?W9gD8>q&lgT8GCf0yQf=PMQnQ*;W2 z_>oI011pWDw_=V`OvJ$`dx9Lou2sxT#eBZQutj4$;Q3At_IyX^7R`RHqU3<*8zqVk zZMBAz_Dur;JWCxYp$thHJ;G7>GHq1M_flQhw zbDqn7nazqTHky&gEPVP&@d>`}}Pl~T-_J|K@eur$p{tD!xkQ))D?2FWVu5f%s z<8x@Rgs~E04vh*a7XynB{@U;+X83DPP~j;$#p}ck&la0|VQ}&ah>jXRlrenQT^X4|Y z>%^rVZ;~XpZP73`DqGFDH<^_clro7pe~nySuDap*>$b~#AfFn>CdcV)BP+EI`(BMF z+}G$}Igd6kw^y|MrFzS!9iIrFS^nD5E*!U$i_X$0d}R4hcwe>&do72A4=lTxO>f!L zQ76<`Uh3E`yl(fzbeV`|CAWM2M)lb63$#c!n~U^2KKHaxHrhH4D{;PO`OvagXi?(a z)$y8ez|zq1uJDqbHD$RB4IabR^X+TSS7@*rQ*IpT-`+$sw`Xsq-_zTkuLzd!==M{m zJr|qKefTDuS>Ah$y@#!O_%!CCF}b{^4ew}gRsYdV2U$#*#JGG#XUqzIReDC0KtYJoG+YfkSG<=JRzKA3*42x=h8 z+4dvyc(V%42)78EqQ=B^`nQzbA~blqHGhn8kEn$G8NO=$k1R3`df_XYK3*}#m&#AM zO&%_yk4+jsf(@U>(i>J|6dPEI$6>+$BMYKtN|k^r0aXI31XKyA5>O?eNDgjjj zssvOCs1i^mph`fMfGPo10;&X538)fKC7?<`m4GS%RRXF6R0*gOP$i&BK$UO?eNDgjjjssvOCs1i^mph`fMfGPo10;&X538)fKC7?<`m4GS%RRXF6 zR0*gOP$i&BK$UO?eNDgjjjssvOCs1i^mph`fMfGPo10;&X5 z38)fKC7?<`m4GS%RRXF6R0*gOP$i&BK$UO?eNDgjjjssvOC is1i^mph`fMfGPo10;&X538)fKC7?<`mB4?21pY5A(xuw~ literal 0 HcmV?d00001 From 9d439091a6394fc842c49c4ed8442e956e5ac4d6 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 20 Jan 2018 16:13:54 -0800 Subject: [PATCH 26/45] Developer Preview #2 --- doc/Preview Version 1.0.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/doc/Preview Version 1.0.md b/doc/Preview Version 1.0.md index 1ff527a..4efc165 100644 --- a/doc/Preview Version 1.0.md +++ b/doc/Preview Version 1.0.md @@ -1,16 +1,16 @@ -# Developer Preview Version 1.0 +# Developer Preview #2 Version 1.0 PLASMA is approaching a 1.0 release after _only_ 12 years. Hopefully it was worth the wait. To work out the remaining kinks, this Developer Preview will allow programmers to kick the tires, so to speak, to provide feedback on the system. Download the two disk images: -[PLASMA Preview 1.0 System](https://github.com/dschmenk/PLASMA/blob/master/PLASMA-PRE1.PO?raw=true) +[PLASMA Preview #2 1.0 System](https://github.com/dschmenk/PLASMA/blob/master/PLASMA-PRE2.PO?raw=true) [PLASMA 1.0 Build System](https://github.com/dschmenk/PLASMA/blob/master/PLASMA-BLD1.PO?raw=true) PLASMA can be run from floppies, System in drive 1, and Build in drive 2. All Apple II computers are supported, from the earliest Rev 0 to the last Apple IIGS. However, an accelerator and hard disk/CFFA are highly recommended. The recommended mass storage installation looks like: -System Files => /HARDISK/PLASMA.PRE1/ +System Files => /HARDISK/PLASMA.PRE2/ Build Files => /HARDISK/BLD/ @@ -64,7 +64,7 @@ This is a Developers Preview, so sample source code is included from the project ## 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. The goal is to spend considerable effort improving the load time before the final 1.0 release. 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 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. - Many modules in the project aren't included in the Developer Preview. Only those modules that have gotten a good workout are included. The rest of the modules will be tested and included for the final 1.0 release. Feel free to try them out, and give feedback. Chances are they will work out of the box, or just a small tweak. @@ -129,6 +129,8 @@ To generate compiler warning for this issue, and a few others, use the `-W` opti 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. + # 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: @@ -138,6 +140,7 @@ I wish to thank the people who have contributed the the PLASMA project. They hav - 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 From 4311e9ba51e2ac5f7561600b68f04b8dfcd2deb0 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 20 Jan 2018 16:47:06 -0800 Subject: [PATCH 27/45] Developer Preview #2 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5eb582d..2a00ce6 100755 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# 1/17/2018 Developer Preview 1.0 Available +# 1/20/2018 Developer Preview #2 1.0 Available Download and read the Release Notes: https://github.com/dschmenk/PLASMA/blob/master/doc/Preview%20Version%201.0.md From 65c33cf3aa2ffe48e0cb1bb39b100f6c2d4a9dc4 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 20 Jan 2018 16:48:37 -0800 Subject: [PATCH 28/45] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 2a00ce6..1258760 100755 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # 1/20/2018 Developer Preview #2 1.0 Available -Download and read the Release Notes: -https://github.com/dschmenk/PLASMA/blob/master/doc/Preview%20Version%201.0.md +[Download and read the Release Notes](https://github.com/dschmenk/PLASMA/blob/master/doc/Preview%20Version%201.0.md) # The PLASMA Programming Language From 2a6dbee7064b0f205027f69eadcf901dd5e58ff8 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sun, 21 Jan 2018 21:23:49 -0800 Subject: [PATCH 29/45] Swap eval stack MSB and LSB for guard bytes bytes for stack based pointers --- src/vmsrc/cmd.pla | 2 +- src/vmsrc/plvm02.s | 327 +++++++++++++------------------------------ src/vmsrc/plvm802.s | 55 +++----- src/vmsrc/plvmzp.inc | 8 +- 4 files changed, 126 insertions(+), 266 deletions(-) diff --git a/src/vmsrc/cmd.pla b/src/vmsrc/cmd.pla index 4e04939..5265b72 100755 --- a/src/vmsrc/cmd.pla +++ b/src/vmsrc/cmd.pla @@ -1440,7 +1440,7 @@ heap = *freemem // // Print PLASMA version // -prstr("PLASMA Pre2 "); prbyte(version.1); cout('.'); prbyte(version.0); crout +prstr("PLASMA Pre3 "); prbyte(version.1); cout('.'); prbyte(version.0); crout // // Init symbol table. // diff --git a/src/vmsrc/plvm02.s b/src/vmsrc/plvm02.s index c9d7ca2..c5f127a 100755 --- a/src/vmsrc/plvm02.s +++ b/src/vmsrc/plvm02.s @@ -55,15 +55,6 @@ INTERP = $03D0 ;* ;* INTERPRETER INSTRUCTION POINTER INCREMENT MACRO ;* -;!MACRO INC_IP { -; INY -; BPL + -; INC IPH -; TYA -; AND #$7F -; TAY -;+ -; } !MACRO FIX_IP { TYA CLC @@ -85,6 +76,18 @@ INTERP = $03D0 + LDY #$00 JMP .TARGET } +!MACRO INCJMP_IP .TARGET { + INY + JMP .TARGET ++ TYA + CLC + ADC IPL + STA IPL + BCC + + INC IPH ++ LDY #$00 + JMP .TARGET + } ;****************************** ;* * ;* INTERPRETER INITIALIZATION * @@ -223,13 +226,9 @@ DINTRP PLA ADC #$00 STA IPH LDY #$00 -!IF SELFMODIFY { - BEQ + -} ELSE { LDA #>OPTBL STA OPPAGE JMP FETCHOP -} IINTRP PLA STA TMPL PLA @@ -243,10 +242,6 @@ IINTRP PLA DEY + LDA #>OPTBL STA OPPAGE -!IF SELFMODIFY { - BIT LCRWEN+LCBNK2 - BIT LCRWEN+LCBNK2 -} JMP FETCHOP IINTRPX PHP PLA @@ -266,10 +261,6 @@ IINTRPX PHP LDA #>OPXTBL STA OPPAGE STA ALTRDON -!IF SELFMODIFY { - BIT LCRWEN+LCBNK2 - BIT LCRWEN+LCBNK2 -} JMP FETCHOP ;************************************************************ ;* * @@ -595,16 +586,19 @@ DIVMOD JSR _DIV ;* INCREMENT TOS ;* INCR INC ESTKL,X - BNE INCR1 - INC ESTKH,X -INCR1 JMP NEXTOP + BEQ INCR1 + JMP NEXTOP +INCR1 INC ESTKH,X + JMP NEXTOP ;* ;* DECREMENT TOS ;* DECR LDA ESTKL,X - BNE DECR1 - DEC ESTKH,X + BEQ DECR1 + DEC ESTKL,X + JMP NEXTOP DECR1 DEC ESTKL,X + DEC ESTKH,X JMP NEXTOP ;* ;* BITWISE COMPLIMENT TOS @@ -696,17 +690,6 @@ SHR3 CMP #$80 SHR4 LDY IPY JMP DROP ;* -;* LOGICAL NOT -;* -LNOT LDA ESTKL,X - ORA ESTKH,X - BEQ LNOT1 - LDA #$FF -LNOT1 EOR #$FF - STA ESTKL,X - STA ESTKH,X - JMP NEXTOP -;* ;* LOGICAL AND ;* LAND LDA ESTKL+1,X @@ -741,10 +724,20 @@ DUP DEX STA ESTKH,X JMP NEXTOP ;* +;* LOGICAL NOT +;* +LNOT LDA ESTKL,X + ORA ESTKH,X + BNE + + LDA #$FF + STA ESTKL,X + STA ESTKH,X + JMP NEXTOP +;* ;* CONSTANT ;* ZERO DEX - LDA #$00 ++ LDA #$00 STA ESTKL,X STA ESTKH,X JMP NEXTOP @@ -871,83 +864,50 @@ _CEXSX LDA (IP),Y ; SKIP TO NEXT OP ADDR AFTER STRING ;* ;* LOAD VALUE FROM ADDRESS TAG ;* -!IF SELFMODIFY { LB LDA ESTKL,X - STA LBLDA+1 - LDA ESTKH,X - STA LBLDA+2 -LBLDA LDA $FFFF + STA ESTKH-1,X + LDA (ESTKH-1,X) STA ESTKL,X LDA #$00 STA ESTKH,X JMP NEXTOP -} ELSE { -LB LDA ESTKL,X - STA TMPL - LDA ESTKH,X - STA TMPH - STY IPY - LDY #$00 - LDA (TMP),Y - STA ESTKL,X - STY ESTKH,X - LDY IPY - JMP NEXTOP -} LW LDA ESTKL,X - STA TMPL - LDA ESTKH,X - STA TMPH - STY IPY - LDY #$00 - LDA (TMP),Y + STA ESTKH-1,X + LDA (ESTKH-1,X) STA ESTKL,X - INY - LDA (TMP),Y + INC ESTKH-1,X + BEQ + + LDA (ESTKH-1,X) + STA ESTKH,X + JMP NEXTOP ++ INC ESTKH,X + LDA (ESTKH-1,X) STA ESTKH,X - LDY IPY JMP NEXTOP ; -!IF SELFMODIFY { LBX LDA ESTKL,X - STA LBXLDA+1 - LDA ESTKH,X - STA LBXLDA+2 + STA ESTKH-1,X STA ALTRDOFF -LBXLDA LDA $FFFF + LDA (ESTKH-1,X) STA ESTKL,X LDA #$00 STA ESTKH,X STA ALTRDON JMP NEXTOP -} ELSE { -LBX LDA ESTKL,X - STA TMPL - LDA ESTKH,X - STA TMPH - STY IPY +LWX LDA ESTKL,X + STA ESTKH-1,X STA ALTRDOFF - LDY #$00 - LDA (TMP),Y + LDA (ESTKH-1,X) STA ESTKL,X - STY ESTKH,X - LDY IPY + INC ESTKH-1,X + BEQ + + LDA (ESTKH-1,X) + STA ESTKH,X STA ALTRDON JMP NEXTOP -} -LWX LDA ESTKL,X - STA TMPL - LDA ESTKH,X - STA TMPH - STY IPY - STA ALTRDOFF - LDY #$00 - LDA (TMP),Y - STA ESTKL,X - INY - LDA (TMP),Y ++ INC ESTKH,X + LDA (ESTKH-1,X) STA ESTKH,X - LDY IPY STA ALTRDON JMP NEXTOP ;* @@ -1023,35 +983,18 @@ LLWX INY ;+INC_IP ;* ;* LOAD VALUE FROM ABSOLUTE ADDRESS ;* -!IF SELFMODIFY { LAB INY ;+INC_IP LDA (IP),Y - STA LABLDA+1 + STA ESTKH-2,X INY ;+INC_IP LDA (IP),Y - STA LABLDA+2 -LABLDA LDA $FFFF + STA ESTKH-1,X + LDA (ESTKH-2,X) DEX STA ESTKL,X LDA #$00 STA ESTKH,X JMP NEXTOP -} ELSE { -LAB INY ;+INC_IP - LDA (IP),Y - STA TMPL - INY ;+INC_IP - LDA (IP),Y - STA TMPH - STY IPY - LDY #$00 - LDA (TMP),Y - DEX - STA ESTKL,X - STY ESTKH,X - LDY IPY - JMP NEXTOP -} LAW INY ;+INC_IP LDA (IP),Y STA TMPL @@ -1069,39 +1012,20 @@ LAW INY ;+INC_IP LDY IPY JMP NEXTOP ; -!IF SELFMODIFY { LABX INY ;+INC_IP LDA (IP),Y - STA LABXLDA+1 + STA ESTKH-2,X INY ;+INC_IP LDA (IP),Y - STA LABXLDA+2 + STA ESTKH-1,X STA ALTRDOFF -LABXLDA LDA $FFFF + LDA (ESTKH-2,X) DEX STA ESTKL,X LDA #$00 STA ESTKH,X STA ALTRDON JMP NEXTOP -} ELSE { -LABX INY ;+INC_IP - LDA (IP),Y - STA TMPL - INY ;+INC_IP - LDA (IP),Y - STA TMPH - STY IPY - STA ALTRDOFF - LDY #$00 - LDA (TMP),Y - DEX - STA ESTKL,X - STY ESTKH,X - STA ALTRDON - LDY IPY - JMP NEXTOP -} LAWX INY ;+INC_IP LDA (IP),Y STA TMPL @@ -1123,40 +1047,24 @@ LAWX INY ;+INC_IP ;* ;* STORE VALUE TO ADDRESS ;* -!IF SELFMODIFY { SB LDA ESTKL,X - STA SBSTA+1 - LDA ESTKH,X - STA SBSTA+2 + STA ESTKH-1,X LDA ESTKL+1,X -SBSTA STA $FFFF + STA (ESTKH-1,X) INX JMP DROP -} ELSE { -SB LDA ESTKL,X - STA TMPL - LDA ESTKH,X - STA TMPH - LDA ESTKL+1,X - STY IPY - LDY #$00 - STA (TMP),Y - LDY IPY - INX - JMP DROP -} SW LDA ESTKL,X - STA TMPL - LDA ESTKH,X - STA TMPH - STY IPY - LDY #$00 + STA ESTKH-1,X LDA ESTKL+1,X - STA (TMP),Y - INY + STA (ESTKH-1,X) LDA ESTKH+1,X - STA (TMP),Y - LDY IPY + INC ESTKH-1,X + BEQ + + STA (ESTKH-1,X) + INX + JMP DROP ++ INC ESTKH,X + STA (ESTKH-1,X) INX JMP DROP ;* @@ -1206,33 +1114,18 @@ DLW INY ;+INC_IP ;* ;* STORE VALUE TO ABSOLUTE ADDRESS ;* -!IF SELFMODIFY { SAB INY ;+INC_IP LDA (IP),Y - STA SABSTA+1 + STA ESTKH-2,X INY ;+INC_IP BMI + - LDA (IP),Y - STA SABSTA+2 + STA ESTKH-1,X LDA ESTKL,X -SABSTA STA $FFFF + STA (ESTKH-2,X) JMP DROP + +FIX_IP BPL - -} ELSE { -SAB INY ;+INC_IP - LDA (IP),Y - STA TMPL - INY ;+INC_IP - LDA (IP),Y - STA TMPH - LDA ESTKL,X - STY IPY - LDY #$00 - STA (TMP),Y - LDY IPY - +FIXJMP_IP DROP -} SAW INY ;+INC_IP LDA (IP),Y STA TMPL @@ -1251,30 +1144,15 @@ SAW INY ;+INC_IP ;* ;* STORE VALUE TO ABSOLUTE ADDRESS WITHOUT POPPING STACK ;* -!IF SELFMODIFY { DAB INY ;+INC_IP LDA (IP),Y - STA DABSTA+1 + STA ESTKH-2,X INY ;+INC_IP LDA (IP),Y - STA DABSTA+2 + STA ESTKH-1,X LDA ESTKL,X -DABSTA STA $FFFF + STA (ESTKH-2,X) JMP NEXTOP -} ELSE { -DAB INY ;+INC_IP - LDA (IP),Y - STA TMPL - INY ;+INC_IP - LDA (IP),Y - STA TMPH - STY IPY - LDY #$00 - LDA ESTKL,X - STA (TMP),Y - LDY IPY - JMP NEXTOP -} DAW INY ;+INC_IP LDA (IP),Y STA TMPL @@ -1319,37 +1197,41 @@ ISGE LDA ESTKL+1,X CMP ESTKL,X LDA ESTKH+1,X SBC ESTKH,X - BVC ISGE1 - EOR #$80 -ISGE1 BPL ISTRU + BVS + + BPL ISTRU BMI ISFLS ++ BPL ISFLS + BMI ISTRU ; ISGT LDA ESTKL,X CMP ESTKL+1,X LDA ESTKH,X SBC ESTKH+1,X - BVC ISGT1 - EOR #$80 -ISGT1 BMI ISTRU + BVS + + BMI ISTRU BPL ISFLS ++ BMI ISFLS + BPL ISTRU ; ISLE LDA ESTKL,X CMP ESTKL+1,X LDA ESTKH,X SBC ESTKH+1,X - BVC ISLE1 - EOR #$80 -ISLE1 BPL ISTRU + BVS + + BPL ISTRU BMI ISFLS ++ BPL ISFLS + BMI ISTRU ; ISLT LDA ESTKL+1,X CMP ESTKL,X LDA ESTKH+1,X SBC ESTKH,X - BVC ISLT1 - EOR #$80 -ISLT1 BMI ISTRU + BVS + + BMI ISTRU BPL ISFLS ++ BMI ISFLS + BPL ISTRU ;* ;* BRANCHES ;* @@ -1358,8 +1240,7 @@ BRTRU INX ORA ESTKL-1,X BNE BRNCH NOBRNCH INY ;+INC_IP - INY ;+INC_IP - +FIXJMP_IP NEXTOP + +INCJMP_IP NEXTOP BRFLS INX LDA ESTKH-1,X ORA ESTKL-1,X @@ -1403,15 +1284,21 @@ BRGT INX CMP ESTKL,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 LDA ESTKH,X SBC ESTKH-1,X + BVS + BPL NOBRNCH BMI BRNCH ++ BPL BRNCH + BMI NOBRNCH IBRNCH LDA IPL CLC ADC ESTKL,X @@ -1443,10 +1330,6 @@ CALL INY ;+INC_IP STA IPL LDA #>OPTBL ; MAKE SURE WE'RE INDEXING THE RIGHT TABLE STA OPPAGE -!IF SELFMODIFY { - BIT LCRWEN+LCBNK2 - BIT LCRWEN+LCBNK2 -} LDY #$01 JMP FETCHOP ; @@ -1479,10 +1362,6 @@ CALLX INY ;+INC_IP STA IPL LDA #>OPXTBL ; MAKE SURE WE'RE INDEXING THE RIGHT TABLE STA OPPAGE -!IF SELFMODIFY { - BIT LCRWEN+LCBNK2 - BIT LCRWEN+LCBNK2 -} LDY #$01 JMP FETCHOP ;* @@ -1507,10 +1386,6 @@ ICAL LDA ESTKL,X STA IPL LDA #>OPTBL ; MAKE SURE WE'RE INDEXING THE RIGHT TABLE STA OPPAGE -!IF SELFMODIFY { - BIT LCRWEN+LCBNK2 - BIT LCRWEN+LCBNK2 -} LDY #$01 JMP FETCHOP ; @@ -1541,10 +1416,6 @@ ICALX LDA ESTKL,X STA IPL LDA #>OPXTBL ; MAKE SURE WE'RE INDEXING THE RIGHT TABLE STA OPPAGE -!IF SELFMODIFY { - BIT LCRWEN+LCBNK2 - BIT LCRWEN+LCBNK2 -} LDY #$01 JMP FETCHOP ;* diff --git a/src/vmsrc/plvm802.s b/src/vmsrc/plvm802.s index 1983d7c..ee0798f 100644 --- a/src/vmsrc/plvm802.s +++ b/src/vmsrc/plvm802.s @@ -74,19 +74,6 @@ NOS = $03 ; TOS-1 ;* ;* INTERPRETER INSTRUCTION POINTER INCREMENT MACRO ;* -;!MACRO INC_IP { -; INY -; BPL + -; SEP #$20 ; 8 BIT A/M -; !AS -; INC IPH -; TYA -; AND #$7F -; TAY -; REP #$20 ; 16 BIT A/M -; !AL -;+ -; } !MACRO FIX_IP { TYA CLC @@ -104,6 +91,17 @@ NOS = $03 ; TOS-1 LDY #$00 JMP .TARGET } +!MACRO INCJMP_IP .TARGET { + INY + BMI + + JMP .TARGET ++ TYA + CLC + ADC IP + STA IP + LDY #$00 + JMP .TARGET + } ;* ;* ACCUM/MEM SIZE MACROS ;* @@ -747,15 +745,6 @@ SHR PLA STA TOS,S SHREX JMP NEXTOP ;* -;* LOGICAL NOT -;* -LNOT LDA TOS,S - BEQ LNOT1 - LDA #$0001 -LNOT1 DEC - STA TOS,S - JMP NEXTOP -;* ;* LOGICAL AND ;* LAND PLA @@ -781,6 +770,13 @@ DUP LDA TOS,S PHA JMP NEXTOP ;* +;* LOGICAL NOT +;* +LNOT PLA + BNE ZERO + PEA $FFFF + JMP NEXTOP +;* ;* CONSTANT ;* ZERO PEA $0000 @@ -801,8 +797,7 @@ CB INY ;+INC_IP LA INY ;+INC_IP LDA (IP),Y PHA - INY ;+INC_IP - +FIXJMP_IP NEXTOP + +INCJMP_IP NEXTOP CW INY ;+INC_IP LDA (IP),Y PHA @@ -1165,8 +1160,7 @@ SAB INY ;+INC_IP PLA TAX SABSTX STX $FFFF - INY ;+INC_IP - +FIXJMP_IP NEXTOP + +INCJMP_IP NEXTOP } ELSE { SAB INY ;+INC_IP LDA (IP),Y @@ -1175,16 +1169,14 @@ SAB INY ;+INC_IP +ACCMEM8 ; 8 BIT A/M STA (TMP) +ACCMEM16 ; 16 BIT A/M - INY ;+INC_IP - +FIXJMP_IP NEXTOP + +INCJMP_IP NEXTOP } SAW INY ;+INC_IP LDA (IP),Y STA TMP PLA STA (TMP) - INY ;+INC_IP - +FIXJMP_IP NEXTOP + +INCJMP_IP NEXTOP ;* ;* STORE VALUE TO ABSOLUTE ADDRESS WITHOUT POPPING STACK ;* @@ -1277,8 +1269,7 @@ ISLT PLA BRTRU PLA BNE BRNCH NOBRNCH INY ;+INC_IP - INY ;+INC_IP - +FIXJMP_IP NEXTOP + +INCJMP_IP NEXTOP BRFLS PLA BNE NOBRNCH BRNCH TYA ; FLATTEN IP diff --git a/src/vmsrc/plvmzp.inc b/src/vmsrc/plvmzp.inc index 58f3595..e87f327 100755 --- a/src/vmsrc/plvmzp.inc +++ b/src/vmsrc/plvmzp.inc @@ -9,13 +9,11 @@ SRCH = SRC+1 DST = SRC+2 DSTL = DST DSTH = DST+1 +ESGUARD = $BE ESTKSZ = $20 -XSTK = $A0 -XSTKL = XSTK -XSTKH = XSTK+ESTKSZ/2 ESTK = $C0 -ESTKL = ESTK -ESTKH = ESTK+ESTKSZ/2 +ESTKH = ESTK +ESTKL = ESTK+ESTKSZ/2 VMZP = ESTK+ESTKSZ IFP = VMZP IFPL = IFP From 2175ce0d78776f149a7ad010b037d2e3e06f5b31 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Mon, 22 Jan 2018 13:56:04 -0800 Subject: [PATCH 30/45] IP fixup cleanup --- src/vmsrc/plvm02.s | 112 ++++++++++++++++++++++---------------------- src/vmsrc/plvm802.s | 91 ++++++++++++++++++----------------- 2 files changed, 101 insertions(+), 102 deletions(-) diff --git a/src/vmsrc/plvm02.s b/src/vmsrc/plvm02.s index c5f127a..db8e78d 100755 --- a/src/vmsrc/plvm02.s +++ b/src/vmsrc/plvm02.s @@ -52,48 +52,12 @@ OPIDX = FETCHOP+6 OPPAGE = OPIDX+1 STRBUF = $0280 INTERP = $03D0 -;* -;* INTERPRETER INSTRUCTION POINTER INCREMENT MACRO -;* -!MACRO FIX_IP { - TYA - CLC - ADC IPL - STA IPL - BCC + - INC IPH -+ LDY #$00 - } -!MACRO FIXJMP_IP .TARGET { - BMI + - JMP .TARGET -+ TYA - CLC - ADC IPL - STA IPL - BCC + - INC IPH -+ LDY #$00 - JMP .TARGET - } -!MACRO INCJMP_IP .TARGET { - INY - JMP .TARGET -+ TYA - CLC - ADC IPL - STA IPL - BCC + - INC IPH -+ LDY #$00 - JMP .TARGET - } ;****************************** ;* * ;* INTERPRETER INITIALIZATION * ;* * ;****************************** -* = $2000 +* = $2000 LDX #$FE TXS LDX #$00 @@ -753,17 +717,22 @@ CB LDA #$00 ;* ;* LOAD ADDRESS & LOAD CONSTANT WORD (SAME THING, WITH OR WITHOUT FIXUP) ;* -LA DEX - INY ;+INC_IP +- TYA ; RENORMALIZE IP + CLC + ADC IPL + STA IPL + BCC + + INC IPH ++ LDY #$FF +LA INY ;+INC_IP + BMI - + DEX LDA (IP),Y STA ESTKL,X INY - BMI + -- LDA (IP),Y + LDA (IP),Y STA ESTKH,X JMP NEXTOP -+ +FIX_IP - BPL - CW DEX INY ;+INC_IP LDA (IP),Y @@ -791,7 +760,7 @@ CS DEX TAY JMP NEXTOP ; -CSX DEX +CSX DEX INY ;+INC_IP TYA ; NORMALIZE IP CLC @@ -913,9 +882,16 @@ LWX LDA ESTKL,X ;* ;* LOAD ADDRESS OF LOCAL FRAME OFFSET ;* +- TYA ; RENORMALIZE IP + CLC + ADC IPL + STA IPL + BCC + + INC IPH ++ LDY #$FF LLA INY ;+INC_IP - BMI + -- LDA (IP),Y + BMI - + LDA (IP),Y DEX CLC ADC IFPL @@ -924,8 +900,6 @@ LLA INY ;+INC_IP ADC IFPH STA ESTKH,X JMP NEXTOP -+ +FIX_IP - BPL - ;* ;* LOAD VALUE FROM LOCAL FRAME OFFSET ;* @@ -1077,7 +1051,8 @@ SLB INY ;+INC_IP LDA ESTKL,X STA (IFP),Y LDY IPY - +FIXJMP_IP DROP + BMI FIXDROP + JMP DROP SLW INY ;+INC_IP LDA (IP),Y STY IPY @@ -1088,7 +1063,16 @@ SLW INY ;+INC_IP LDA ESTKH,X STA (IFP),Y LDY IPY - +FIXJMP_IP DROP + BMI FIXDROP + JMP DROP +FIXDROP TYA + LDY #$00 + CLC + ADC IPL + STA IPL + BCC + + INC IPH ++ JMP DROP ;* ;* STORE VALUE TO LOCAL FRAME OFFSET WITHOUT POPPING STACK ;* @@ -1114,18 +1098,23 @@ DLW INY ;+INC_IP ;* ;* STORE VALUE TO ABSOLUTE ADDRESS ;* +- TYA ; RENORMALIZE IP + CLC + ADC IPL + STA IPL + BCC + + INC IPH ++ LDY #$FF SAB INY ;+INC_IP + BMI - LDA (IP),Y STA ESTKH-2,X INY ;+INC_IP - BMI + -- LDA (IP),Y + LDA (IP),Y STA ESTKH-1,X LDA ESTKL,X STA (ESTKH-2,X) JMP DROP -+ +FIX_IP - BPL - SAW INY ;+INC_IP LDA (IP),Y STA TMPL @@ -1140,7 +1129,8 @@ SAW INY ;+INC_IP LDA ESTKH,X STA (TMP),Y LDY IPY - +FIXJMP_IP DROP + BMI FIXDROP + JMP DROP ;* ;* STORE VALUE TO ABSOLUTE ADDRESS WITHOUT POPPING STACK ;* @@ -1240,7 +1230,17 @@ BRTRU INX ORA ESTKL-1,X BNE BRNCH NOBRNCH INY ;+INC_IP - +INCJMP_IP NEXTOP + INY + 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 diff --git a/src/vmsrc/plvm802.s b/src/vmsrc/plvm802.s index ee0798f..f6c04f8 100644 --- a/src/vmsrc/plvm802.s +++ b/src/vmsrc/plvm802.s @@ -72,37 +72,6 @@ INTERP = $03D0 TOS = $01 ; TOS NOS = $03 ; TOS-1 ;* -;* INTERPRETER INSTRUCTION POINTER INCREMENT MACRO -;* -!MACRO FIX_IP { - TYA - CLC - ADC IP - STA IP - LDY #$00 - } -!MACRO FIXJMP_IP .TARGET { - BMI + - JMP .TARGET -+ TYA - CLC - ADC IP - STA IP - LDY #$00 - JMP .TARGET - } -!MACRO INCJMP_IP .TARGET { - INY - BMI + - JMP .TARGET -+ TYA - CLC - ADC IP - STA IP - LDY #$00 - JMP .TARGET - } -;* ;* ACCUM/MEM SIZE MACROS ;* !MACRO ACCMEM8 { @@ -797,7 +766,10 @@ CB INY ;+INC_IP LA INY ;+INC_IP LDA (IP),Y PHA - +INCJMP_IP NEXTOP + INY + BMI + + JMP NEXTOP ++ JMP FIXNEXT CW INY ;+INC_IP LDA (IP),Y PHA @@ -931,16 +903,19 @@ LWX TYX ;* ;* LOAD ADDRESS OF LOCAL FRAME OFFSET ;* +- TYA + CLC + ADC IP + STA IP + LDY #$FF LLA INY ;+INC_IP - BMI + -- LDA (IP),Y + BMI - + LDA (IP),Y AND #$00FF CLC ADC IFP PHA JMP NEXTOP -+ +FIX_IP - BPL - ;* ;* LOAD VALUE FROM LOCAL FRAME OFFSET ;* @@ -1083,9 +1058,14 @@ SW TYX ;* STORE VALUE TO LOCAL FRAME OFFSET ;* !IF SELFMODIFY { +- TYA + CLC + ADC IP + STA IP + LDY #$FF SLB INY ;+INC_IP - BMI + -- LDA (IP),Y + BMI - + LDA (IP),Y AND #$00FF CLC ADC IFP @@ -1094,8 +1074,6 @@ SLB INY ;+INC_IP TAX SLBSTX STX $FFFF JMP NEXTOP -+ +FIX_IP - BPL - } ELSE { SLB INY ;+INC_IP TYX @@ -1106,7 +1084,9 @@ SLB INY ;+INC_IP STA (IFP),Y +ACCMEM16 ; 16 BIT A/M TXY - +FIXJMP_IP NEXTOP + BMI + + JMP NEXTOP ++ JMP FIXNEXT } SLW INY ;+INC_IP LDA (IP),Y @@ -1115,7 +1095,9 @@ SLW INY ;+INC_IP PLA STA (IFP),Y TXY - +FIXJMP_IP NEXTOP + BMI + + JMP NEXTOP ++ JMP FIXNEXT ;* ;* STORE VALUE TO LOCAL FRAME OFFSET WITHOUT POPPING STACK ;* @@ -1160,7 +1142,10 @@ SAB INY ;+INC_IP PLA TAX SABSTX STX $FFFF - +INCJMP_IP NEXTOP + INY + BMI + + JMP NEXTOP ++ JMP FIXNEXT } ELSE { SAB INY ;+INC_IP LDA (IP),Y @@ -1169,14 +1154,20 @@ SAB INY ;+INC_IP +ACCMEM8 ; 8 BIT A/M STA (TMP) +ACCMEM16 ; 16 BIT A/M - +INCJMP_IP NEXTOP + INY + BMI + + JMP NEXTOP ++ JMP FIXNEXT } SAW INY ;+INC_IP LDA (IP),Y STA TMP PLA STA (TMP) - +INCJMP_IP NEXTOP + INY + BMI + + JMP NEXTOP ++ JMP FIXNEXT ;* ;* STORE VALUE TO ABSOLUTE ADDRESS WITHOUT POPPING STACK ;* @@ -1269,7 +1260,15 @@ ISLT PLA BRTRU PLA BNE BRNCH NOBRNCH INY ;+INC_IP - +INCJMP_IP NEXTOP + INY + BMI FIXNEXT + JMP NEXTOP +FIXNEXT TYA + CLC + ADC IP + STA IP + LDY #$00 + JMP NEXTOP BRFLS PLA BNE NOBRNCH BRNCH TYA ; FLATTEN IP From 1f999a86e8ed72610ca1ec88c754a5861de06759 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Mon, 22 Jan 2018 16:05:33 -0800 Subject: [PATCH 31/45] Remove SELFMODIFY references for Apple II --- src/vmsrc/plvm02.s | 13 +++- src/vmsrc/plvm802.s | 169 ++++---------------------------------------- 2 files changed, 22 insertions(+), 160 deletions(-) diff --git a/src/vmsrc/plvm02.s b/src/vmsrc/plvm02.s index db8e78d..3951b7a 100755 --- a/src/vmsrc/plvm02.s +++ b/src/vmsrc/plvm02.s @@ -5,7 +5,6 @@ ;* SYSTEM ROUTINES AND LOCATIONS ;* ;********************************************************** -SELFMODIFY = 0 ;* ;* MONITOR SPECIAL LOCATIONS ;* @@ -1299,11 +1298,19 @@ BRLT INX BMI BRNCH + BPL BRNCH BMI NOBRNCH -IBRNCH LDA IPL +IBRNCH TYA ; FLATTEN IP 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 IPH + LDA TMPH ADC ESTKH,X STA IPH JMP DROP diff --git a/src/vmsrc/plvm802.s b/src/vmsrc/plvm802.s index f6c04f8..b041b39 100644 --- a/src/vmsrc/plvm802.s +++ b/src/vmsrc/plvm802.s @@ -6,7 +6,6 @@ ;* ;********************************************************** !CPU 65816 -SELFMODIFY = 0 DEBUG = 0 ;* ;* THE DEFAULT CPU MODE FOR EXECUTING OPCODES IS: @@ -262,10 +261,6 @@ DINTRP PHP BRA SETDBG } ELSE { STX OPPAGE -!IF SELFMODIFY { - LDX LCRWEN+LCBNK2 - LDX LCRWEN+LCBNK2 -} LDY #$00 JMP FETCHOP } @@ -290,10 +285,6 @@ IINTRP PHP BRA SETDBG } ELSE { STX OPPAGE -!IF SELFMODIFY { - LDX LCRWEN+LCBNK2 - LDX LCRWEN+LCBNK2 -} JMP FETCHOP } !AS @@ -323,10 +314,6 @@ SETDBG LDY LCRWEN+LCBNK2 LDY #$00 } STX OPPAGE -!IF SELFMODIFY { - LDX LCRWEN+LCBNK2 - LDX LCRWEN+LCBNK2 -} JMP FETCHOP ;************************************************************ ;* * @@ -845,14 +832,6 @@ _CEXSX LDA (IP) ; SKIP TO NEXT OP ADDR AFTER STRING ;* ;* LOAD VALUE FROM ADDRESS TAG ;* -!IF SELFMODIFY { -LB LDA TOS,S - STA LBLDX+1 -LBLDX LDX $FFFF - TXA - STA TOS,S - JMP NEXTOP -} ELSE { LB TYX LDY #$00 TYA ; QUICKY CLEAR OUT MSB @@ -862,7 +841,6 @@ LB TYX STA TOS,S TXY JMP NEXTOP -} LW TYX LDY #$00 LDA (TOS,S),Y @@ -870,16 +848,6 @@ LW TYX TXY JMP NEXTOP ; -!IF SELFMODIFY { -LBX LDA TOS,S - STA LBXLDX+1 - STX ALTRDOFF -LBXLDX LDX $FFFF - STX ALTRDON - TXA - STA TOS,S - JMP NEXTOP -} ELSE { LBX TYX LDY #$00 TYA ; QUICKY CLEAR OUT MSB @@ -891,7 +859,6 @@ LBX TYX STA TOS,S TXY JMP NEXTOP -} LWX TYX LDY #$00 STX ALTRDOFF @@ -961,16 +928,6 @@ LLWX INY ;+INC_IP ;* ;* LOAD VALUE FROM ABSOLUTE ADDRESS ;* -!IF SELFMODIFY { -LAB INY ;+INC_IP - LDA (IP),Y - STA LABLDX+1 -LABLDX LDX $FFFF - TXA - PHA - INY ;+INC_IP - JMP NEXTOP -} ELSE { LAB INY ;+INC_IP LDA (IP),Y STA TMP @@ -981,7 +938,6 @@ LAB INY ;+INC_IP PHA INY ;+INC_IP JMP NEXTOP -} LAW INY ;+INC_IP LDA (IP),Y STA TMP @@ -990,18 +946,6 @@ LAW INY ;+INC_IP INY ;+INC_IP JMP NEXTOP ; -!IF SELFMODIFY { -LABX INY ;+INC_IP - LDA (IP),Y - STA LABXLDX+1 - STX ALTRDOFF -LABXLDX LDX $FFFF - STX ALTRDON - TXA - PHA - INY ;+INC_IP - JMP NEXTOP -} ELSE { LABX INY ;+INC_IP LDA (IP),Y STA TMP @@ -1014,7 +958,6 @@ LABX INY ;+INC_IP PHA INY ;+INC_IP JMP NEXTOP -} LAWX INY ;+INC_IP LDA (IP),Y STA TMP @@ -1028,15 +971,6 @@ LAWX INY ;+INC_IP ;* ;* STORE VALUE TO ADDRESS ;* -!IF SELFMODIFY { -SB LDA TOS,S - STA SBSTX+1 - LDA NOS,S - TAX -SBSTX STX $FFFF - PLA - JMP DROP -} ELSE { SB TYX LDY #$00 +ACCMEM8 ; 8 BIT A/M @@ -1046,7 +980,6 @@ SB TYX TXY PLA JMP DROP -} SW TYX LDY #$00 LDA NOS,S @@ -1057,24 +990,6 @@ SW TYX ;* ;* STORE VALUE TO LOCAL FRAME OFFSET ;* -!IF SELFMODIFY { -- TYA - CLC - ADC IP - STA IP - LDY #$FF -SLB INY ;+INC_IP - BMI - - LDA (IP),Y - AND #$00FF - CLC - ADC IFP - STA SLBSTX+1 - PLA - TAX -SLBSTX STX $FFFF - JMP NEXTOP -} ELSE { SLB INY ;+INC_IP TYX LDA (IP),Y @@ -1087,7 +1002,6 @@ SLB INY ;+INC_IP BMI + JMP NEXTOP + JMP FIXNEXT -} SLW INY ;+INC_IP LDA (IP),Y TYX @@ -1101,18 +1015,6 @@ SLW INY ;+INC_IP ;* ;* STORE VALUE TO LOCAL FRAME OFFSET WITHOUT POPPING STACK ;* -!IF SELFMODIFY { -DLB INY ;+INC_IP - LDA (IP),Y - AND #$00FF - CLC - ADC IFP - STA DLBSTX+1 - LDA TOS,S - TAX -DLBSTX STX $FFFF - JMP NEXTOP -} ELSE { DLB INY ;+INC_IP TYX +ACCMEM8 ; 8 BIT A/M @@ -1123,7 +1025,6 @@ DLB INY ;+INC_IP +ACCMEM16 ; 16 BIT A/M TXY JMP NEXTOP -} DLW INY ;+INC_IP LDA (IP),Y TYX @@ -1135,18 +1036,6 @@ DLW INY ;+INC_IP ;* ;* STORE VALUE TO ABSOLUTE ADDRESS ;* -!IF SELFMODIFY { -SAB INY ;+INC_IP - LDA (IP),Y - STA SABSTX+1 - PLA - TAX -SABSTX STX $FFFF - INY - BMI + - JMP NEXTOP -+ JMP FIXNEXT -} ELSE { SAB INY ;+INC_IP LDA (IP),Y STA TMP @@ -1158,7 +1047,6 @@ SAB INY ;+INC_IP BMI + JMP NEXTOP + JMP FIXNEXT -} SAW INY ;+INC_IP LDA (IP),Y STA TMP @@ -1171,16 +1059,6 @@ SAW INY ;+INC_IP ;* ;* STORE VALUE TO ABSOLUTE ADDRESS WITHOUT POPPING STACK ;* -!IF SELFMODIFY { -DAB INY ;+INC_IP - LDA (IP),Y - STA DABSTX+1 - LDA TOS,S - TAX -DABSTX STX $FFFF - INY ;+INC_IP - JMP NEXTOP -} ELSE { DAB INY ;+INC_IP LDA (IP),Y STA TMP @@ -1190,7 +1068,6 @@ DAB INY ;+INC_IP +ACCMEM16 ; 16 BIT A/M INY ;+INC_IP JMP NEXTOP -} DAW INY ;+INC_IP LDA (IP),Y STA TMP @@ -1306,22 +1183,22 @@ BRLT PLA + BMI BRNCH BEQ BRNCH BPL NOBRNCH -IBRNCH PLA +IBRNCH TYA ; FLATTEN IP CLC ADC IP STA IP - JMP NEXTOP + PLA + ;CLC ; ADD BRANCH OFFSET (BETTER NOT CARRY OUT OF IP+Y) + ADC IP + STA IP + LDY #$01 + JMP FETCHOP ;* ;* CALL INTO ABSOLUTE ADDRESS (NATIVE CODE) ;* CALL INY ;+INC_IP LDA (IP),Y INY - BNE EMUSTK - LDX IPH - INX - STX IPH - BRA EMUSTK ;* ;* INDIRECT CALL TO ADDRESS (NATIVE CODE) ;* @@ -1421,10 +1298,6 @@ EMUSTK STA TMP LDX #>DBGTBL } STX OPPAGE -!IF SELFMODIFY { - LDX LCRWEN+LCBNK2 - LDX LCRWEN+LCBNK2 -} LDY #$01 JMP FETCHOP ;* @@ -1433,10 +1306,6 @@ EMUSTK STA TMP CALLX INY ;+INC_IP LDA (IP),Y INY - BNE EMUSTKX - LDX IPH - INX - STX IPH BRA EMUSTKX ;* ;* INDIRECT CALL TO ADDRESS (NATIVE CODE) @@ -1447,9 +1316,7 @@ EMUSTKX STA TMP CLC ADC IP STA IP - SEC ; SWITCH TO EMULATED MODE - XCE - !AS + +ACCMEM8 ; 8 BIT A/M TSC ; MOVE HW EVAL STACK TO ZP EVAL STACK EOR #$FF SEC @@ -1539,10 +1406,6 @@ EMUSTKX STA TMP LDX #>DBGTBL } STX OPPAGE -!IF SELFMODIFY { - LDX LCRWEN+LCBNK2 - LDX LCRWEN+LCBNK2 -} LDY #$01 JMP FETCHOP ;* @@ -1648,14 +1511,10 @@ LEAVE INY ;+INC_IP STA PP PLA ; RESTORE PREVIOUS FRAME STA IFP - SEC ; SWITCH TO EMULATED MODE - XCE - !AS - LDA PSR - PHA + LDY PSR + PHY PLP RTS - +ACCMEM16 ; 16 BIT A/M ; RETX STX ALTRDOFF RET +ACCMEM8 ; 8 BIT A/M @@ -1696,12 +1555,8 @@ RET +ACCMEM8 ; 8 BIT A/M + } TYX - +ACCMEM16 - SEC ; SWITCH TO EMULATED MODE - XCE - !AS - LDA PSR - PHA + LDY PSR + PHY PLP RTS !IF DEBUG { From 4a033634ada96ab794a7871df7f7ad0d07624938 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Tue, 23 Jan 2018 12:20:45 -0800 Subject: [PATCH 32/45] Get all libraries to build --- src/inc/fiber.plh | 4 + src/inc/portio.plh | 4 + src/inc/sndseq.plh | 4 + src/inc/spiport.plh | 26 +- src/inc/wireio.plh | 23 - src/libsrc/fiber.pla | 33 -- src/libsrc/portio.pla | 2 +- src/libsrc/sndseq.pla | 838 +++++++++++++++++++++++++++++++++ src/makefile | 17 +- src/mkrel | 88 ++++ src/samplesrc/fibertest.pla | 24 + src/samplesrc/playseq.pla | 39 ++ src/samplesrc/rogue.combat.pla | 25 +- src/samplesrc/rogue.io.pla | 161 +------ src/samplesrc/rogue.map.pla | 118 ++--- src/samplesrc/rogue.pla | 23 +- 16 files changed, 1132 insertions(+), 297 deletions(-) create mode 100644 src/inc/fiber.plh create mode 100644 src/inc/portio.plh create mode 100644 src/inc/sndseq.plh delete mode 100644 src/inc/wireio.plh create mode 100755 src/libsrc/sndseq.pla create mode 100755 src/mkrel create mode 100644 src/samplesrc/fibertest.pla create mode 100644 src/samplesrc/playseq.pla diff --git a/src/inc/fiber.plh b/src/inc/fiber.plh new file mode 100644 index 0000000..b19dea3 --- /dev/null +++ b/src/inc/fiber.plh @@ -0,0 +1,4 @@ +import fiber + predef fbrInit(numPool), fbrStop(fid)#0, fbrExit#0, fbrStart(defaddr, param) + predef fbrYield#0, fbrHalt#0, fbrResume(fid)#0 +end diff --git a/src/inc/portio.plh b/src/inc/portio.plh new file mode 100644 index 0000000..97d81ad --- /dev/null +++ b/src/inc/portio.plh @@ -0,0 +1,4 @@ +import portio + predef digitalRead(pin), portRead, digitalWrite(pin, val)#0 + predef portWrite(val)#0, analogRead(pin), delay(time)#0 +end diff --git a/src/inc/sndseq.plh b/src/inc/sndseq.plh new file mode 100644 index 0000000..61bfbbb --- /dev/null +++ b/src/inc/sndseq.plh @@ -0,0 +1,4 @@ +import sndseq + predef spkrTone(pitch, duration)#0, spkrPWM(sample, speed, len)#0 + predef musicPlay(track, rept)#0, musicStop#0, getKey(backgroundProc)#1 +end diff --git a/src/inc/spiport.plh b/src/inc/spiport.plh index 2488f82..730dfac 100644 --- a/src/inc/spiport.plh +++ b/src/inc/spiport.plh @@ -1,7 +1,27 @@ import spiport - const SPI_SLAVE_READY = '@' - const SPI_SLAVE_ERROR = '!' - const SPI_SLAVE_BUSY = $FF + // + // Wiring constants for Arduino + // + const PINHIGH = 1 + const PINLOW = 0 + const PINOUTPUT = 1 + const PININPUT = 0 + const PINPULLUP = 2 + // + // SPI commands to Wiring functions on Arduino + // + const CMDPINMODE = 3 + const CMDDIGREAD = 4 + const CMDDIGWRITE = 5 + const CMDANAREAD = 6 + const CMDANAWRITE = 7 + // + // SPI commands to serial functions on Arduino + // + const CMDSERMODE = 8 + const CMDSERAVAIL = 9 + const CMDSERREAD = 10 + const CMDSERWRITE = 11 predef spiXferByte(outbyte), spiSend(data), spiRecv, spiWriteBuf(buf, len), spiReadBuf(buf, len) predef spiDelay(time), spiReady end diff --git a/src/inc/wireio.plh b/src/inc/wireio.plh deleted file mode 100644 index 5bb3302..0000000 --- a/src/inc/wireio.plh +++ /dev/null @@ -1,23 +0,0 @@ -// -// Wiring constants for Arduino -// -const PINHIGH = 1 -const PINLOW = 0 -const PINOUTPUT = 1 -const PININPUT = 0 -const PINPULLUP = 2 -// -// SPI commands to Wiring functions on Arduino -// -const CMDPINMODE = 3 -const CMDDIGREAD = 4 -const CMDDIGWRITE = 5 -const CMDANAREAD = 6 -const CMDANAWRITE = 7 -// -// SPI commands to serial functions on Arduino -// -const CMDSERMODE = 8 -const CMDSERAVAIL = 9 -const CMDSERREAD = 10 -const CMDSERWRITE = 11 diff --git a/src/libsrc/fiber.pla b/src/libsrc/fiber.pla index 408c22b..85fe167 100644 --- a/src/libsrc/fiber.pla +++ b/src/libsrc/fiber.pla @@ -268,36 +268,3 @@ export def fbrResume(fid)#0 fin end done - -// -// Test Fiber library -// - -def puth(h)#0 - word valstr - - valstr = "0123456789ABCDEF" - valstr++ - putc('$') - putc(valstr->[(h >> 12) & $0F]) - putc(valstr->[(h >> 8) & $0F]) - putc(valstr->[(h >> 4) & $0F]) - putc(valstr->[ h & $0F]) -end - -def fbrTest(fid, param)#0 - byte i - - for i = 1 to param - puth(fid); putc($0D) - fbrYield - next -end - -//puts("fbrSwap = "); puth(@fbrSwap); putln -fbrInit(4) -fbrStart(@fbrTest, 3) -fbrStart(@fbrTest, 2) -fbrStart(@fbrTest, 1) -fbrYield; fbrYield; fbrYield; fbrYield -done diff --git a/src/libsrc/portio.pla b/src/libsrc/portio.pla index 2915cb8..31a818a 100644 --- a/src/libsrc/portio.pla +++ b/src/libsrc/portio.pla @@ -25,7 +25,7 @@ export def portRead return (^FLAG0>>7)&1|(^FLAG1>>6)&2|(^FLAG2>>5)&4|(^FLAG3>>4)&8 end -def digitalWrite(pin, val)#0 +export def digitalWrite(pin, val)#0 ANN0[((pin&3)<<1)+(val&1)] end diff --git a/src/libsrc/sndseq.pla b/src/libsrc/sndseq.pla new file mode 100755 index 0000000..deb6922 --- /dev/null +++ b/src/libsrc/sndseq.pla @@ -0,0 +1,838 @@ +include "inc/cmdsys.plh" +include "inc/fileio.plh" +include "inc/args.plh" +// +// Usage is documented following the source in this file... +// +const rndseed = $004E +const LSB = 0 +const MSB = 1 +const MB_ARPEGGIO = 4 // In 16ths of a second +const MAX_MBCH_NOTES = 9 +const SPKR_ARPEGGIO = 2 // In 16ths of a second +const DUR16TH = 8 +const MAX_SPKR_NOTES = 4 +const NOTEDIV = 4 +// +// 6522 VIA registers +// +struc t_VIA + byte IORB // I/O Register B + byte IORA // I/O Register A + byte DDRB // Data Direction Register B + byte DDRA // Data Direction Register A + word T1C // Timer 1 Count + word T1L // Timer 1 Latch + word T2C // Timer 2 Count + byte SR // Shift Register + byte ACR // Aux Control Register + byte PCR // Peripheral Control Register + byte IFR // Interrupt Flag Register + byte IER // Interrupt Enable Register + byte IOA_noHS // I/O Register A - no HandShake +end +const T1CH = T1C+1 +// +// AY-3-8910 PSG registers +// +struc t_PSG + word AFREQ // A Frequency Period + word BFREQ // B Frequency Period + word CFREQ // C Frequency Period + byte NGFREQ // Noise Generator Frequency Period + byte MIXER // Enable=0/Disable=1 NG C(5) B(4) A(3) Tone C(2) B(1) A(0) + byte AENVAMP // A Envelope/Amplitude + byte BENVAMP // B Envelope/Amplitude + byte CENVAMP // C Envelope/Amplitude + word ENVPERIOD // Envelope Period + byte ENVSHAPE // Envelope Shape +end +// +// Sequence event +// +struc t_event + byte deltatime // Event delta time in 4.4 seconds + byte percnote // Percussion:7==0 ? Pitch:4-0 : Octave:6-4,Note:3-0 + byte perchanvol // Percussion ? EnvDur:7-0 : Channel:7,Volume:3-0 +end +// +// Predef routines +// +predef musicPlay(track, rept)#0 +predef musicStop#0 +// +// Static sequencer values +// +word seqTrack, seqEvent, seqTime, eventTime, updateTime, musicSequence +byte numNotes, seqRepeat +byte indexA[2], indexB[2], indexC[2] +byte noteA[2], noteB[2], noteC[2] +word notes1[MAX_MBCH_NOTES], notes2[MAX_MBCH_NOTES] +word notes[2] = @notes1, @notes2 +word periods1[MAX_MBCH_NOTES], periods2[MAX_MBCH_NOTES] +word periods[2] = @periods1, @periods2 +// +// MockingBoard data. +// +word[] mbVIAs // Treat this as an array of VIA ptrs +word mbVIA1 = -1 // Init to "discover MockingBoard flag" value +word mbVIA2 = 0 +// +// Octave basis frequency periods (starting at MIDI note #12) +// Notes will be encoded as basis note (LSNibble) and octave (MSNibble)) +// +word[] spkrOctave0 // Overlay and scale mbOctave0 for speaker version +word[12] mbOctave0 = 3900, 3681, 3474, 3279, 3095, 2922, 2758, 2603, 2457, 2319, 2189, 2066 +word[5] arpeggioDuration = DUR16TH, DUR16TH, DUR16TH/2, DUR16TH/3, DUR16TH/4 +// +// Emulators are broken - they only activate the MockingBoard's 6522 Timer1 +// functionality when interrupts are enabled. This music sequencer is run +// in polling mode without the use of MockingBoard interrupts. To work around +// the emulators, MockingBoard interrupts are enabled, but the 6502 IRQs are +// disabled. NO INTERRUPTS ARE HANDLED WHEN PLAYING MUSIC! The previous state +// is restored between playing sequences. +// +asm vmincs + !SOURCE "vmsrc/plvmzp.inc" +end +asm getStatusReg#1 + PHP + PLA + DEX + STA ESTKL,X + LDA #$00 + STA ESTKH,X + RTS +end +asm setStatusReg(stat)#0 + LDA ESTKL,X + INX + PHA + PLP + RTS +end +asm disableInts#0 + SEI + RTS +end +asm enableInts#0 + CLI + RTS +end +// +// Write Programmable Sound Generator Registers +// +asm psgWriteTone(pVIA, reg, freq, vol)#0 + LDA ESTKL+3,X + STA TMPL + LDA ESTKH+3,X + STA TMPH + LDY #$01 + LDA ESTKL+2,X + LSR + ADC #$08 + STA (TMP),Y + DEY + LDA #$07 + STA (TMP),Y + LDA #$04 + STA (TMP),Y + LDA ESTKL,X + INY + STA (TMP),Y + DEY + LDA #$06 + STA (TMP),Y + LDA #$04 + STA (TMP),Y + INX + BNE + +end +asm psgWriteWord(pVIA, reg, val)#0 + LDA ESTKL+2,X + STA TMPL + LDA ESTKH+2,X + STA TMPH ++ LDY #$01 + TYA + CLC + ADC ESTKL+1,X + STA (TMP),Y + DEY + LDA #$07 + STA (TMP),Y + LDA #$04 + STA (TMP),Y + LDA ESTKH,X + INY + STA (TMP),Y + DEY + LDA #$06 + STA (TMP),Y + LDA #$04 + STA (TMP),Y + BNE + +end +asm psgWrite(pVIA, reg, val)#0 + LDA ESTKL+2,X + STA TMPL + LDA ESTKH+2,X + STA TMPH ++ LDY #$01 + LDA ESTKL+1,X + STA (TMP),Y + DEY + LDA #$07 + STA (TMP),Y + LDA #$04 + STA (TMP),Y + LDA ESTKL,X + INY + STA (TMP),Y + DEY + LDA #$06 + STA (TMP),Y + LDA #$04 + STA (TMP),Y + INX + INX + INX + RTS +end +// +// Apple II speaker tone generator routines +// +export asm spkrTone(pitch, duration)#0 + STX ESP + LDY ESTKH,X + LDA ESTKL,X + BEQ + + INY ++ STA DSTL + STY DSTH + LDY ESTKH+1,X + LDA ESTKL+1,X + BEQ + + INY ++ STA TMPL + STY TMPH + TAX + LDA #$FF + PHP + SEI +; +; Total loop count is 32 cycles, regardless of path taken +; +- NOP ; 2 + NOP ; 2 + BCS + ; 3 + ;--- + ;+7 = 12 (from BCS below) ++ +-- SEC ; 2 + DEX ; 2 + BNE ++ ; 2/3 + ;---- + ; 6/7 + + DEY ; 2 + BNE +++ ; 2/3 + ;---- + ;+4/5 = 10/11 + + BIT $C030 ; 4 + LDX TMPL ; 3 + LDY TMPH ; 3 + ;--- + ;+10 = 20 + +TONELP SBC #$01 ; 2 + BCS - ; 2/3 + ;---- + ; 4/5 + + DEC DSTL ; 5 + BNE -- ; 3 + ;---- + ;+8 = 12 + + DEC DSTH ; This sequence isn't accounted for + BNE -- ; since it is taken only in extreme cases + BEQ TONEXIT + +++ NOP ; 2 + NOP ; 2 + ;--- + ;+4 = 11 (from BNE above) + ++++ BIT $C000 ; 4 + BMI TONEXIT ; 2 + BPL TONELP ; 3 + ;--- + ;+9 = 20 +TONEXIT PLP + LDX ESP + INX + INX + RTS +end +export asm spkrPWM(sample, speed, len)#0 + STX ESP + LDY ESTKH,X + LDA ESTKL,X + BEQ + + INY ++ STY DSTH + STA DSTL + LDA ESTKL+2,X + STA SRCL + LDA ESTKH+2,X + STA SRCH + LDY ESTKL+1,X + INY + STY TMPL + LDY #$00 + PHP + SEI +- LDA (SRC),Y + SEC +-- LDX TMPL +--- DEX + BNE --- + SBC #$01 + BCS -- + BIT $C030 + INY + BNE + + INC SRCH ++ DEC DSTL + BNE - + DEC DSTH + BNE - + PLP + LDX ESP + INX + INX + INX + RTS +end +// +// Search slots for MockingBoard +// +def mbTicklePSG(pVIA) + pVIA->IER = $7F // Mask all interrupts + pVIA->ACR = $00 // Stop T1 countdown + pVIA->DDRB = $FF // Output enable port A and B + pVIA->DDRA = $FF + pVIA->IORA = $00 // Reset MockingBoard + if pVIA->IORA == $00 + pVIA->IORA = $04 // Inactive MockingBoard control lines + if pVIA->IORA == $04 + // + // At least we know we have some sort of R/W in the ROM + // address space. Most likely a MockingBoard or John Bell + // 6522 board. We will assume its a MockingBoard because + // emulators fail the following PSG read test. + // + //psgWriteWord(pVIA, 2, $DA7E) + //if mbReadP(pVIA, 2) == $7E and mbReadP(pVIA, 3) == $0A + return pVIA + //fin + fin + fin + return 0 +end +def mbSearch(slot) + if slot + mbVIA1 = mbTicklePSG($C000 + (slot << 8)) + if mbVIA1 + mbVIA2 = mbTicklePSG(mbVIA1 + $80) + return slot + fin + else + for slot = 1 to 7 + if slot == 3 or slot == 6 + continue + fin + mbVIA1 = mbTicklePSG($C000 + (slot << 8)) + if mbVIA1 + mbVIA2 = mbTicklePSG(mbVIA1 + $80) + return slot + fin + next + fin + return 0 +end +def psgSetup(pVIA)#0 + psgWrite(pVIA, MIXER, $3F) // Turn everything off + psgWrite(pVIA, AENVAMP, $00) + psgWrite(pVIA, BENVAMP, $00) + psgWrite(pVIA, CENVAMP, $10) + psgWrite(pVIA, NGFREQ, $01) + psgWriteWord(pVIA, ENVPERIOD, $0001) + psgWrite(pVIA, ENVSHAPE, $00) // Single decay + psgWriteWord(pVIA, AFREQ, $0000) // Fast response to update + psgWriteWord(pVIA, BFREQ, $0000) + psgWriteWord(pVIA, CFREQ, $0000) + psgWrite(pVIA, MIXER, $38) // Tone on C, B, A +end +// +// Sequence notes through MockingBoard +// +def mbSequence(yield, func)#0 + word period, n, yieldTime + byte note, volume, channel, i, overflow, status, quit + + // + // Reset oscillator table + // + indexA[0] = 0; indexA[1] = 0 + indexB[0] = 1; indexB[1] = 1 + indexC[0] = 2; indexC[1] = 2 + noteA[0] = 0; noteA[1] = 0 + noteB[0] = 0; noteB[1] = 0 + noteC[0] = 0; noteC[1] = 0 + // + // Get the PSGs ready + // + status = getStatusReg + disableInts + mbVIA1->ACR = $40 // Continuous T1 interrupts + mbVIA1=>T1L = $F9C2 // 16 Ints/sec + mbVIA1=>T1C = $F9C2 // 16 Ints/sec + mbVIA1->IFR = $40 // Clear interrupt + mbVIA1->IER = $C0 // Enable Timer1 interrupt + psgSetup(mbVIA1) + if mbVIA2; psgSetup(mbVIA2); fin + overflow = 0 + if yield and func + yieldTime = seqTime + yield + else + yieldTime = $7FFF + fin + updateTime = seqTime + quit = FALSE + repeat + while eventTime == seqTime + note = seqEvent->percnote + if note & $80 + // + // Note event + // + volume = seqEvent->perchanvol + channel = (volume & mbVIA2.LSB) >> 7 // Clever - mbVIA2.0 will be $80 if it exists + if volume & $0F + // + // Note on + // + for i = 0 to MAX_MBCH_NOTES-1 + // + // Look for available slot in active note table + // + if !notes[channel, i].LSB //or notes[channel, i] == note + break + fin + next + // + // Full note table, kick one out + // + if i == MAX_MBCH_NOTES + i = overflow + overflow = (overflow + 1) % MAX_MBCH_NOTES + else + numNotes++ + fin + notes[channel, i] = note | (volume << 8) + periods[channel, i] = mbOctave0[note & $0F] >> ((note >> 4) & $07) + else + // + // Note off + // + for i = 0 to MAX_MBCH_NOTES-1 + // + // Remove from active note table + // + if notes[channel, i].LSB == note + notes[channel, i] = 0 + numNotes-- + break + fin + next + fin + updateTime = seqTime + else + // + // Percussion event + // + period = seqEvent->perchanvol + if period + if (period & $80) + psgWrite(mbVIA1, MIXER, $1C) // NG on C, Tone on B, A + psgWrite(mbVIA1, CENVAMP, $10) + psgWrite(mbVIA1, ENVSHAPE, (note >> 4) & $04) + psgWrite(mbVIA1, NGFREQ, (note >> 1) & $1F) + psgWrite(mbVIA1, ENVPERIOD+1, period & $7F) + elsif mbVIA2 + psgWrite(mbVIA2, MIXER, $1C) // NG on C, Tone on B, A + psgWrite(mbVIA2, CENVAMP, $10) + psgWrite(mbVIA2, ENVSHAPE, (note >> 4) & $04) + psgWrite(mbVIA2, NGFREQ, (note >> 1) & $1F) + psgWrite(mbVIA2, ENVPERIOD+1, period) + fin + else + if seqRepeat + // + // Reset sequence + // + musicPlay(seqTrack, TRUE) + seqTime = -1 // Offset seqTime++ later + else + musicStop + fin + quit = TRUE // Exit out + break + fin + fin + // + // Next event + // + seqEvent = seqEvent + t_event + eventTime = seqEvent->deltatime + eventTime + loop + if updateTime <= seqTime + // + // Time slice active note tables (arpeggio) + // + for channel = 0 to 1 + // + // Multiplex oscillator A + // + i = indexA[channel] + repeat + i = (i + 3) % MAX_MBCH_NOTES + n = notes[channel, i] + if n // Non-zero volume + break + fin + until i == indexA[channel] + if n.LSB <> noteA[channel] + psgWriteTone(mbVIAs[channel], AFREQ, periods[channel, i], n.MSB) + noteA[channel] = n.LSB + indexA[channel] = i + fin + // + // Multiplex oscillator B + // + i = indexB[channel] + repeat + i = (i + 3) % MAX_MBCH_NOTES + n = notes[channel, i] + if n // Non-zero volume + break + fin + until i == indexB[channel] + if n.LSB <> noteB[channel] + psgWriteTone(mbVIAs[channel], BFREQ, periods[channel, i], n.MSB) + noteB[channel] = n.LSB + indexB[channel] = i + fin + // + // Multiplex oscillator C + // + i = indexC[channel] + repeat + i = (i + 3) % MAX_MBCH_NOTES + n = notes[channel, i] + if n // Non-zero volume + break + fin + until i == indexC[channel] + if n.LSB <> noteC[channel] + psgWrite(mbVIAs[channel], MIXER, $38) // Tone on C, B, A + psgWriteTone(mbVIAs[channel], CFREQ, periods[channel, i], n.MSB) + noteC[channel] = n.LSB + indexC[channel] = i + fin + next + updateTime = seqTime + MB_ARPEGGIO - (numNotes >> 2) + fin + // + // Increment time tick + // + seqTime++ + while !(mbVIA1->IFR & $40) // Wait for T1 interrupt + if ^$C000 > 127; quit = TRUE; break; fin + *rndseed++ + loop + mbVIA1->IFR = $40 // Clear interrupt + if yieldTime <= seqTime; func()#0; yieldTime = seqTime + yield; fin + until quit + psgWrite(mbVIA1, MIXER, $FF) // Turn everything off + psgWrite(mbVIA1, AENVAMP, $00) + psgWrite(mbVIA1, BENVAMP, $00) + psgWrite(mbVIA1, CENVAMP, $00) + if mbVIA2 + psgWrite(mbVIA2, MIXER, $FF) + psgWrite(mbVIA2, AENVAMP, $00) + psgWrite(mbVIA2, BENVAMP, $00) + psgWrite(mbVIA2, CENVAMP, $00) + fin + mbVIA1->ACR = $00 // Stop T1 countdown + mbVIA1->IER = $7F // Mask all interrupts + mbVIA1->IFR = $40 // Clear interrupt + setStatusReg(status)) +end +// +// Sequence notes through Apple II speaker +// +def spkrSequence(yield, func)#0 + word period, duration, yieldTime + byte note, i, n, overflow + + // + // Start sequencing + // + overflow = 0 + if yield and func + yieldTime = seqTime + yield + else + yieldTime = $7FFF + fin + updateTime = seqTime + repeat + while eventTime == seqTime + note = seqEvent->percnote + if note & $80 + // + // Note event + // + if seqEvent->perchanvol & $0F + // + // Note on + // + for i = 0 to MAX_SPKR_NOTES-1 + // + // Look for available slot in active note table + // + if !notes1[i] or note == notes1[i] + break + fin + next + if i == MAX_SPKR_NOTES + // + // Full note table, kick one out + // + overflow = (overflow + 1) & (MAX_SPKR_NOTES-1) + i = overflow + elsif !notes1[i] + // + // Add new note + // + numNotes++ + fin + notes1[i] = note + periods1[i] = spkrOctave0[note & $0F] >> ((note >> 4) & $07) + else + // + // Note off + // + for i = 0 to MAX_SPKR_NOTES-1 + // + // Remove from active note table + // + if notes1[i] == note + notes1[i] = 0 + numNotes-- + break + fin + next + fin + else + // + // Percussion event + // + if seqEvent->perchanvol + //spkrPWM($D000, 0, 64) // Play some random sample as percussion + else + if seqRepeat + musicPlay(seqTrack, TRUE) + else + musicStop + fin + return + fin + fin + // + // Next event + // + seqEvent = seqEvent + t_event + eventTime = eventTime + seqEvent->deltatime + loop + if numNotes > 1 + for i = 0 to MAX_SPKR_NOTES-1 + if notes1[i] + spkrTone(periods1[i], arpeggioDuration[numNotes]) + fin + *rndseed++ + next + seqTime++ + else + period = 0 + for i = 0 to MAX_SPKR_NOTES-1 + if notes1[i] + period = periods1[i] + break; + fin + *rndseed++ + next + duration = eventTime - seqTime + seqTime = duration + seqTime + spkrTone(period, DUR16TH * duration) + fin + if ^$C000 > 127; return; fin + if yieldTime <= seqTime; func()#0; yieldTime = seqTime + yield; fin + until FALSE +end +// +// No sequence, just waste time and yield +// +def noSequence(yield, func)#0 + // + // Start wasting time + // + if !yield or !func + yield = 0 + fin + seqTime = 0 + repeat + seqTime++ + if seqTime < 0; seqTime = 1; fin // Capture wrap-around + *rndseed++ + spkrTone(0, DUR16TH) // Waste 16th of a second playing silence + if ^$C000 > 127; return; fin + if yield == seqTime; func()#0; seqTime = 0; fin + until FALSE +end +// +// Start sequencing music track +// +export def musicPlay(track, rept)#0 + byte i + + // + // First time search for MockingBoard + // + if mbVIA1 == -1 + if !mbSearch(0) + // + // No MockingBoard - scale octave0 for speaker + // + for i = 0 to 11 + spkrOctave0[i] = mbOctave0[i]/NOTEDIV + next + fin + fin + // + // Zero out active notes + // + for i = 0 to MAX_MBCH_NOTES-1; notes1[i] = 0; notes2[i] = 0; next + for i = 0 to MAX_MBCH_NOTES-1; periods1[i] = 0; periods2[i] = 0; next + // + // Start sequencing + // + seqRepeat = rept + seqTrack = track + seqEvent = seqTrack + seqTime = 0 + eventTime = seqEvent->deltatime + numNotes = 0 + // + // Select proper sequencer based on hardware + // + if mbVIA1 + musicSequence = @mbSequence + else + musicSequence = @spkrSequence + fin +end +// +// Stop sequencing music track +// +export def musicStop#0 + musicSequence = @noSequence +end +// +// Get a keystroke and convert it to upper case +// +export def getKey(backgroundProc)#1 + byte key + + while ^$C000 < 128 + musicSequence($08, backgroundProc)#0 // Call background proc every half second + loop + key = ^$C000 & $7F + ^$C010 + return key +end +done + +//////////////////////////////////////////////////////////////////////////////// + +There are three main externally callable routines in this module: + +musicPlay(trackPtr, trackRepeat) + Start playing a track sequence in the getUpperKey routine + Params: + Pointer to a track sequence created from the cvtmidi.py tool + Repeat flag - TRUE or FALSE. + The first time its is called, it will try and search for a MockingBoard. + However, it is noted that this can cause problems if a Z-80 card is installed. + The scanning routine might cause a hang if it encounters a Z-80 card before + it finds a MockingBoard. In order to make this robust, it might be best to + prompt the user to search for the MockingBoard, enter the actual MockingBoard + slot, or skip the MockingBoard and use the internal speaker. + +musicStop() + Stop playing a track sequence in the getUpperKey routine + The getUpperKey routine will call a dummy sequence routine that will + keep the correct timing for any background processing + +getKey() + Wait for a keypress and return the character + While waiting for the keypress, the track sequence will be played though + either the MockingBoard (if present) or the internal speaker. Optionally, + a background function can be called periodically based on the sequencer + timing, so its pretty accurate. + +The low level internal speaker routines used to generate tones and waveforms +can be called for warnings, sound effects, etc: + +spkrTone(period, duration) + Play a tone + Params: + (1020000 / 64 / period) Hz + (duration * 32 * 256 / 1020000) seconds + +spkrPWM(samples, speed, len) + Play a Pulse Width Modulated waveform + Params: + Pointer to 8 bit pulse width samples + Speed to play through samples + Length of sample + +The main routines for sequencing music are: + +mbSequence(yield, func) +spkrSequence(yield, func) +noSequence(yield, func) + + All three try and provide more functionality than would be present in + previous music sequencers. The MockingBoard sequencer will attempt to play up + to 9 tones per sound generator (18 if a MockingBoard II is found). Up to + four notes will be played simultaneously on the internal speaker. In order + to play more notes than the hardware normally supports, a technique using + arpeggio (playing multiple notes in a quick sequence rather than concurrently) + pulls off this feat. The sequencers will immediately return if a keypress is + detected. Finally, during the sequencing, a background function can be periodically + called every 'yield' time which has a resolution of a 16th of a second. Pass + in zero for 'yield' and/or 'func' to disable any background calls. diff --git a/src/makefile b/src/makefile index 122c28c..90675c8 100755 --- a/src/makefile +++ b/src/makefile @@ -23,6 +23,8 @@ CONIO = CONIO\#FE1000 SANE = SANE\#FE1000 FPSTR = FPSTR\#FE1000 FPU = FPU\#FE1000 +SNDSEQ = SNDSEQ\#FE1000 +PLAYSEQ = PLAYSEQ\#FE1000 SANITY = SANITY\#FE1000 RPNCALC = RPNCALC\#FE1000 WIZNET = WIZNET\#FE1000 @@ -49,6 +51,7 @@ TESTLIB = TESTLIB\#FE1000 PROFILE = PROFILE\#FE1000 MEMMGR = MEMMGR\#FE1000 MEMTEST = MEMTEST\#FE1000 +FIBERTEST = FIBERTEST\#FE1000 FIBER = FIBER\#FE1000 LONGJMP = LONGJMP\#FE1000 PLASM = plasm @@ -72,7 +75,7 @@ TXTTYPE = .TXT #SYSTYPE = \#FF2000 #TXTTYPE = \#040000 -all: $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM802) $(PLVM03) $(CMD) $(PLASMAPLASM) $(CODEOPT) $(ARGS) $(MEMMGR) $(MEMTEST) $(FIBER) $(LONGJMP) $(ED) $(MON) $(ROD) $(SIEVE) $(UTHERNET2) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(HTTPD) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(ROGUEIO) $(HGR1) $(TONE) $(DGR) $(DGRTEST) $(FILEIO) $(CONIO) $(PORTIO) $(SPIPORT) $(SDFAT) $(FATCAT) $(FATGET) $(FATPUT) $(FATWDSK) $(FATRDSK) $(SANE) $(FPSTR) $(FPU) $(SANITY) $(RPNCALC) +all: $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM802) $(PLVM03) $(CMD) $(PLASMAPLASM) $(CODEOPT) $(ARGS) $(MEMMGR) $(MEMTEST) $(FIBER) $(FIBERTEST) $(LONGJMP) $(ED) $(MON) $(ROD) $(SIEVE) $(UTHERNET2) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(HTTPD) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(ROGUEIO) $(HGR1) $(TONE) $(DGR) $(DGRTEST) $(FILEIO) $(CONIO) $(PORTIO) $(SPIPORT) $(SDFAT) $(FATCAT) $(FATGET) $(FATPUT) $(FATWDSK) $(FATRDSK) $(SANE) $(FPSTR) $(FPU) $(SANITY) $(RPNCALC) $(SNDSEQ) $(PLAYSEQ) clean: -rm *FE1000 *FF2000 $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03) @@ -156,6 +159,18 @@ $(FIBER): libsrc/fiber.pla $(PLVM02) $(PLASM) ./$(PLASM) -AMOW < libsrc/fiber.pla > libsrc/fiber.a acme --setpc 4094 -o $(FIBER) libsrc/fiber.a +$(FIBERTEST): samplesrc/fibertest.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AMOW < samplesrc/fibertest.pla > samplesrc/fibertest.a + acme --setpc 4094 -o $(FIBERTEST) samplesrc/fibertest.a + +$(SNDSEQ): libsrc/sndseq.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AMOW < libsrc/sndseq.pla > libsrc/sndseq.a + acme --setpc 4094 -o $(SNDSEQ) libsrc/sndseq.a + +$(PLAYSEQ): samplesrc/playseq.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AMOW < samplesrc/playseq.pla > samplesrc/playseq.a + acme --setpc 4094 -o $(PLAYSEQ) samplesrc/playseq.a + $(LONGJMP): libsrc/longjmp.pla $(PLVM02) $(PLASM) ./$(PLASM) -AMOW < libsrc/longjmp.pla > libsrc/longjmp.a acme --setpc 4094 -o $(LONGJMP) libsrc/longjmp.a diff --git a/src/mkrel b/src/mkrel new file mode 100755 index 0000000..ba20ee9 --- /dev/null +++ b/src/mkrel @@ -0,0 +1,88 @@ +cp CMD#FF2000 prodos/CMD.BIN +cp PLASMA.SYSTEM#FF2000 prodos/PLASMA.SYSTEM.SYS +cp PLASMA16.SYSTEM#FF2000 prodos/PLASMA16.SYSTEM.SYS + +mkdir prodos/sys +cp ARGS#FE1000 prodos/sys/ARGS.REL +cp CONIO#FE1000 prodos/sys/CONIO.REL +cp DGR#FE1000 prodos/sys/DGR.REL +cp DHCP#FE1000 prodos/sys/DHCP.REL +cp ED#FE1000 prodos/sys/ED.REL +cp ETHERIP#FE1000 prodos/sys/ETHERIP.REL +cp FIBER#FE1000 prodos/sys/FIBER.REL +cp FILEIO#FE1000 prodos/sys/FILEIO.REL +cp FPSTR#FE1000 prodos/sys/FPSTR.REL +cp FPU#FE1000 prodos/sys/FPU.REL +cp INET#FE1000 prodos/sys/INET.REL +cp LONGJMP#FE1000 prodos/sys/LONGJMP.REL +cp MEMMGR#FE1000 prodos/sys/MEMMGR.REL +cp PORTIO#FE1000 prodos/sys/PORTIO.REL +cp SANE#FE1000 prodos/sys/SANE.REL +cp SDFAT#FE1000 prodos/sys/SDFAT.REL +cp SPIPORT#FE1000 prodos/sys/SPIPORT.REL +cp SNDSEQ#FE1000 prodos/sys/SNDSEQ.REL +cp UTHERNET#FE1000 prodos/sys/UTHERNET.REL +cp UTHERNET2#FE1000 prodos/sys/UTHERNET2.REL +cp ../sysfiles/FP6502.CODE#060000 prodos/sys/FP6502.CODE.BIN +cp ../sysfiles/ELEMS.CODE#060000 prodos/sys/ELEMS.CODE.BIN + +mkdir prodos/demos +cp DGRTEST#FE1000 prodos/demos/DGRTEST.REL +cp RPNCALC#FE1000 prodos/demos/RPNCALC.REL +cp ROD#FE1000 prodos/demos/ROD.REL + +mkdir prodos/demos/rogue +cp ROGUE#FE1000 prodos/demos/rogue/ROGUE.REL +cp ROGUECOMBAT#FE1000 prodos/demos/rogue/ROGUECOMBAT.REL +cp ROGUEIO#FE1000 prodos/demos/rogue/ROGUEIO.REL +cp 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 FATCAT#FE1000 prodos/demos/sdutils/FATCAT.REL +cp FATGET#FE1000 prodos/demos/sdutils/FATGET.REL +cp FATPUT#FE1000 prodos/demos/sdutils/FATPUT.REL +cp FATREADDSK#FE1000 prodos/demos/sdutils/FATREADDSK.REL +cp FATWRITEDSK#FE1000 prodos/demos/sdutils/FATWRITEDSK.REL + +mkdir prodos/demos/net +cp HTTPD#FE1000 prodos/demos/net/HTTPD.REL + +mkdir prodos/demos/music +cp PLAYSEQ#FE1000 prodos/demos/music/PLAYSEQ.REL +cp mockingboard/ultima3.seq prodos/demos/music/ULTIMA3.SEQ.BIN + +mkdir prodos/bld +cp PLASM#FE1000 prodos/bld/PLASM.REL +cp 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/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 + +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/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 diff --git a/src/samplesrc/fibertest.pla b/src/samplesrc/fibertest.pla new file mode 100644 index 0000000..cc806aa --- /dev/null +++ b/src/samplesrc/fibertest.pla @@ -0,0 +1,24 @@ +// +// Test Fiber library +// + +include "inc/cmdsys.plh" +include "inc/fiber.plh" + +def fbrTest(fid, param)#0 + byte i + + for i = 1 to param + puth(fid); putc($0D) + fbrYield + next +end + +//puts("fbrSwap = "); puth(@fbrSwap); putln +fbrInit(4) +fbrStart(@fbrTest, 3) +fbrStart(@fbrTest, 2) +fbrStart(@fbrTest, 1) +fbrYield; fbrYield; fbrYield; fbrYield + +done diff --git a/src/samplesrc/playseq.pla b/src/samplesrc/playseq.pla new file mode 100644 index 0000000..c602b41 --- /dev/null +++ b/src/samplesrc/playseq.pla @@ -0,0 +1,39 @@ +include "inc/cmdsys.plh" +include "inc/args.plh" +include "inc/fileio.plh" +include "inc/sndseq.plh" + +/////////////////////////////////////////////////////////////////////////////// +// +// These are utility sequences/routines needed to test the music sequencer code. +// +word arg +word ref +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// +// More utility routines to test the getKey routine +// +// Sample background process +// +def backgroundProc#0 + ^$0400++ +end + +arg = argNext(argFirst) +if ^arg + ref = fileio:open(arg) + if ref + fileio:read(ref, heapmark(), heapavail()) + fileio:close(ref) + musicPlay(heapmark(), TRUE) + getKey(@backgroundProc) + musicStop + else + puts("File not found.\n") + fin +fin + +done +//////////////////////////////////////////////////////////////////////////////// diff --git a/src/samplesrc/rogue.combat.pla b/src/samplesrc/rogue.combat.pla index e305891..3809663 100644 --- a/src/samplesrc/rogue.combat.pla +++ b/src/samplesrc/rogue.combat.pla @@ -1,7 +1,8 @@ include "inc/cmdsys.plh" +include "inc/conio.plh" import rogueio - word rnd, getkb, home, gotoxy, tone + word rnd, getkb, tone end import roguemap predef moveplayer @@ -138,28 +139,28 @@ export def fight(player, enemy) word p_atck, e_atck repeat - home() - gotoxy(0, 0) + conio:home() + conio:gotoxy(0, 0) puts(player+name) - gotoxy(1, 2) + conio:gotoxy(1, 2) puts("Skill :"); puti(player->skill) - gotoxy(1, 3) + conio:gotoxy(1, 3) puts("Health :"); puti(player->health) - gotoxy(1, 4) + conio:gotoxy(1, 4) puts("Energy :"); puti(player->energy) - gotoxy(20, 0) + conio:gotoxy(20, 0) puts(entity[enemy->kind]) - gotoxy(21, 2) + conio:gotoxy(21, 2) puts("Power :"); puti(enemy->power) - gotoxy(21, 3) + conio:gotoxy(21, 3) puts("Life :"); puti(enemy->life) for e_atck = 0 to 9 - gotoxy(0, 10 + e_atck) + conio:gotoxy(0, 10 + e_atck) puts(@ascii_warrior + e_atck * 11) - gotoxy(20, 10 + e_atck) + conio:gotoxy(20, 10 + e_atck) puts(ascii_entity[enemy->kind] + e_atck * 11) next - gotoxy(12, 8); puts("F)ight or R)un?") + conio:gotoxy(12, 8); puts("F)ight or R)un?") if toupper(getkb()) == 'R' return 1 else diff --git a/src/samplesrc/rogue.io.pla b/src/samplesrc/rogue.io.pla index ddf40e9..31b349a 100644 --- a/src/samplesrc/rogue.io.pla +++ b/src/samplesrc/rogue.io.pla @@ -1,7 +1,5 @@ include "inc/cmdsys.plh" - -const modkeep = $2000 -const modinitkeep = $4000 +include "inc/conio.plh" byte[] initstr byte = " ( )\n" @@ -22,10 +20,7 @@ word titlestr = @initstr // Machine specific routines // -export word rnd, getkb, home, gotoxy, tone -export word open, read, close, newline - -byte noapple1 = "APPLE 1 NOT SUPPORTED." +export word rnd, getkb, tone const ENV_REG = $FFDF @@ -35,8 +30,6 @@ const a2rndnum = $4E // ZP location of RND const a2rndl = $4E const a2rndh = $4F -word iobuff - word a3rndnum = 12345 def a3rnd @@ -60,7 +53,7 @@ def a2tone(duration, delay) ^SPEAKER for i = 0 to delay next - duration = duration - 1 + duration-- loop return 0 end @@ -75,183 +68,41 @@ def a3tone(duration, pitch) return 0 end -// -// ProDOS file routines -// - -def a2open(path, access) - byte params[6] - - params.0 = 3 - params:1 = path - params:3 = heapallocalign($0400, 8, @iobuff) - params.5 = 0 - syscall($C8, @params) - return params.5 -end -def a2close(refnum) - byte params[2] - - if iobuff - heaprelease(iobuff) - iobuff = 0 - fin - params.0 = 1 - params.1 = refnum - return syscall($CC, @params) -end -def a2read(refnum, buff, len) - byte params[8] - - params.0 = 4 - params.1 = refnum - params:2 = buff - params:4 = len - params:6 = 0 - syscall($CA, @params) - return params:6 -end -def a2newline(refnum, emask, nlchar) - byte params[4] - - params.0 = 3 - params.1 = refnum - params.2 = emask - params.3 = nlchar - return syscall($C9, @params) -end - -// -// SOS file routines -// - -def a3open(path, access) - byte params[7] - - params.0 = 4 - params:1 = path - params.3 = 0 - params:4 = @access - params.6 = 1 - syscall($C8, @params) - return params.3 -end -def a3close(refnum) - byte params[2] - - params.0 = 1 - params.1 = refnum - return syscall($CC, @params) -end -def a3read(refnum, buff, len) - byte params[8] - - params.0 = 4 - params.1 = refnum - params:2 = buff - params:4 = len - params:6 = 0 - syscall($CA, @params) - return params:6 -end -def a3newline(refnum, emask, nlchar) - byte params[4] - - params.0 = 3 - params.1 = refnum - params.2 = $FF - params.3 = nlchar - return syscall($C9, @params) -end - // // Apple /// console routines // -def dev_status(devnum, code, list) - byte params[5] - - params.0 = 3 - params.1 = devnum - params.2 = code - params:3 = list - return syscall($82, @params) -end -def a3keypressed - byte count - dev_status(cmdsys.devcons, 5, @count) - return count -end - def a3getkb - while not a3keypressed + while not conio:keypressed() a3rndnum = a3rndnum + 123 loop return getc() end -def a3home - putc(28) - return 0 -end - -def a3gotoxy(ch, cv) - putc(24) - putc(ch) - putc(25) - putc(cv) - return 0 -end - -// -// Apple ][ console routines -// - -def a2home - return call($FC58, 0, 0, 0, 0) // home() -end - -def a2gotoxy(x, y) - ^$24 = x + ^$20 - return call($FB5B, y + ^$22, 0, 0, 0) -end - // // Set machine specific routines // when MACHID & $C8 is $08 // Apple 1 - puts(@noapple1) + puts("APPLE 1 NOT SUPPORTED.") return -1 is $C0 // Apple /// rnd = @a3rnd getkb = @a3getkb - home = @a3home - gotoxy = @a3gotoxy tone = @a3tone - open = @a3open - read = @a3read - close = @a3close - newline = @a3newline break otherwise // Apple ][ rnd = @a2rnd getkb = @a2getkb - home = @a2home - gotoxy = @a2gotoxy tone = @a2tone - open = @a2open - read = @a2read - close = @a2close - newline = @a2newline wend // // Print title page // -home() +conio:home() while ^titlestr puts(titlestr) titlestr = titlestr + ^titlestr + 1 diff --git a/src/samplesrc/rogue.map.pla b/src/samplesrc/rogue.map.pla index 3010c68..0f33e2a 100644 --- a/src/samplesrc/rogue.map.pla +++ b/src/samplesrc/rogue.map.pla @@ -2,13 +2,15 @@ // Map module // include "inc/cmdsys.plh" +include "inc/conio.plh" +include "inc/fileio.plh" import rogueio const O_READ = 1 const O_WRITE = 2 const O_READ_WRITE = 3 - word rnd, getkb, home, gotoxy, tone, open, read, close, newline + word rnd, getkb, tone end // @@ -175,14 +177,14 @@ export def loadmap(level) // Set level map and read it // catacomb[catacomb] = '0' + level - mapref = open(@catacomb, O_READ) + mapref = fileio:open(@catacomb) if mapref - newline(mapref, $7F, $0D) + fileio:newline(mapref, $7F, $0D) for row = 1 to maprows - 2 - l = read(mapref, map + (row << 6) + 1, mapcols) + l = fileio:read(mapref, map + (row << 6) + 1, mapcols) ^(map + (row << 6) + l) = WALL_TILE next - close(mapref) + fileio:close(mapref) return TRUE fin return FALSE @@ -260,7 +262,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist) // // Clear screen // - home() + conio:home() // // Draw background map if in light // @@ -302,96 +304,96 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist) occluded = 1 when o & 7 is 0 - // - // Run through lit octant beam points - // + // + // Run through lit octant beam points + // for l = 1 to dbeam[lightdist] - // - // Check parent visiblity - // + // + // Check parent visiblity + // if vispix[vbeam[l]] imap = ((yorg - ybeam[l]) << rowshift) + xorg + xbeam[l] tile = ^(map + imap) if tile & OPAQUE_TILE - // - // The view stops here - // + // + // The view stops here + // vispix[l] = 0 else - // - // This tile is transparent - // + // + // This tile is transparent + // vispix[l] = 1 - // - // Check adjacent tile for opaqueness - improves wall display - // + // + // Check adjacent tile for opaqueness - improves wall display + // adjtile = ^(map + imap + 1) & INV_TILE if adjtile & OPAQUE_TILE ^(viewmap + imap + 1) = adjtile | VIEWED_TILE screen.[ycentr-ybeam[l], xcentr+xbeam[l]+1] = adjtile - fin + fin fin - // - // Update view - // + // + // Update view + // ^(viewmap + imap) = tile | VIEWED_TILE - if tile <> PIT_TILE + if tile <> PIT_TILE screen.[ycentr-ybeam[l], xcentr+xbeam[l]] = tile & INV_TILE - fin + fin else vispix[l] = 0 fin next - // - // Run through visible octant beam points - // + // + // Run through visible octant beam points + // for l = l to dbeam[viewdist] - // - // Check parent visiblity - // + // + // Check parent visiblity + // if vispix[vbeam[l]] imap = ((yorg - ybeam[l]) << rowshift) + xorg + xbeam[l] tile = ^(map + imap) if tile & OPAQUE_TILE - // - // The view stops here - // + // + // The view stops here + // vispix[l] = 0 else - // - // This tile is transparent - // + // + // This tile is transparent + // vispix[l] = 1 - occluded = 0 + occluded = 0 fin - // - // If the tile is in light, update view - // - if tile & LIT_TILE + // + // If the tile is in light, update view + // + if tile & LIT_TILE ^(viewmap + imap) = tile | VIEWED_TILE screen.[ycentr-ybeam[l], xcentr+xbeam[l]] = tile & INV_TILE darkness = 0 - fin + fin else vispix[l] = 0 fin - // - // Advance beam distance - // - if l == dbeam[dist] - if occluded // - // Beam fully occluded + // Advance beam distance // - break - fin - // - // Update distance - // + if l == dbeam[dist] + if occluded + // + // Beam fully occluded + // + break + fin + // + // Update distance + // occluded = 1 dist = dist + 1 - fin - next + fin + next break is 1 for l = 1 to dbeam[lightdist] diff --git a/src/samplesrc/rogue.pla b/src/samplesrc/rogue.pla index 5c2c2a5..7b2e58d 100755 --- a/src/samplesrc/rogue.pla +++ b/src/samplesrc/rogue.pla @@ -1,4 +1,5 @@ include "inc/cmdsys.plh" +include "inc/conio.plh" import roguemap const xcentr = 20 @@ -41,7 +42,7 @@ import roguecombat end import rogueio - word rnd, getkb, home, gotoxy, tone + word rnd, getkb, tone end const maxlight = 10 @@ -200,24 +201,24 @@ end // def status#0 - gotoxy(0, statusline) + conio:gotoxy(0, statusline) puts(@helthstr) puti(player.health) - gotoxy(9, statusline) + conio:gotoxy(9, statusline) puts(@enrgystr) puti(player.energy) - gotoxy(17, statusline) + conio:gotoxy(17, statusline) puts(@oilstr) puti(player:oil/10) - gotoxy(25, statusline) + conio:gotoxy(25, statusline) puts(@goldstr) puti(player.gold) if player.raft - gotoxy(32, statusline) + conio:gotoxy(32, statusline) puts(@raftstr) fin if player.key - gotoxy(36, statusline) + conio:gotoxy(36, statusline) puts(@keystr) fin end @@ -461,7 +462,7 @@ def play if player.health == 0 return FALSE fin - gotoxy(xcentr, ycentr) + conio:gotoxy(xcentr, ycentr) when toupper(getkb()) is 'I' if totaldarkness @@ -598,7 +599,7 @@ def play break is 'X' clearstatus - gotoxy(0, statusline) + conio:gotoxy(0, statusline) puts(@quitstr) if toupper(getkb()) == 'Y' player.health = 0 @@ -637,7 +638,7 @@ while loadmap(level) totaldarkness = drawmap(player.xpos, player.ypos, player.fov, player.angle, player.lamp, maxview) if not totaldarkness drawentities - gotoxy(xcentr, ycentr) + conio:gotoxy(xcentr, ycentr) putc(vplayer[player.angle]) fin status @@ -647,7 +648,7 @@ while loadmap(level) player.key = 0 level = level + 1 clearstatus - gotoxy(0, statusline) + conio:gotoxy(0, statusline) if player.health == 0 break fin From 527d27b9f655e5f3bf415aeccadffba702a61ee6 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Tue, 23 Jan 2018 15:15:11 -0800 Subject: [PATCH 33/45] Clean up a few more libraries and demos --- src/libsrc/fiber.pla | 4 +- src/makefile | 10 +---- src/mkrel | 4 ++ src/mockingboard/ultima3.seq | Bin 170709 -> 4401 bytes src/samplesrc/fibertest.pla | 2 +- src/samplesrc/hgr1.pla | 10 ----- src/samplesrc/hgr1test.pla | 79 +++-------------------------------- src/samplesrc/index.html | 5 +++ 8 files changed, 19 insertions(+), 95 deletions(-) mode change 100755 => 100644 src/mockingboard/ultima3.seq delete mode 100644 src/samplesrc/hgr1.pla create mode 100755 src/samplesrc/index.html diff --git a/src/libsrc/fiber.pla b/src/libsrc/fiber.pla index 85fe167..4d3be2d 100644 --- a/src/libsrc/fiber.pla +++ b/src/libsrc/fiber.pla @@ -23,12 +23,12 @@ byte fbrRunning = 0 // Zero Page VM state and 6502 stack // struc t_vm - byte estklo[$10] byte estkhi[$10] - byte esp + byte estklo[$10] word ifp word pp byte hwsp + byte esp byte fill[9] byte dropop byte nextop[$10] diff --git a/src/makefile b/src/makefile index 90675c8..787ac0e 100755 --- a/src/makefile +++ b/src/makefile @@ -43,8 +43,6 @@ ROGUEMAP= ROGUEMAP\#FE1000 ROGUECOMBAT= ROGUECOMBAT\#FE1000 HELLO = HELLO\#FE1000 MON = MON\#FE1000 -HGR1 = HGR1\#FE1000 -HGR1TEST= HGR1TEST\#FE1000 DGRTEST = DGRTEST\#FE1000 TEST = TEST\#FE1000 TESTLIB = TESTLIB\#FE1000 @@ -75,7 +73,7 @@ TXTTYPE = .TXT #SYSTYPE = \#FF2000 #TXTTYPE = \#040000 -all: $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM802) $(PLVM03) $(CMD) $(PLASMAPLASM) $(CODEOPT) $(ARGS) $(MEMMGR) $(MEMTEST) $(FIBER) $(FIBERTEST) $(LONGJMP) $(ED) $(MON) $(ROD) $(SIEVE) $(UTHERNET2) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(HTTPD) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(ROGUEIO) $(HGR1) $(TONE) $(DGR) $(DGRTEST) $(FILEIO) $(CONIO) $(PORTIO) $(SPIPORT) $(SDFAT) $(FATCAT) $(FATGET) $(FATPUT) $(FATWDSK) $(FATRDSK) $(SANE) $(FPSTR) $(FPU) $(SANITY) $(RPNCALC) $(SNDSEQ) $(PLAYSEQ) +all: $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM802) $(PLVM03) $(CMD) $(PLASMAPLASM) $(CODEOPT) $(ARGS) $(MEMMGR) $(MEMTEST) $(FIBER) $(FIBERTEST) $(LONGJMP) $(ED) $(MON) $(ROD) $(SIEVE) $(UTHERNET2) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(HTTPD) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(ROGUEIO) $(TONE) $(DGR) $(DGRTEST) $(FILEIO) $(CONIO) $(PORTIO) $(SPIPORT) $(SDFAT) $(FATCAT) $(FATGET) $(FATPUT) $(FATWDSK) $(FATRDSK) $(SANE) $(FPSTR) $(FPU) $(SANITY) $(RPNCALC) $(SNDSEQ) $(PLAYSEQ) clean: -rm *FE1000 *FF2000 $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03) @@ -299,12 +297,6 @@ $(ROGUEMAP): samplesrc/rogue.map.pla $(PLVM02) $(PLASM) ./$(PLASM) -AMOW < samplesrc/rogue.map.pla > samplesrc/rogue.map.a acme --setpc 4094 -o $(ROGUEMAP) samplesrc/rogue.map.a -$(HGR1): samplesrc/hgr1.pla samplesrc/hgr1test.pla $(PLVM02) $(PLASM) - ./$(PLASM) -AMOW < samplesrc/hgr1test.pla > samplesrc/hgr1test.a - acme --setpc 4094 -o $(HGR1TEST) samplesrc/hgr1test.a - ./$(PLASM) -AMOW < samplesrc/hgr1.pla > samplesrc/hgr1.a - acme --setpc 4094 -o $(HGR1) samplesrc/hgr1.a - hello: samplesrc/hello.pla $(PLVM) $(PLASM) ./$(PLASM) -AMOW < samplesrc/hello.pla > samplesrc/hello.a acme --setpc 4094 -o $(HELLO) samplesrc/hello.a diff --git a/src/mkrel b/src/mkrel index ba20ee9..b6bc1e8 100755 --- a/src/mkrel +++ b/src/mkrel @@ -48,16 +48,19 @@ cp FATWRITEDSK#FE1000 prodos/demos/sdutils/FATWRITEDSK.REL mkdir prodos/demos/net cp HTTPD#FE1000 prodos/demos/net/HTTPD.REL +cp samplesrc/index.html prodos/demos/net/INDEX.HTML.TXT mkdir prodos/demos/music cp PLAYSEQ#FE1000 prodos/demos/music/PLAYSEQ.REL cp mockingboard/ultima3.seq prodos/demos/music/ULTIMA3.SEQ.BIN +cp mockingboard/startrek.seq prodos/demos/music/STARTREK.SEQ.BIN mkdir prodos/bld cp PLASM#FE1000 prodos/bld/PLASM.REL cp 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 @@ -86,3 +89,4 @@ 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 vmsrc/plvmzp.inc prodos/bld/inc/PLVMZP.INC.TXT diff --git a/src/mockingboard/ultima3.seq b/src/mockingboard/ultima3.seq old mode 100755 new mode 100644 index 412c4373afb5842987ab0a6abd4e857f82d901b7..9e7d0aae729d05a07155e2c49915c3971c2eed04 GIT binary patch literal 4401 zcmeH~%}!fM5QWQfTWV=WDjxa1K|e@VmLe2j6CifL-q;4;*zqRhN#?7n`_q`rD2tJ1 z7Hkl7pE_N2>gN`6sTY?bbG?|0^uPbP)wJbMq*V@6D{|0u5IJf(+M%6bbx;h)^OL4i zkHq$9wi*13<`>7G91kXVf-|goyz$3*yb{R%t&9(Q&HK@}j3-;o0Op$Uncw*d+nMJ8 z@aMMj|MrdlSm7aL!TU>y*{rRtAoB=rK6y&W=Jx4QK?U`qOGKHU8&QCfcy52WKo_br(Uv&23w;r7# zk2=~O)Yxj<`rTH|lltAZx8;1VGlJsQ<2v_wuqD#D{;{=?XZ*x%@Q=lc@Ubx|kZW7g zwlTR#OSQ_9g9|jklc8iZ(b&_p#(-W9f#|4ZYyq zwtk)G2A-O~;vCBWa=ax9!in<6$?$n!tc=4SieX*yx)F4Pr`919z#O?Ai$%RGY3U@l z#*l6sxhv_ek*#AEB`q4*5^S8n<_^mz?P7=gsidb~;USj#{FB$`);+{wy!xqfD*4pN zPv>;GEK|e+Gx(4$RK3!4C32(bhBD|C_Nz{9Y9kZ|6WOU1u2rqiVI!93A|EwBdmd}A zK6=j{i`1_VUSUNu^6s6cJCQG%zlcCWIYs>}G%pa)X(Nhd?>WlsO5V9*ORQ8L3en|< zMxI4>eeQOI>?xpz(&?0zU17zQw>?$11!$TV{9)g3r zjv&T}2(~Jm4herKkL}yOz&4oa3tp*O!}4gi-XOsM|J&RR^#=dm#jLYg@sB+c4-o?O zW)YbWb_>}2w|28mfjJ1hSvr5BWooUWUyQTL#n3fy{$|&_=A6LB0K^|-Ha}zhPLL?N zG90dzZ_C67*A$G&;#R;;IzhMSJLXcQ$vC1-dB+171~uZ>%EQksLp%6UDaQUmCnl87 zJsddWk1>vkt8Gz?19?>2hJTE7sMgMm0>fZO_J7dF>pz$$gYuYLLiJq#MVW5xe6n~w zwY;t5gW4S1b*Z!p2mC=~?H$A%pzGEGQn7VpLt zi&u!tkSb@G2iz#~SuZ||+&6;H!Mr956*EdkM4@D@TPPN4*O*|w(F-PIFh{?yG_A-5 z<<}^stxyTi=)W`Sw2F{?GG`5fLMuwhtIoLR#0tlEjeTkE|Kzgg T>}~g$((Ft^7}zlBdXc{X?t7jT literal 170709 zcmeI5OR^oykzL!=C?vCLs)3T~12!K3Y6R+N{u2>>yBX5oij|4T^SJ<6>^!p@j12#6 z-|q3j;a~p8m;d*F|Mr)E`Sj_3{`Y_R`oI4EpHE-^+h6`P_-{7&R~xL)KilWaV12HG zpFWv%4n|KMH0g^)s(e)9nq~WE4#rF!H0f%l4nAS~3zT2H^t;6UN!t|+YP)7fq;JJt zvqO;_=>%BxiI|?g8udIYv%KX8PxOf()j$)a}1WAU!pu*_a)L{(U&iO zpS~n)X8!SK+rQSDpZ^ns_4((|e;)i6J^$kvEHir$dVbC49E>0gYBambU}oFS!C1t> z*v`SsgzFaARCwB-{5)%ZJ8b_!I3TDkqUYmJ&NR&qet}^Os53AS9q2UOETE zcHEo6;E?wG5L9WnWN{5DyxX5xvy*GAS;}{EVNmhedcKw!oKzEcDsOeOZ3lb*3LFA| z{$#qaH1w*i@J={J+-tcT91>O>4hd*$jZZA)8RSd_L-Zs6wvaBq=5q!vGe?YS(zi&5ASb|cgy@XU0IkNoEdoMXIs|nzhd&edD9^#43I?Z(EhpdO5JgBk8LoSh zLp(R>`R~dvCsCFNPAoYG18f>0IM8q`1)u!<9P@-timB4YkBB8zrliyMZyNUqLX4b4 z^z&+0XKu#xnw#+_1UZM4AQq|am*9DAU%y5r3M#!+PYy1PSsC-?KT0Kd{!1)k;9@%{ zs2g1gYRbEl>vMwPt69|2p=Tomo^R!cLxLrPO?wG5TRH@JjHrCT z5ambzS%cb#EU-y5vnHfF{hE_I9OLr?b;Hbi2vIO7Y#N`S-yX!pid$s1_bw93>lS#) zj>NsZ^a%)Q<$>e|0|wi63|{QDhvyG44CRkOAf&+nu4^xi!6TX!q^>iBEM5xgPKlZo zp)(HB6%0y27aRhFI9-@U?YiOQGUhIa3@0Z>^&jqbFJLpIA0dX9oI~jOe9m*5V@;Hv z1tFOkFbs>{MJ#^86N}XL;ia0S2vLCDprC5@xE1Qo3cTdui0h!|(g~FE-oED82Xvvw zDOqy?SS`#!PXx_(w%G@k1{gA!nHX$Z8-rmRjiz?g0WIS0J#E&6lN}6pjOLr=xDL{L zyE+7w?S8hlZ>H{g==oaiVzUgDZtP{!r2}Anm;>9>+pG}He9DIN2`R-70ErwxEpMoSb|TK2|cH6hYUgAN#GMtPU3luI|e&&_64&X>;mf?>FI3 z-|ecIThB`>?%mgo7zGR!DAHPEe#}fKkbN8w(z`Rv?29T5F~D%KT}2<_P3hKgN{A&5 zIXwU5Za20s#1bz-kaLL5d~&zjDnYsyQ-yasWJI$N;+<-cJZAm?A%J%y1RYDO1QNJF zh+=8W_JCn1{{n>^kuqo+Vu<7K&nu?|UEwH;TW>QbH zU9ogQEP%}ogalwpEQC#>NwzU8IjLsmu>EZu5(&VD-GjXN z)3_IMCtZ{=OS@H(*nc#lZFVaU*z{$h-qFwA>)*dA6bT2kg97F2|bCjsP; zT4RAtlty_4iv4lH3GBoLHg~y%dM&;K-x;ayehB!Tr~0 zjgYbCBOIco2e5GtdEEAQafovATM$yV^C?J!7MFCbl7fMQN!St1lFrt19hhB~ab^DDOvm+J3nAS7SP^W!}a!A{b80{lODM;^S zdJy%!&uy@m**A09h-HIgd#;P!?#RusO%efmUfke-f?6f|lTB0*k}VrR+sEeMx-O=p zB@Ty_p3BLJwlTIh)DyFqxvUvM!%OwIpSqjpb%WFXq?h9PA*j5hrN=qM=)zA<%%TfD z(J%S=yeZ#aB0?gawktw12r&35T-Mw|h=D;bYrM)Bz`XRtA!g>X1>S~@a)=HpvFM-{ zsf2hI)1OZ)7pQxftlCVA(X{;_s{ybK1`HTfvRc@tK3@jY#u&g-Wu{7nts4}y4KU>; z7qk!W%ml49+h9<+P6yi|2wbxw*3>Ik&G)5peRnb|LYIjlsAf8Uo_p!Fq}qXd!`>Fl6G!ipGd=|~yx=i{aEc@Pp3V3VIg&Wv;j@+_vFC1^?5NY6}e zLPM1}yXeoyV3De4M?R;Xru;(GzteAyIYP|##q$+ir^@mYe>6oO9(rZ#s_8sF2CJ4zO%ygA3?*7WF%vw$l z;w1=jFxbqCb8k4=w-`|g(!FP(lTQ(HQDsm&T6xxvn29Xbr(gTwSRTxj*=^=169?)P zA!A$p0)#9D<=~LvkkEz2T@j*S=;T6(`>o~>RJPxEZC)xZ%}KB{)~rc49);HDOF@b4 zgiQv45Iu=%gbbBR#xDp4r;9Bo7eYM5m9Xr76(RZ#u(SAK4)NTKMI#*Fm0z%AY~#dI z6@jp6hv2?LIiwu|Go1jbe6W;yq;&BkVhM*NWssZxme>lPbBMy`xBkts*bdk%Jy^MN z|M_Ug9mLX&E@0zNEDE^`XfrtU3_@}(j_dnglduUG25e3d;wstw`{Jck8D8|4-rnTb zOmc|c)GM*{8wohsUwN7G7hB-rb`(17P#`LSlO6k_3EEzCCiLQkZ22M%lY z1CP;vmh|RN>PfaqG>sXYe$B}@UTDO2SfnpB6buTR#wX~v2e%$$nC-gT)s5|v9f^A| z56`#qKys%H29;QRV{04mBLJ zRWf|u*vr&*U=JbD6VltFq2~bxlt}GZdM`tS*bc=z7E|eBvpn>SlVdw9QZVQiSj$;w z@eouFY0&bZ)y#B+l(Li3>r1DLfMJIO`Y0ZHDu=X6BSr~v;LQ+6PtMFBoV>vMfXz_p zoG!ML%jv>kfKiRWSF4GPMdC@9^3ZowuFp`Pbn!c5mQ7D1(+i9v;p z-}S`vTd*;J?PW)r6SLh5w1Hvi{AAh-$1cF24jGt#8?gj+Lr{55Lwu2OP~HKSa124kpH3H+ z2#$~>!dUaW@`Q~l-)0gFK?qLF+9JTa*BsKzqNRa6$^@%S%mlGqm#zY}+djV1yy ze>h~Q^e(#i=WmV;C;uQ3h^1hj91^zSU|v%UK}U!cOT0G>LP#u%CBEedhvai6mwmp^ zAzHQn`I}=vNbk-N_rCbk5CaSs+tqQ=pL(SGI6ZkL+k{x`^JjOvr5CIA{w?rZcDqrD ziJ;j*FBLPiLq;@f&^y)ooc-tB^AL0_opB(63xp_^wruBq^92aG*aE|!??A{ue{&3U zp|FYPm-}K(nF9Vy?I6Tv`a1#3I6pCqAcB_otVwzfrk$z-tk&dl%KjGEU1uEPt-Dd> z1+k#YToB7hu9DHVE3qhDkZt05#S&vg+uzF}l&%P|5Gz7%l%9efANKT~ix+=UiFz`R zg5=x=j=cBtSRIeG81v-(Qj_7_?h6FnAwQpD)VCBD9)q(Qrtx6eJT2^}j6l zGEoU6&@loST2CD$7_ue@-+&N(NusyvZ$U_$41_pcoI8YG%06yHvt&3zA|0PMhoB-{ zJPFuG2;%-MLTtO*YYyAr#v$dp+3?igZ$U`17zl9=iAsp3Qzi2#$_HS>bv3yE8to+< zqE!a4Q4aAc6EoEz!^{^T#5u&$@GS_bKyho?9KuVw^OT{N3=B(h1tF1+&znQg9(0LR zVj1D60@Ge1u|%cE5u#vFQZ0*SYQF#>+J_`%rl1mh10m}9&;`P=--onH_}ninltZk| zzTgm~_I^{U^{7eUp_gMp-Qzu2x=I6BlNJ4Gs8bHns@=9@O?^(LO{oG*?`3)rY1rpB z*vssjxttQ0({*F3gS|TgT_|iWZg4}{x#8&jR9{HJ7J|DK1KOG?&_xKYI(Qqi+=%7-N z4(=i3=Tp$f(ON}swj2e;BmxH;ii4~U&|>fgJ`IXWzYDFE^kuOAd6+{{QKy69CF0YN z?1HvGR}RrZWkntAz(M)w$wT`9YzeV}VJUo-9h$H{7}sIDdI9f2ECE>ji30s`L>-5~ zpY1vfHs*)&RmvAqEsK`H)1u!uBV*0d#!+YZY%f92_B;pUWDL5X?UdOkYQF#qGYs3y zb&HcviTVOyXkXh)5Y)BSmfB2J zo`WT5p`f5{n0aIejwuu&-?HZTyq4=hNdNXnNyp3&Bdd-P4%ih-4x1=Xi@4WTwh6IV z^StEIO=8)GjU&Xsph&*KA!Pvpwjd-NLSnheA@w=815Fns7K69Oy=_+x;h@olV*YP& z$iVz5hxAMWj9#kcJY^IN@ea5 zAIM?weXtp>JLeEf*l&DB7=*mxC!wB2NFjm=tN#?PEds!nVj2!1{pMHHA_$**A5xUF z+?nQc#yvAZ0t$vca6^@8<+(f4ico?U{-l{f2+cgNGFfu~tPs-AOVmpojO`fIvr2Cd zN>5s(9MV+=p4Za@7ep_WncvjO$s;(VrNhjI4GK!zK0YrC+nRuAE`1vz`#&?~WW~6b;N>L0%>KBanTkq`dmI8RIT*HG z*S*aE?J0+72e^3Y9)~DG^zGJ@2)V%_=DLhZF_z;aO(~HnvU| zrRVZ_XiX8K#KM_Ra!BX`%6s5G>UX02o=eH!qSCm2YJV04!O9#N8sA_A?WZD2NNRJ^D~E=oVOuRHq^Q>3gnHe(S)kIfQq7*3U1e2bvw_Ag7CD z9HOZ$$Hgr$K38T?4(a3~7{VdQcTKK^1kO3c*3{(ED;P(J(S@>&bBGl_C6*2c3QBjC zM2IFrl560z^!C1v8CNr%R0A8RqwsEqug945FMaCgU?_(Q;*xAOm)q48sY-2sG+U^_@3IZ6~A;5gE35zJj)?bUd_bdveQ515ZzY)t)?$0CvgY_DQvtR8A3Gf`><*0aI$hpTLk47FO`Mr zkZ*)d%~ac+Lt;DWLVFwg?Wr4dQF<-=VucMKjhu5xX2Nw#a>XI`=EO^nfk9#OEJ7;j zd3WY-PLxB!pCjMPOh2F3Dii5&U7I=9tVtIaf0(Jy43tTj(wj=EZtpR4UkK^=F1;l^fJQ-+*eW;*@eWE%kN z2A1L_?2q2UHrBB?+XOaHY41&GU}JGt*z6zP?juA2);%pLsFeN0E5g_g)T#6(4eLv7 zxAZZ_a=Mk|D%5>K?dU7Qk?)xq<$*fAVZ69*=4QDTUdT#M57^g*f}+xJT`Jf14q6ZG z{onrAnj{w8O(+=jLBhq&GGODcQ;fYEHY0FBi1L!MjhY#RAaE~12r8FeBDX(T__h(^ zKLnu&F^Bw$2nptakWOt9i+U-wmgGO2+@~0iTkkqCWn;g zmot`Pu!R|tGJ}`GpPF1`u$uXC91@G5=l<&yuQF<89D*!<35PuXs7bTK5ORYs*?-}t=gA5Ntw$Fx+_p-Oc2>IUAuFa+)pJ?`tU|6K z_DF71M1Aia-&S){%Fha$YRDaQIbBcTbkGlP<0a^MaVrE0(#>+8 zoRC;z5wPUj|I9=dFDFq28{I+c*+qvK$>qoU<>aM}iI7c6Qy-oayxG%SCdFO8q`7pBjZ3$4ht}<>Rz;d$V(>(77gB8sM$p&v1 zwEejPY#;N=Hae*NybkJJc@Kj8b#LhWdF~LLU0mQ3$)%+F7NRcL@KU~Gq@2t_-8f{; zVUZGb!F$;s)lBahta)~P8j`h??`MY#(u^}OJedf}^E#+JuY+C4F*J0vv@JH zqPg^S75Du$mueU+ndkp2SDD41<>U?r0=E44&F5-9BG1U$!q^%3xR#wre@lK`m!GxWql-h;)X-R9Y;0SBO1E=br!d zi)p(KC9=W5!FXPG&?82tfm`Zk&D23JrcA>lH+Q7(uj$EUdGvD&^ipM#u%R_1?2;Yv zd_|K_`n~Kj4HM!B8lF!$R5}wjGr8t5IFzr!8znL^8Y;yh$xR+5WsozY65!p5fWh`B z274yf?3rV*EYfnOFEeNa;Zx2Ae}Lc=7XhWZL8r2HW!(jGzgI!}CC$GOcrnF>N2kW6kA_L|kW&mc0v# z>jr3}d~y?m&!Vmt=0Eq=2ZwpLw&hQE9d8^0FmhdK(CnpYmtt@))ObCy*uNh5pIDKVmhQO>TtlKpX+3Q#8}EN{23=xd5e+nVQc2r zzc21;h`@Q(&YA;Y_4jiAS)TXSh$_7c$rtqcF3kWWqb3C6Wo+ z_>)d9FL`~ZKkM%W-U&zO7Z(BV;3a)*sYLA;l!keQ_hRPZI;6~#zq-(ZfRKf0>p1$x z%kWZ`|KP;|7KZ?etr7tiFkq(g=UzoP{7Kt` zSW=Y~V0WofZ6B_Slj+a0eP7Roe(Q55z&uC*&$pAo3=TyDZ8y4#I%P%93<1(hbchn* zIl%JE7{kfIQj~`vePZFLE0tKF6*d~UWjj#Xbn^_)_aI+n#Ud!b>^p*`vURqa@lpo$ z^D%hL9Infnx!M?mnW^_36jU>HkMIlrK;phX)gs?b&`afzeL?$c`qr}U^a)zWyk&>N zTamnM*#hsd4caY#)=tpA0Cn$h^2HN1)MD)_+w&uj%1k}GXn&$t>~K&}0EWSa4FoOM zxCO=Knd{;C!3-I+)ZQ25{~FiU+()t({h$uYD`*|w`s}UrWVhBNpfB9$`5e5A!SH7W zq381EBy_>gk8p5J`m<*0ai20+b26~hphXsUj4;^Y;9&gu@PqCB^G~(N`IDYcIQaZ2 zPNwH?2Cmjv=y#iwH4z-NtTKtaBKe$?w~!n`M4d@jBs*Qu^G7(C9fWtyyx?T?pNh{5 zcn>oVe?I)fnEOa}PNwZq$&kD+Xg@m?iux4!<2X4dW{6QAl3;`5s3VfA!}d*6IhjYD zdMMiG^B_Q{$^;Hf>zn$-9Z23QriBondt;}cEimBipe^a2 zxzo?49!S=3=ni_%_EZGg9we7nK4Y)FFMaPutOWb%LBVDThaD*>e>N{6?&>8yv(lcS z^PT4m@e)v{Yqmo;a|`q5OdBr&V9KBUMgk5|`c-^(+(EychQQ~3ZZ2t9U|90~oN3kb z@h6AUp(jN3!< zQ6>hK6kwUDfurp;)4R%=>0KoWu%gLl28~aav#6w~!(clET(|GfrB^(-j&Uc0l|%Lg z?FY^YFiwU_&Wdp|X6{KZ+ZEnTEWnZzU|@rp%eBru)V;&WN~%tkVOro*`BS~*_zb)i zv>?@e+ZR&3hvX$j$LAxO2^^UrGsz(}^TNr%=RT6#A^2QDtC-jRvq@l>8H-ZNImmhx zhmaYL&xf8hb3dA@{9=2pd6$!6(FgaRkiMXZRjE+=;$0m%!8)Xa7WW;(pf%w?w^C-d{D#6gSuqEfl8&#cfV>+92H z!x+!={4);G-2``MnaSVLJqCwGaa~Dshag55CsCN$XDkF*{K-bQr29z}Z&$Z_u;ryw z{Atl#0v9i_L>_~1-8+tw^wdZXh!(afGcP&;-P9v+TDd$86?I!zMdeSg?@2?bbb&e~ zSBC>VZF^}Sb!cDP^H6C?*s{p$JG~Sr2J^sDLlMgN;E*0DvQw?W4}+qjPVsqz0BKP< zs09t%57&*s^6!mToi+Uvc4C;iV)>G1z6Js^1U+-gMI=@*OfySuB%DTb@`kYu|U_P3tD5d z7cXJ3Jx|nSCYa$_TGK`%C2~kFEG@JafN3#JB8<<=A&!vnJp9>dh(U#-!bSn+SSr2P zQFl+vCl;}YDlzWCQV;^$m+m5IsGjHNS<`Y;d++_Xn!OoO)NwG<^<5D7vpr9)%ja;N zI%K&=i0yQ8xGsSkYX*wyPnE9tENPQJ>u-HHq0cgPbLUVrJujYRg4X<5rr~qx8BVcu zL6yVF`JBv9k+^u+1B6_>t0d|Y4h|-osIdKFkf^KAmtU^lBCD8bs9Rq9oTE;|VL#Zb zwDyxxm*fKKoE5iz#kc(Vw}b<%*n8)OxPK#+E8AJ&-ZKWETpZ|T;`81Iv< zeZ62XaL9h=uXVGP*T>Zm}9zDCz!9EMZnhLOsdsswM4>bDzhzu5sfV%y2o7@V` zJJSkJOCJ`cnDUsS2K7jx*F-oLQZ2pxPKtt3J8Jr}Gp!oOL8Xi3>g_NSdUoK3?KM*? ztYcmq39H5Gkd{uBVkR~t7pQ~s?PLNhDq&};sB3=$U~W72#f1*kWMfj7CX{#FLtAG|;vh>*xf4I5nt5U7YfDd4`s4eKC{K&(#B5p=dfb{Lir^e|W7qhn@4 z@#3W@Fy9>uklg;nVBbj%)CKdoF5!z8E)seBnqYK5M3)RklOW3AF71Z95qNb0jC4VA_s5 zK^uf@;WG}QN{pNA&r$SK$J&DhK`c?8@U{f)>U`0h8vcmxu zFaV0rvSJY)>0%+4UzHW(5b);`j?jh8+((^)_DR$=FCp&Eid!){HM3hIq@lB7m=-EE z7|?DxKBFf;uQmN&s3}z%y!Y_=xS+6NDbLPIL#$VsH(0SQXJ%uTz*&g(-GvgM z+ru_gDYw;l0<QRs!rX6c$kSSAx9ZmF#+Epr+_H2JrP_Sfy z^AKA!_1&6=BWp5n`}pi|AjA&Z=Pc@sLpAI{zD6teGduLaP0wv|_&|p&`5u4;$-rmZ zjy!6AVo*u7@wxw=7W~=DBOFU^9{7An(A)SkSxn{Yr9H#ps7pBTxk6Fl?a5`J?HEDO z1%CpcUtoSsz26+42R6wL z&a}ZkItF|D_P;(~{;%FOi+N%el?oyJXMlTx!nBbNhxF$hj35m9PRg9T9Nv~-rAobi z^6h^-50xBCIfcW_Cy)32e2Ke>Qc<^oy3@Zni2@XFZ0e&DK{4OlI?R0bb9G%pJX{wnS>QaxmQ-&tnl%d%;q<&O>bQ z-e+15akfGuk4i-i@dewcMHqb2qLx1NtPnfX>gF!68K1|@3_{NZ^EFd#@0o;R)&%O> z^B`5VsJ*21orA`-Pkyd(Uk*u5nO32wad)QGy|xAJA{>aO({JbkGnHv?SVTPwpUt!b zb>SsN9T}{s^DZkw&_XN+D+07_=1*fq3rAoxDg9ln*n$9tZzXL?|D{zQfcD^Sb_Tts%+4* zr&WCJe;(ThY@!ko5`5PGvhZgF@$;yJLFdm1!puI+9$pH6THv&lJCZFCl>8O69V6)3 z42GhwCsBSrAC+jP>A5s!<&X>h1U_#-G17l6{?ulVCp^JtDZk*;K&#Po{@g!!vA`)l zKd!zfxq#1Z$oZ0_5_Tz4`JDL7AQGV;vtj1a`Bx^72?nO zerfyj#dU1mPx&+bJVER4g6R2L)3*bGBEq2;l>TFJc4npfV&%^p7DW*7=`TesxfWK8 zL$>LnK}#ej5r*q(&5JjsKuAA-8lMOA3EV!CQS{rNDEb#je*AMKfj1y||4pe9%dd#! zgcwM6rqzPNlhRtwk7(>Y*ag#~lwUm0+s7yOM}-jIUIDaCYma}v^+@bvnKp4B`JTXO zr)qKk;5Vhfr!#FVA}f*vVrB+8GiJge7yJo?yo5isltWPSC!u)W32cA<5uJeYr=O{6 zjFfFY4771FVG|C)VAI;bQmNR3c!=VMw{`{N1;ui+JF6kRFn__cKuGsXO21>xvgmG4 z3qcp1zMGI?SK)BhuC;Ynbt3=!XYC&3UC@?-*Xv0wb5;VZh_V;(lh@a zM2P!5ga-vN6Vm(4AGY@(XU0s-)PpP??BkU2dF8(%`Qn`bIJwV)NPty4mY%khUtaH9 z;8f2i1chlMo&JoT9JJHd<#a2qvmM_T{yV9X-h&XdaB|I5vhs5fi-Fq5MAmzGF?r zd}9eb?}=b>e`3vZ%qNe4x)y{%W$$IM{#lE|+bnvLlU?XS zB~4hvk_+1Zyk@eA+RsfbQaY$bN(V1^2~O6GYw4J&Sz!P@gpAm$el$J;pIy3$emmv84H~7HKrS zcElpM?hnGIEbKwfBmve;$9#~?G7&)-Y=>a*;&mdCn?2tapl%2Ho(oXy=goK|rg}O)ji~nog+J@WkyPpTaS;S3>l<>#r-s8{ zhKDX7=;Pk#8d+)4*BEtj4J?Hf)gmTBkgPK^h^pOpkwZ`|*Zu^+9LcpN@6I~zK=M95 z7u%!K{*3apD1t_a4}22y^}ozgUVkr%@B(})e=65$;P&}b@u`BI#AlN~ z;(mia8KWPh;fQ9<^wN{|04lZXxCM@MWmkW%HoMcq*&?!G^=Uo2m?SHY*UO;AUC>ddt6fQ{eF z#Gk-ts|1VmL6<)LYJaM9hB(R(i-ONm{xe>V?Fl-?r$VtUf=aqS@=Yj}ufKg}!T~`J zT7$RZ^M*x%4MMCh!(Dkpohsj-k7$-dbYI*LM9_HR|@676?()U4V87I$(nWeS>K=M(6l^NYJ~OR$Udrl-q zh?598$wwoxCn)?G>4;H(&cO)6pzoyiPom;Ftm(XDYu>nNs?T{Ktk+M=i9|X1#z|Bx z8ZoNBJ(}DXXJ$!Tww4xmKXl6H$fMqb0iWDc@5O57s|GZhR< zmEBRZXGn<2bw+^txu+o=a?XlIfJ&9liV;MvGZIi*^RqQwGvRJ~8vj&m9bG zjmjY!Vh2N#3$R)Cn{l$Wh3%ygxQfJnDc9W8M0nOB1B3UUmPf58%{)gPW;)a6bD}PK zaxf~5H4mo6!Ak>7p@>1H$|pZ}e8$Y7d|}C<_ztF}^!i%?rciW?3?WZiv;eF^>`WVr zkgy9Y)+ATn9HO>6D+ZrHol>P*bb&e+{eS`d`Q+znW*7dYbju?4^B#`qIX(}PP5A|2HS;dh4nd{oQqB&h1t&jAl}~=| zu1jtXi{8ex5k%CLG(NHTWtkSybf%3(G;=#Q_4TO+&Y3otNB`NW&B34g3-J1$Ry%(s z)qVc-jRP?sy3n8LOW+tyB^HCXlK;L%eZGXi-8f%jlOHp+cJK!lGP7vx+4H4AEMdj$ zVNsx!*7`sLGyCWRccxE%?!O~JgoG8}alT}*Sq{f49Pc<^dh#ggqLgp#^y%cFP94IX ze$Di%%{5b?gF3KxAGjg8+R13Q?gETWX{p42iF^TXe6IJ}3qoFiPd|x@>qvm*{-tW` zOpT_^)br0L@p*$kV-d{^0S*Q$y?ag0jF|*j%mjmV;5d_lLX`@eTJs}*gWb(!+=IGO zmR-6APOIT^>R!uf!=sq*L572LQF}cZ(yzsz+VI5lBembgpAkfS#!Ewbg~L&I{yElEcqLxAM=5(i8AlRvlq_~%~VY0)Xu>Jtlnx2ESy%?xz1 z;%dHSp+@8$qzk6EJaQuq+4CaTIDjc1LJhQT6-i1HU%}f>#LBVIFBab?o#AjwIsg5;+ zrTWh&<M;&VqxEE>wc0H4mE=4AcZgd6y@HPy@y>uLR8D$&XHx9_>E$@ewG zv?!*%CQ)ZlY%g(U>bpLbhafHbjn9Wa_fsR@h!sAyh4T={BBZwSr`#uvUpIS%G>tJ_Z6*UUN9P@Ty2&I_fZOq=S?7cA)S0 zz>3|^1Kt`qb@CH}!nCFQvaPNfw+vP|IHSSlyxQ?LJ(=DB8wOIE@db_HpTkUy( zK|29uMZKx_d+o5|5L6aw+#7Y+8(x5Rta*;lgcv6hiY3QqlxN@)BT9c<&^bO0iW=hm zPN1(ghVo^Mzd13~UGNgTHJfcv_&SR*_$&n_xlnfZYVkP*h1QVTT2Ph}S$KV7uvGFgktS-3 z!3^`xbvDzbTY>g9EsOVOI@8*kKGXDci)>A2?`<%&pb?`2!;^#FoWx9=UF^^FqojZV z%6H(#U~M4XpZlKInF+^hyP$V;R=>-d3EbxqxPoG{;zMoWIaP*!NtKo|OSe`kJuz4+ zwV9M&Af2`s;PxqKf2LEAk*cq0iLgJjp$OYOH;wD|mDe@3Db=nrj~uwQjF~e=!KXQ7 z(KFEu>IS@PP&>f>e9SyJ`Qg4!JAt+c;czpf{4dk7B#)A?!%K1URyYoS!uAV%4nYSA zpq%NB&z)>w=u$oel`)FscTl=F644W0>Z7@#XA&Xd_+^OtVA`SQIYRc?#sGGMSnBhI zSoGFX;hk`dmZO%t!67koI3$6KMI@FCa;AbIdJ-XocL`eH9qF05Pb_2Rd3`@u33@KO zp86$0&$!Zac~%sEV$J0HGSmF2-S2)HF8(YT{&^fSqFFO9%p3r#7%AJdnVgv`0}MJV z8bY+$Yl}!MC20PvNAf*`2*-s(FmvhavS#$e%>J!-`ctn+|G8ncZF7$OK}dLNSeIM7Ak;4to)ITE&H_??szpduuLx+W0PZ%W5=vd~4^Y?$dP zS=^UL;6aG_^Bu2bo9E$VZ(pMl%=8YBPCiA*MU_!7jO-|F+98OMKG@z5M|bHI6pMIX z7l#lw0mEw%vJ{kqLx!HoxMT-nv}_#Wy7~_biUTY&hoJh~>B8XM{)9?N?MWA$lZi1{DAxbP`W~xlBLEH7;IOrn> z=MaTWwW~8X<9P*xz0h!gl^_DFTO)X0+t;sA2~b>)6u#?8<(D3;jOnvqc)p+OFmSOQ z6x59_lviT$t$Hat^(-0su&1M`Y%`QUMTml-1;L+-mr`Z&uxB`=^!6rSAGat%3`>1I z3McD7XHezc$>{*0e1DEXy`0sji3u^AXN66BX$U$(49|OvsQmHy=q_ro`4b3PV3TNO zO-Oh8P24e4A9O8s^BzLlpAe*P3mc!H-yXy}E4RpO@4exOQ7Nxm;3YfC^NJ9C^4DMh zyxVpR?r$v@Bp(RbfBX6o973+Ezdi2T9HJC-!6871(}iKa^9Tr8JYN=FaL90SVpRX( zqvZ?O4CzORkuuI9^n5<&xy`YrzA61##NsDBu}EznUaCoo5WVnqC>C8T9ZUM;A*fu} zofUY=!$C?fJ++PT_B98CpbI@t$(jqmN*V_}5tJ&~W*=B0LNXJBO=}|&(y?eXwWAJb z5qIxtv*w6V{q10gKe487mg73kEC;X?@O|;VnY!zt=VMW%Q>B_om2T{1(xn4ne!`<0 zhnP7$AA~3v>VNUgG7(~eyuKT3^lU9B&$IU~y?xsff6~eE5(bq+I*Z|u1}*ORS|zTj zu%VMn8>fpXk7#Ni(ns;oQ#qu;fYffH#^93g0mGI>2W*B)=X7DrprCcSFxV(7I&8`! zmI>vM8x)i^QBb=7+=5LUGF(^7c`;3LVW#UDEJ3B7i9v-;1B^4{`Ekloac|fFORYR+ zCSiFV(t#TmW!GZ}@iyDQuyp>lrh=i(L>BLZpxtZ|ivg14D5UnywEXpB0 zbC_8wDj3?I(9?;<5OUFn4C#lHA;|YKg!g$L5`-uiAicqWLB-OueMpq2nZ*3zkfGAM z=;B)~yfmejT#Ar=F!bjLhtfr>1TQJPFA`z6u8i@|iKQPT0+e?S3EPlZ@|t3(bcA?| zL-;-<6r@cpvzFoypyf>v=$0;F}*bXzF-0fy(x)4hV+Kao* zd~&zjD#1+U5QVqiIC!TT57gkx#QgAkkP z?*xpf^~9_NQF<&Iwg)yPeT!HeVDUTz?QenIbup8An(d0E3u0j(66G=2R5_#vA({DF zVsTPsjNZl}5rn`gdwbkN)cCwJ4ukDa40dZoVoAfpi$9Hf&75>m#w_ht1#bV*h_>0S zJQ0#>N4>EH1vyR*6ZlrEH5 z=%xBn&j2r8k|4ET!Xa9EAgJjASkhw(uN}1g1*JzhL^=6=95O0GWnhCAmvqjwijc6) zSTpdZ>uPYxj)OxGxF$d)mLaGG3VwR(7N!*i6qj zL)|`ywC#w|K0=g&^j@Y1QQ!OA278%(Gnb86HaNEDy4dZG+zi_!5uoSA4Gt)%RiZ!H zM1_~KWh1dC{BKutlCV*h1`~FQ>12$$`?0yX&ZG4S{JmB`OE}eH0Cj=1gL}U5JofM7;Bbbk9$JQ znQD;^*5|xPy#VbH6o6$-P~|)5H*5Z|#vPddW$3q5Qck{64bKBd*d&@9+)f$Kj_uEt z(sfWNT?e%x??f;tPGb4TB!7jCGDFX#mqIM82v#OOq=9 z%nOQzWAS`N*I6+sgELj_emiA2GY=y%c)?&mNLz$Pw?D^V|8UkA%#P3AK)Q7ElJ~TV z`3M@y$DgqsiO^}t!K5Juoq{Sw`0owpw+l5LRvbIyf9eFxBvs=9xwok|NJE} zTz*}69^qI#|D6E0_Hj-uRS|fI*9hU!T=-Kd2&n5c{E_m(QtFW+M2Th0OqB`1Ajn?` zTj6sK(cJv4e@QI15B4tDEInAcvTuRm`Mxh6pC@qjA2ui5=mIvr=PDHz&}NW=a@mbb z`Ce1mW+;D(5Ld}=)fX?N`_0UuXX))te$8C&Op|c{t(KmC`GAb`N1>+t#TFRK_e>04 zyt{zsTlw*MuoN>nSgvB-ywH6;C_O)ySoTlyHDULQlta-_*IgxC*PRu3$+I{VG(JxvFh;>r zrObl)obV7KnK{->h--}nU^aN89x;m#EP((!xiHuc8Ho_KiS0yk1aZ*L*1V@Byi10I zA^wCQ-z>*gb8jn@XbzRm>0&#%oGuJDj(LSmyoA6hhuol` ztcl$0{&Nd9Mu1*S>EsgZdIn2Ssb^v^u3Jh^n3gjmeVlR>Lb^-YO8DH7T*^)kslVHwu*iv}rY|85LO>T6 z#KM!4cwXaibq8!pQhnc0~g+HOZ zR~bXdMISPxA5MlK-&)4W2g_BwJM-Oc@(7>r|9{fy#otSIyCWQBOz(CX%_t9I>HQ{VE_b`%*IYI@DJXPE z1Pzr!EZJgU=Cixq(u-BQZHFK)D5Vm&z|Zb>qY|WRF;#fCLx$@L+1{xJ$zx^-zIz^m zjzvq)1wue9`_Wty;ROh}*a8nPl|SEskj`Ro@(m8L> zL!$iF&E2_~OqmMQG&2aXiCF|;=7P__rlgZDlvo^K#y0y~;8uxxl4+x- z*?yN;0Gk^KiJ2cpECZkK3r2WY?4Pd>!BC(XTPrUexN?fyM&OC~q zxebK!%Ra8O*?&pWn>)a!izx>qU9WN3ha}(8vG}h5#Z206yIn6*+Q!(O>EfkA-3_{^ zH5U#k>C0e342$|67GUs~BnpOeGXVyt3)M3gA#nQE=q^G~PoIzkMzZ4oL$TLfmfixBjm&mzRO ztG(uH5#k&Y1{;Fv@3$Z%S-iy|QHgn^9Kt+`@&Onux_C)~EPe@xXqADWMl!LqpB=RQ zZ5(20_!fjz^p@NI4DyohJY@(Q1H+PBC1c5sqYpvgnl6-B2I}hbyL|`*X_axRRM?bR zvj=+tLKZL8nn{@{s080YNJ5OjY3bSTLs})Q>Gv|sqbP4}_63I^i}wpkn~8eVRa;+< zL6DXn-?AxxGCL}o3b2ME{b{JvK18dwhS>WMLx=)Q?`3)rPVRFX>}B@NT#nHSF?wRA zgS|TgT_|iWZg4CbGfs=?xtE5Z65I%(MfExF5iS5W*8C0z|Gy!Fpk=?A&!apxVt%5V zXbuKDhmD5VyrlKW2{4}z+e;fqNc;)g_hGZoHhV9KPKo6r#NfJTIV6D_uB*6b&0m~D z>YrVChznp_M;}j;Kzj*T(mo{7T>NRC*V3cR;1wZjLZy~I1}it0e_Ym$a|iDqV+mlC)c_smr3)|BQ%m)E0dqLwwy z^De#g + +Hello from the Apple II! + + \ No newline at end of file From ae34aae60849395ecac2a6a4a1a9f3df2b3d4095 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Tue, 23 Jan 2018 15:31:34 -0800 Subject: [PATCH 34/45] Add more demo music --- src/mockingboard/startrek.seq | Bin 0 -> 5421 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/mockingboard/startrek.seq diff --git a/src/mockingboard/startrek.seq b/src/mockingboard/startrek.seq new file mode 100644 index 0000000000000000000000000000000000000000..b954233746148ed6b1f1ab1d5ae511d636faef81 GIT binary patch literal 5421 zcmZ`-%WfOT5w#y?5A3WGgFgae}!)B7g00vH8CGskdUO`?t*-KD)nQUfQ$s1+>f3SwN>O z?b-Pv+7;<6qEnIf?0gCBs&tmnsY=_=j~tE=Mv!;Wj-}H@CziIKGX#5O2=9Q8Ks!ad zMk}FtCq;+pb$AV2Bsfj*R|PwTj(xq}#q}7?6wMkg>Nw4DQM-15(goyg4{z&VoI0GM zbQ+NcyG(u`+=%y>J8(Ea#J!t#F|FgckK^Ru z)7zL<NpVuUcH(e? z(lo`i_Ahg?lMp|qteJ1o7WH&c} z;5F5jP(2p{RL>5@sY2QYj`*)ZQ>_@3Cx{`Lp-h3(lgPdX%{n}TRKeE(Je8n2EO;ds zKG3rP_AJxHdifi|P<~;hgq_GQQGxM}>7@r_p8=cUqjyfmc_s$fo{s_c-wZ8adr5%p z8LC!9{x@easrgJcK)!f6PGU?L1vMM+ye6C2)?^&Bz;MR0QF8@z6mwgR*EozZF09xD zM$Eag9tTxYz$0fJY6rl673_X{RdUU*5*h;bfgv}->kO*cSeJMk;fz^5Z0zAyH+{bp7D%hGCdN;%Snjc!}hV8ZA1!~ zp_WsR?FAxmQq)q=VRAil#yqzpUr3=ynjgg^`uv27O}bP{9HV|unY7||HF(08A904)fF8MUBUM* zmNVfhw$`>2?$?OBpMyv)_hOg_oy)8aix7@7tmb&q!^lNjIR=51@N?mM+9(bl&%F zbAu7+-~rGx=-7;$HLAD|UN$WywyjkQHJX9yO>(BV9mb9QwfpgpZ1`H4DKkX~8X zf5toliX1*j@q+cNKRu#h51U1c;AGg7O`oOXDqc7|aBR__L!RT)s>XX#S73Y+j79pk ziZ$*?DsSm6#ik#e7?^R@idk)^RZJQ>$Ucrs54=ylNbz8iH!Gt6*atYs|I7lrA)@(#ljzMzsFY6@;mS$mJdbt zD1VY-HB-51($A#_^USqK%qLFQ+K*+wupOAK{!&(Ko-9h-@_EtzSJlq32>ly+VkQ2Pg+u4noJ$KE_pOb@T*_}#%HIaDo{)(x~GY2HM$gkRZJs?xfNRw+m(6|K4;xrOGOwz6?WTDQ=e zlctw2aQ@5TCE7o&Dh3s>Z?tZsbwzJS-J+MWb!<~v<ayl2u^&QnH9V!Z literal 0 HcmV?d00001 From ec5109a6db02ee2c03fdfb682e7c21ee7da1b62f Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Tue, 23 Jan 2018 20:54:06 -0800 Subject: [PATCH 35/45] DP#3 test --- PLASMA-BLD1.PO | Bin 143360 -> 143360 bytes PLASMA-DEM1.PO | Bin 0 -> 143360 bytes PLASMA-PRE3.PO | Bin 0 -> 143360 bytes src/vmsrc/plvm802.s | 67 +++++++++++++++++++++++++------------------- 4 files changed, 38 insertions(+), 29 deletions(-) create mode 100644 PLASMA-DEM1.PO create mode 100644 PLASMA-PRE3.PO diff --git a/PLASMA-BLD1.PO b/PLASMA-BLD1.PO index d555f3570e018eacc8345471c3e5dfdc3cec4af5..c124105b1e4b009dbddf2a7883d848172a35da88 100644 GIT binary patch delta 15153 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 literal 0 HcmV?d00001 diff --git a/PLASMA-PRE3.PO b/PLASMA-PRE3.PO new file mode 100644 index 0000000000000000000000000000000000000000..c9ca83a6a577b231faec0e5559d86c711b7631c5 GIT binary patch literal 143360 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�k3#ByDvrv$G`e0P3wrU7VnYsxl5&&t4Ya`Yu(~S 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 literal 0 HcmV?d00001 diff --git a/src/vmsrc/plvm802.s b/src/vmsrc/plvm802.s index b041b39..dec5efe 100644 --- a/src/vmsrc/plvm802.s +++ b/src/vmsrc/plvm802.s @@ -1194,15 +1194,16 @@ IBRNCH TYA ; FLATTEN IP LDY #$01 JMP FETCHOP ;* +;* INDIRECT CALL TO ADDRESS (NATIVE CODE) +;* +ICAL PLA + BRA EMUSTK +;* ;* CALL INTO ABSOLUTE ADDRESS (NATIVE CODE) ;* CALL INY ;+INC_IP LDA (IP),Y INY -;* -;* INDIRECT CALL TO ADDRESS (NATIVE CODE) -;* -ICAL PLA EMUSTK STA TMP TYA ; FLATTEN IP CLC @@ -1228,14 +1229,16 @@ EMUSTK STA TMP ADC ESP ; ESP - STACK DEPTH TAY TAX - BRA + + CPX ESP + BEQ + - PLA STA ESTKL,X PLA STA ESTKH,X INX -+ CPX ESP + CPX ESP BNE - ++ !IF DEBUG { TXA TSX @@ -1278,15 +1281,16 @@ EMUSTK STA TMP TSX ; RESTORE BASELINE HWSP STX HWSP TYX - BRA + + CPX TMPL + BEQ + - DEX LDA ESTKH,X PHA LDA ESTKL,X PHA -+ CPX TMPL + CPX TMPL BNE - - CLC ; SWITCH BACK TO NATIVE MODE ++ CLC ; SWITCH BACK TO NATIVE MODE XCE +ACCMEM16 ; 16 BIT A/M LDX #>OPTBL ; MAKE SURE WE'RE INDEXING THE RIGHT TABLE @@ -1301,16 +1305,16 @@ EMUSTK STA TMP LDY #$01 JMP FETCHOP ;* +;* INDIRECT CALL TO ADDRESS (NATIVE CODE) +;* +ICALX PLA + BRA EMUSTKX +;* ;* CALL INTO ABSOLUTE ADDRESS (NATIVE CODE) ;* CALLX INY ;+INC_IP LDA (IP),Y INY - BRA EMUSTKX -;* -;* INDIRECT CALL TO ADDRESS (NATIVE CODE) -;* -ICALX PLA EMUSTKX STA TMP TYA ; FLATTEN IP CLC @@ -1334,14 +1338,16 @@ EMUSTKX STA TMP ADC ESP ; ESP - STACK DEPTH TAY TAX - BRA + + CPX ESP + BEQ + - PLA STA ESTKL,X PLA STA ESTKH,X INX -+ CPX ESP + CPX ESP BNE - ++ !IF DEBUG { TXA TSX @@ -1386,15 +1392,16 @@ EMUSTKX STA TMP TSX ; RESTORE BASELINE HWSP STX HWSP TYX - BRA + + CPX TMPL + BEQ + - DEX LDA ESTKH,X PHA LDA ESTKL,X PHA -+ CPX TMPL + CPX TMPL BNE - - CLC ; SWITCH BACK TO NATIVE MODE ++ CLC ; SWITCH BACK TO NATIVE MODE XCE +ACCMEM16 ; 16 BIT A/M LDX #>OPXTBL ; MAKE SURE WE'RE INDEXING THE RIGHT TABLE @@ -1457,14 +1464,14 @@ ENTER PEI (IFP) ; SAVE ON STACK FOR LEAVE ;* ;* LEAVE FUNCTION ;* +LEAVE INY ;+INC_IP + +ACCMEM8 ; 8 BIT A/M + LDA (IP),Y ; DEALLOCATE POOL + FRAME + BRA + LEAVEX INY ;+INC_IP +ACCMEM8 ; 8 BIT A/M LDA (IP),Y ; DEALLOCATE POOL + FRAME STA ALTRDOFF - BRA + -LEAVE INY ;+INC_IP - +ACCMEM8 ; 8 BIT A/M - LDA (IP),Y ; DEALLOCATE POOL + FRAME + STA TMPL TSC ; MOVE HW EVAL STACK TO ZP EVAL STACK EOR #$FF @@ -1483,13 +1490,14 @@ LEAVE INY ;+INC_IP ADC ESP ; ESP - STACK DEPTH TAY TAX - BRA + + CPX ESP + BEQ ++ - PLA STA ESTKL,X PLA STA ESTKH,X INX -+ CPX ESP + CPX ESP BNE - !IF DEBUG { TSX @@ -1503,7 +1511,7 @@ LEAVE INY ;+INC_IP + } TYX ; RESTORE NEW ESP - LDA TMPL ; DEALLOCATE POOL + FRAME +++ LDA TMPL ; DEALLOCATE POOL + FRAME +ACCMEM16 ; 16 BIT A/M AND #$00FF CLC @@ -1535,13 +1543,14 @@ RET +ACCMEM8 ; 8 BIT A/M ADC ESP ; ESP - STACK DEPTH TAY TAX - BRA + + CPX ESP + BEQ ++ - PLA STA ESTKL,X PLA STA ESTKH,X INX -+ CPX ESP + CPX ESP BNE - !IF DEBUG { TSX @@ -1555,7 +1564,7 @@ RET +ACCMEM8 ; 8 BIT A/M + } TYX - LDY PSR +++ LDY PSR PHY PLP RTS From 243dba457d700a316fb2faddfc81bfc07ea56a8f Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 24 Jan 2018 10:42:50 -0800 Subject: [PATCH 36/45] Ready for HW testing --- PLASMA-BLD1.PO | Bin 143360 -> 143360 bytes PLASMA-DEM1.PO | Bin 143360 -> 143360 bytes PLASMA-PRE3.PO | Bin 143360 -> 143360 bytes src/inc/sndseq.plh | 2 +- src/libsrc/sndseq.pla | 11 ++++++----- src/mkrel | 3 +++ src/samplesrc/hgr1test.pla | 34 +++++++++++++++++----------------- src/samplesrc/playseq.pla | 11 ++--------- 8 files changed, 29 insertions(+), 32 deletions(-) diff --git a/PLASMA-BLD1.PO b/PLASMA-BLD1.PO index c124105b1e4b009dbddf2a7883d848172a35da88..51d2d796e53563280eafb72415eabfe704b09203 100644 GIT binary patch delta 2682 zcmZuyYfw~W82;Xm!=7b@*Z_eAFPn-WAXiZ;NpM+Ub#LxL3vab9E390Wb|I9^r7|yR zrjo2#URd#j{b)>z?RV3d(>P624qe76X8h4OP17_@BsV35lA>lK*K9VeF0q^Igfpg^B#=Z( zsu$&HM4I3r&0@3&%qZfT7N8i1JpEOyVw3@`{@p9py4TWM#s2KDeOfCsXK+(E_SpK3SGfXrjs8!18nv7<%EhfmEMY-if zNy8yBqzDUX;f(7dY-R-OT|YClQen6=Q>$;3bq`Y<#mk&xYD3P%^sF%yfVioX@d4Gx z0A##aeJde()x+3l=+b=qxRxG+Sq0=~WYdBvV~`V|gyt7|DoBrW=BBAOF`Z(#k#Ph&~Dyf*=R3` zq|Kyaa;xH!%Qjh!(E@}T9!E86oLUaP8J0#zG-`lJLtaB1FAHZ8B?)rrNV^wD%N4do zdLO0EWgyKLS8D-RXEn;?m`svP{+x|--za-;S+azyZ>W=1!7RX9U5YmYThd@M8%@IY zi9rdIhl?`8Ji2^rc=}7Al&Ur3K&N5i8nASn-3>IX{u*vWXbfuDj*`ouy>?zSkm_YNd1TAYtZ4Ds8$)LrZd>AQb%%y z4MtuW^2!tg8*-+mudKj0zq86XIl>Dd@9A>9e?%Dv3r&aNyRc8y)#vxP8pHeVLNA04 zQ>L(ZX$hkDA#^mEDX&~sB|V%`@%Mp-Mk!tKB%Vw|XpHjHKog!?S%c3HfTxrReMo0N zQ(L#%P;YE#Y%;A`YqnTz_H_;p8Nb2hk8}k=or-EfA1qYS+JIjC)aVx($|}oJT;6Vf zuioG8?Qiord)hrNzg~o@KT4C?gy-2ND}Tn4p!9)VWOKppN~+q_O+t8ht*6|7)sn%D#}ba|xC z_BNlGP=r}gRwjeQgd)(g7!<8T(vRGT)*v01r}TR<2Mi$qo3`kaYlMgL;^qy{KG%X{ zx(C6tEOkz3XrhV{kg!HehhZX(>gc#`@>ignwn+2;iH7FUlC3W|x4Bx~+uPbbJ32bM zy1hLw`ux3pFZJ)-HSqH8SM~%3Uw!TMy>IN>f8gMohYp9GOKBAycP%*G64FxDTW=pd zc6b>_*pF!YX2u-C8XH$3Z(`@RgNGUDVbIz`wPPcxW z)78=D^Y(SO>U(@%m)q~x_j<*N>OH;rem&ON;puJ*rq7|bbkdT$d)K;m71YLVo(qYk z1RtAA*N6MH^dJmr>4M{vDdCiJ@E0VUzrZ5_cY72V{&W12`QV~>fxiNjZwB>wpulei z;J42B+tF_at$4l@U}69m6_8-!AS^~xEE!HR1CkjLP59~{R40h{_M*l<(1`v~^pAr| z^iQIHY9>wywJ|3~&>jOli(eD?^M?_}#6X;61|%~gnX8idLo%5cMP`j;S|xKxGM7aY z{_!H@CySvcF!X02`Cp)a1sL)CEA+3;r1veRbR8Hfq%?fIbAm=iuWUn(-eq4q|lx delta 19221 zcmbt+Z*W}Kb>BV+{3BUw(Y7RuQte#9FtH#P%LPDyASFP2*nJB;b9di*-!6a^LaLMq zijXLRB`JxrJ$dY(q@B9$)Mjn8PBX1(hmG6Lv=N;s(`iQi&~`l2e#xYhX+POhPsjCS zGVO;>lS~}Dzu!6czV`r7j+5?)*!S)|_x!u(oO|xMcXj)F2XBAx;J^O#@UcUM{e`Ez z-woTfLhkd}fx=LsFkCo3I`-j0;roTc$$|~@^@6z93>PZ^C-87wc&M;%Xb)Jo)2{i=S_-yOc(SljB3P2A zI@XQq4o1*j0lN8zcB3niY7TCAtMEu+`_OK%!^=Ul8D((8w+dcimZIlGO@<2NaTu%w zIk^80s@`59T0tvMc(~vV7tZY4iEgM+US8@>=HP~hz5Ru^4+89TF{j{9G{VK8+Y1sW z$?(ITS9s0ajSkZ`T=;k^YG?dG&5r=~;k~dHXWY|?`|*bW_B{&xoRB_ra&#PXdkm8` zh=b1x#%DNdMem`)xA&;|*!|D#|8>v%ulLIbfB4XyLqm^xAG!1Eza8B_H1s7e`TfH8 zcbV8*N>og2U*Y>>#gBsbp|NM0QG4k#tq!Oy6JmG)voP2-3kM2^8=bhFnk7Zf3gei&V|Q5miXwnzK71yM%WBOT7_^^7_LFTUmxD7_5+2Z zwN^bI#2MI9VPE09`*(vq<#(4dAaH#aM5l#l&afd}Eo$e87KWREtM20ZKw+%W>8B*A zt2U_q!GYaWkHwv^6LskVs?z@fgZ=g{gN>+D+L(g^x*ve*SN5u;(_Cr2*r~Yr9R4BD zy+Cw1i#_n(j}Lo8L;DUs@}WnI+uk!nKY>O3=-wy2NACXHq4HxN`RKU>sT zF73a2b!e#D!`qL&yVr;Aeqrc|{_5J`#r2;*cmAcneBtF+E^b_U_44Lx0Qi0H-P?yt z_YeQ(54@q*-_Q~NX6W8gZ|LEx*Z#`&8#mv4>ut3Dp?9z1ee}yC`%f(St-w&lCOjS) z1h}r>9TblrH;aB8)J@bjz2(5HhTX8eV2LV{p|EdxJn35 zHnp%YGd^+TgngY}SU53$WG=&LIa%$7y@0Hg-}$^)LSk0@W{$7(oV@iCL5@t1KmYvX z_%Q$+nLL-FB72I*4%IOh%ox5-u9xt>urLXJ&p{5hP1&|7+a{Vw+R`^|`=+HY)r8;n zo6*t()Q9!7S(14uSIfdHzN_Pvsf^8ffIwgBg{>ebo{ZyEmDzzY35V&R^QNP#e z_r$`Lx(VCT5V4nrZ&fKCg0|x7GJ>i(4`Z)Z&GVSbIS8C7sWde+VwdtYwFW;N=bHJ|AtI8i4AT15xxQXZoBDWoZ38EE$FVf)!7OE0IP4(7RAhL*u< zV|;rZ5pP0`#!rRIY0ND9v57jwOLcwW7ZP~fpL)r0gLSjt3fevB&GoBNa~dUiDivBv zVQlPxXZ3>$03^ov^?C^=ut+P1m~~St;;Dw1<(p$>5zls5P0c)kHHRgRnk*ZbVzC}U zBSlyfjoV+0Rss{O`BY(9n%wZH->erAVB-*dVI#y+04p1@-9l`H^H2=UDkSf92V5Tj z5-&%qhX3%~j}vD=sr6K#kS>xkm_r+r7DonDVA{2y?${EO%V|gEyB+ml=$QT@IdA!E zVXNN)doPOP>>9$^D1w1S(5FW(4v?mrsB2)pn1>GBK^#Vmy;3ZakFu%v#g&M^?IUnI zmo&38)hRXKxaZf-Vj|nk0W?mF2BHp(3*H57!Y)tE!YzybiXS%NEoTDA+vtHFSyvSc zjv_SQZ8W3RSSG&T4%RwBtw%L4Lz6Ki=yZa1<-KRuynpW@P<*;}dE=GW&8wR?FTeS+ zxwLiNTzd1$m3Pc5TW`FvarNfLMLb>H*#6SjywL>Oc}WtYmCpPI+cS>x-WJ6T(L>}<#%pwm`g8Tk8fVM zxv`#6Jy(2t>-t6ZthDy_xl!$nTQ~EAge%wCee>$o&8x3U+l`yo-+aZ~eCe$>iY74v zv2o+(>sPkcM<=UXl+vclo4cB>p;vg>yp%p(H38?Hr7W^Wb}dT=IiUDb7W-(0B+F-8lVg?&d2){(PwZ(RmHzkllUe&egovxDUwOi5o8YCllX2-;~7|ef&;9Y z1H)*Csg|IhLNxI0pCAV*x;z!4u3}s*1y8|z%l9c#<1;{!5o$kduDNyLqH1vmvsR1A z9yO}`Df&DYP7kS&nZ}j(ovO*0PO+t;I;N9dTqC`wql8yCZ#uKwbVhp(w!<}m-;n4G z;Al=*4b&MVRBWOrwI*|M>+P#Ix8TTd(abeB&xyw}2*82q?XKTBC?MvAj&uk?Vvvt^ zWK`)700TGT+<=+KYK%P^LxXl$v^l25DIjd3AqE^S`qQYW6cNijE}iOq|6$Z)Tt zft)G&lyS;j6~MPIZ(flYB+&#?Jim}40Y<=qP1`2}k}F%{*+Rn&%AiP3;FK9NFI_eo zNrw!~!jnUfZ`-Kjjk&&Y^Udp5P3a7}Xp`e5Jgg)(BIe+!1z_F0if{g9_^@UX+!C_@ zaEuT{1eVBn9tzWN{bmV6E?m5Ly=<;sKyb>b)`q~h-nfA{oorCmTw{KU;ZS%N)@d1g zCP0*+p)!xgSwpWdBSFeoazEvimQZ>l@a^BpiT+%f3UJn&(Kttk+vUB>7p~-j zI{M*PNj5|X{u!Zcr+g2LX!(GqE}4|{(02c-MI1Q8yjxD$j2sK9b9yBB4)8m`c)DKl;|3j8Fvomr-%cYcN;ySWw~;* zu3N|+!iZ^XzPxe$26uKgkh7H%l<&Os?E?uWLJa&C9yC1_GY3XG=`F=R)~$C+w_t<1cp^7=^X83G8u4}TEv(fVzo4vJEM*wP`&%eaO-})%VX2OGH=#h* z6{$AoeqvK}%OV}yZ`sgR}Y{%7VuOfEL|rz?*e;pcvfuTwSK{`(-3ylZ zfGuv9dpiQ5d>9AVYz4hqMe6{~@GJ@p*l)&h&{}LteY5Gem-_ya?t8J<^Ar4ON7z84 zxEN~Lh5K$T9hSLW7`M7jOj(f(54Lfa|=s*Dkx2W1I z>2g=j8VG?#1b(C}qHvQ+;IT7f6;x5c2lmteswb?zNVNuCsKvbCN=#amvKpSiPB+2^ z+V4eONC{m2Ss5pV77JvBBN?~xXR#{A7@bE{j96OHNoGmwZ~g5r4*i|Ki`~zkc!~0- z^Pd&P9HI)5qfR2FyPi}XQqg7lN!9V8!<}NlLWd?Gri8L6=qfFgXF^Pd>Mvng3ZU4= zLoKa-ZP~QIw+R}JuoeQ;a=`k9S{>n1+^BCv{dS$DBQ|z}2IiU76GCB9d^6ICIL+M= z(VxD>BNif#l2#x!04e%l4CSds-Kg0_Wu9e~oPd}OqIDBOg6y>fCIIZZ#HLU>q|ao2 z<{&vxDrSDWn2=BFPQ(V$(F@NA>w(Wg2Q3EDk+2W~&8Xr^XHptD3qp{T1rb7N`Go~8 z)~rx~f!QfyAIN*FqMDTFBx5>0jp4+AqOxNZLQN2%HXqG56T2M%21FBMN5@hXh$mS& z=}p8yZMFK%UWh7JP0NCbQ<)YTRnWy?*+<0^_235Qv)w}h2$dfcuW5l%o4C}Yb=tL} zB?V3t9UVroD9Vg#_C(Z)pCkQ&6l4+Q;1n!zCBm2tX-g;|?zH^nriOLc-f|xnt;VFG zkGLmi%_5i(|3T5qmijtcV-+(98xn;GyoAwOw}W`BKl=4VA}NV7Vx|r(2Hj#+74g`Y znIw#JOB&{K)YQUoqmRNEWUPfO2RlP{rUWWBAaW2iHITq0bB&Vh_ABe&Gl^*pILlap zre=#$>TC_r6|i)T0?d>5MKt15jH?F+#ksJ_a=Q zu&~yZL^8piYp!nFT0RapxD87WBm-$;9>)vAUS**t}iFNz{8~tE*^93RKi3cxz`)$#0sY?RVti>0cFTChCGu#zCJy5P7|ek z1EzzU5eWitR6L6N$HAH&ZAeG!@BRHR=|Ky$4BVpV5$boOC;$ynHhbpHh`x+CwP(hI zfDnt$AQP5ajk?0xIol%Ggi+vuS*=(Ct|?iKUTlZ{Sxc5?FmGljHBjl>8L|aV9QiaH zns$J65K#~sDr6}cn^+iQM?!-T_C)RKZz{5g)JnAnjHM-y8?G6- zv24UK6Nc^{8CoVL7GU-mrz4jFQ=)1uYda``$pl=_FTgq60BZ@H6WAPsMu{4>$KN6x z?AXQ~iM^+>Nke;BvT9P6-I6KUp@fJBg^S{PDm|u$GsHw&w4RfBmzT*z>iM7UdzjQq zlmIeL2DJ~Kw{O4im6?_9_;k8aJ>o1AO^Dp16L8JLzM|bj7hHsAybxalJE3?+8@6$! zhzYqycuhZYYct`1da3KTTGX1L#G;nS5w&m!2+<18?9#2BoO|NbP7glaQMd9)ChB1< zi4HRlToQ?vbir@=;+3n6%Yb5RMKUUSb7KSSKd_0ICu0D?)&k2F0y$2L5s*0}9c+iO zXFxNZg>c!#T4&(-^`{aZd@>MLHJZ&#BJS3~&SJmO(Ay|T96F7)QpfKt)6gUY;?9at zh*^I)&o0h`7T2`{WlXI~=mVj?4U z@JOVU8C`xDGq4=j;jE2zzs0>mqfy2Ivt0ZU#m#*HhbJ=H)RZDf+fGlR4aky4)^q|* zz??PATAuUj71nV%;6d6IbHs7?$tEk-CXWt<7jRjaZP#6F7XA>tP%9tZrq zg20di8c0t$G0y>m-2c)SEIH_N5&^B0@pTPZWJb?Cjd#I#3n1uRR=u!H~lrA7C zghNa5MAHN(5`{QDIyJKc$3W4|TON<4^J<}}Dm{eZ-6BMHR%Q|PFx!lQ85=29&OD&b z%Y>(`mH?}oMkFo8aTxulP|kB&vJ+K;6#t8-iuyz~_J0cvTRSisRX6^|2ZF7e!y zV2gu*kHrfcuE7hrL4vGS8aqCgN9DL8Z^!Hrj4>BU2|KF2gm61DM+jl77qmq24K2st{Eryq9e*%r#!j7^3qTm1^vSrNS$TtQ}TikqF}?QDBMA;!1bOmaL@y zW@P=`2q9sw?#fw3?=`{Te1qI4yN7;$<|ov90>m*F~`6MpFvRp{*Kj#Axk#fHLONhhtA4oWEH>BAg`{JK}Pa?Q!!#M z%52Tg?*$Fg5m(xi%Abhz0V?98I?K>4QBiBCfRB7KBk;ZlWsI&zT+~vRb58AFwo?z^xIfxId{@i zq?g%EDkD|3Qo(I_34WL#+~(E;h;or3hvZlpX2f*i5`$ucA(aZR=t8MQRLxN%%aN`W z-H)FNcRpYG;#a@zeJF892fS#!XTxoa*|3*7NMW(Xm+auPB7oN2WpUUE9UB&f>#!CY zh#gGEnZ`;?;ps=h8fYhqrFx`*TFFK}Q%P@zYa!R&=_MGHXm!$`w0 zGv3|59J+qtR(|=ggB#fk0SRVtNe)xWzw%GS7VhuI1zD-wvw*`0AD<07YGBGcOxYI6 zotQbsXtYww>US`$Jm3h-8dYj5BsG-v&oYYnIKdsAX2hyV&e^Q{e4N(WiKeiGtNHes zUl11>)_|eSfS9fBgy>?`QxJp{i6!$@n#WYN`ccG)(i!1l9D#3A1y&fD<&a~a>p!@MeSR;(Mjl?cQ z0-Q21V>L+_E+O-v)_D{_xOM=e0OvuQKMc`1Xu>jad!E^@RJ;hM38ss|Os#O54I^p? zO;f_pP)v1Fz;LU6+~#cvEG)snkvshD2gE`33RWk8O`NX92K}AouqHVlr;*)L8h?nb z!I=!Y6LN3eGGp@un6yT=Di%h%UgSioO;Xg8X^}C>=;4_$h;M$IH+Qz#+6A< zgvpR%7$H&0u8xj?jx^ByJVw(ci6w$-Cs9;6R*+XBAxGMJCgMGJHgp`vpvbU=l}-UJU!vLM2bfaT1}IN~i|xqnPUQQIbQc%R*_W1~;(+ zi2$^aR`{X@KUu4hO4@yavo>+tw5%-k^A-OUMpC!^0tvDwvw@RNnmm)RdN=CeXJa_# z1`86|2xU!QdTf_dZ;1)j8TXq) zws)4YA48t7r-ItfOIC_!CfBa!t?je6y_>+UumzC;lc#L!TGUU z=(dK7EfAVeK|_%Yp|dK9=VW#2#Q651-}0V*Xl{CH``OpLCuWzr4n4Jo=Mi8=-vxsm>GmTBD9`zZ@;0FPUfC#IUlGm_GYxo7#0RPse@QozQ z9!=KQu&QEHP*2!VAK*`?gBvdBm-I14e~fF6@cWYXzi@A8}<-Ix| z*QQW}Sz|+5&JYm%P=}MPFq4Ggc&({~jRf2Q=fL6|WH|XaAkM)~oNRYE1%^0fyyC2b z5h>%Xndfmo5VRnkwhUYgL;*hwsP!cS;SMSzlTh$7evkJeVm*=qDlp%RQIP2Qw7k^m zP;3>?P&ZV948R-f;hm0s6G)MRR3I@$lRnhzz+DbB7Wraj%T=B*1Aw7q6O=|qY84w| zeQO?60SeTj|Hw*aHuE2tAwCl6}78J+xWCitNNJUhcSX6^{q8}O&E9^yjZ39Nv zgYBsq+WIc>&@^$JBfsp-4Nf0H#ZD%xj#fOOzk{40k}Q`ST2>tfJVTvW98B;hfTW}! z(CYvKS2qw5C92|j1df#v3U@;J_0QlE2X~?LoE?39arM$=Otv@+rtui383jOkPQK!4 zVWdCrQOZ$j_4@iVB1}M)vkHosvb|WH1rRA%!z@|`Q%Pv<*8AeMv=ugnR{Vu9cB+Aa zj$pmYwu<~}Hu#&bdgg70)Yabj_n1Tkw&i@CFFHg;Njb^JWwz`5ANt2VQS}nF5Ew`5 zCz%S<;N=FU%FY}Y7n}6*$%EV$p8sICP5y#@yT@%A0w?SQxJk2aD~1o}6_uzusBx%c zZHgDBB{*Vu3C_IBZ^fT?_^q4bpUrK%OjTqT*bExGeE>d$^AgD~{w&`W8)bxp?>Y|1 zcrH@>#auV}|L|QhfX@nDmusB0c6Hsg9jG8f$Ax-R}9N)QqLW@kD1fnuzdLnm0? zbs+<6BV7!$ImuLQ*L;pnGqLVRxE(Cj(!?YzZjbgo-#fN_e#Lugdt$|_>hmYI-|BhG zc>Y&?wEse1+VMQLeZ23@qWyjC#@AEZrtdwreY@u^p#6}x<4f9?wqIKD4!(D|=l$To zy>p)TjYC7;z4P9|d#~E(%if`T@96Vye$E@-@0GUq-S&=PbeUh{+p&Iqj$ftiuk-8i z_r7!6n|tWqFIpVG-Z}{GSvd{k+JpQib>%VxzLlAb~?*ZG>+hu;0wqt&Q8EyQ!e7*Ob-}B}U z-21MMyIXnk-XB_Ye*`hTA@7^e?9kBudk^FLApSivbm-nQL*7@sp`X0>6FfZr{{S_l BF3JD^ diff --git a/PLASMA-DEM1.PO b/PLASMA-DEM1.PO index 0c94ba637bbfe4b48f97a853d83a776e9ce99ae9..9ecdcfb77eaf4de5ea191be318bf4ff2d2bf4d14 100644 GIT binary patch delta 1284 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 Z;r!syAIgX4-+%P8`S8|bM}IYK{%_hdm>~cF diff --git a/PLASMA-PRE3.PO b/PLASMA-PRE3.PO index c9ca83a6a577b231faec0e5559d86c711b7631c5..902ce0d9fb3710b8a41aaf39dc0ac8bb7353c08f 100644 GIT binary patch delta 14396 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 delta 13654 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 S&cs9L{|WbLTn%^C{r>IFR = $40 // Clear interrupt if yieldTime <= seqTime; func()#0; yieldTime = seqTime + yield; fin until quit - psgWrite(mbVIA1, MIXER, $FF) // Turn everything off + psgWrite(mbVIA1, MIXER, $FF) // Turn everything off psgWrite(mbVIA1, AENVAMP, $00) psgWrite(mbVIA1, BENVAMP, $00) psgWrite(mbVIA1, CENVAMP, $00) if mbVIA2 - psgWrite(mbVIA2, MIXER, $FF) + psgWrite(mbVIA2, MIXER, $FF) psgWrite(mbVIA2, AENVAMP, $00) psgWrite(mbVIA2, BENVAMP, $00) psgWrite(mbVIA2, CENVAMP, $00) @@ -580,7 +581,7 @@ def mbSequence(yield, func)#0 mbVIA1->ACR = $00 // Stop T1 countdown mbVIA1->IER = $7F // Mask all interrupts mbVIA1->IFR = $40 // Clear interrupt - setStatusReg(status)) + setStatusReg(status) end // // Sequence notes through Apple II speaker @@ -764,7 +765,7 @@ end // // Get a keystroke and convert it to upper case // -export def getKey(backgroundProc)#1 +export def musicGetKey(backgroundProc)#1 byte key while ^$C000 < 128 diff --git a/src/mkrel b/src/mkrel index b6bc1e8..8f15ac2 100755 --- a/src/mkrel +++ b/src/mkrel @@ -2,6 +2,7 @@ cp CMD#FF2000 prodos/CMD.BIN cp PLASMA.SYSTEM#FF2000 prodos/PLASMA.SYSTEM.SYS cp PLASMA16.SYSTEM#FF2000 prodos/PLASMA16.SYSTEM.SYS +rm -rf prodos/sys mkdir prodos/sys cp ARGS#FE1000 prodos/sys/ARGS.REL cp CONIO#FE1000 prodos/sys/CONIO.REL @@ -26,6 +27,7 @@ cp UTHERNET2#FE1000 prodos/sys/UTHERNET2.REL cp ../sysfiles/FP6502.CODE#060000 prodos/sys/FP6502.CODE.BIN cp ../sysfiles/ELEMS.CODE#060000 prodos/sys/ELEMS.CODE.BIN +rm -rf prodos/demos mkdir prodos/demos cp DGRTEST#FE1000 prodos/demos/DGRTEST.REL cp RPNCALC#FE1000 prodos/demos/RPNCALC.REL @@ -55,6 +57,7 @@ cp PLAYSEQ#FE1000 prodos/demos/music/PLAYSEQ.REL cp mockingboard/ultima3.seq prodos/demos/music/ULTIMA3.SEQ.BIN cp mockingboard/startrek.seq prodos/demos/music/STARTREK.SEQ.BIN +rm -rf prodos/bld mkdir prodos/bld cp PLASM#FE1000 prodos/bld/PLASM.REL cp CODEOPT#FE1000 prodos/bld/CODEOPT.REL diff --git a/src/samplesrc/hgr1test.pla b/src/samplesrc/hgr1test.pla index f7ead33..41efef9 100644 --- a/src/samplesrc/hgr1test.pla +++ b/src/samplesrc/hgr1test.pla @@ -1,24 +1,24 @@ include "inc/cmdsys.plh" -sysflags reshgr1 // Reserve HGR page 1 +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 +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 @@ -45,7 +45,7 @@ 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($2000, 0, $2000) // Clear HGR page 1 +memset(hgr1, 0, $2000) // Clear HGR page 1 ^showpage1 ^showfull ^showhires diff --git a/src/samplesrc/playseq.pla b/src/samplesrc/playseq.pla index c602b41..5f502be 100644 --- a/src/samplesrc/playseq.pla +++ b/src/samplesrc/playseq.pla @@ -3,19 +3,13 @@ include "inc/args.plh" include "inc/fileio.plh" include "inc/sndseq.plh" -/////////////////////////////////////////////////////////////////////////////// // // These are utility sequences/routines needed to test the music sequencer code. // word arg word ref -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// // -// More utility routines to test the getKey routine -// -// Sample background process +// Sample background process to show it's working // def backgroundProc#0 ^$0400++ @@ -28,7 +22,7 @@ if ^arg fileio:read(ref, heapmark(), heapavail()) fileio:close(ref) musicPlay(heapmark(), TRUE) - getKey(@backgroundProc) + musicGetKey(@backgroundProc) musicStop else puts("File not found.\n") @@ -36,4 +30,3 @@ if ^arg fin done -//////////////////////////////////////////////////////////////////////////////// From 115c11d57b9cd1c5bd48e7229c276cb576199a25 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 24 Jan 2018 11:52:05 -0800 Subject: [PATCH 37/45] Turns out you cannot set emulation mode from native mode with PLP --- src/vmsrc/plvm802.s | 46 ++++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/src/vmsrc/plvm802.s b/src/vmsrc/plvm802.s index dec5efe..5e37e75 100644 --- a/src/vmsrc/plvm802.s +++ b/src/vmsrc/plvm802.s @@ -1141,11 +1141,11 @@ NOBRNCH INY ;+INC_IP BMI FIXNEXT JMP NEXTOP FIXNEXT TYA - CLC + SEC ADC IP STA IP LDY #$00 - JMP NEXTOP + JMP FETCHOP BRFLS PLA BNE NOBRNCH BRNCH TYA ; FLATTEN IP @@ -1268,7 +1268,6 @@ EMUSTK STA TMP STA IPL PLA STA IPH - STX TMPL !IF DEBUG { TXA EOR #$FF @@ -1278,11 +1277,12 @@ EMUSTK STA TMP ADC #$80+'0' STA $7D0+32 } + STX TMPL TSX ; RESTORE BASELINE HWSP STX HWSP - TYX - CPX TMPL + CPY TMPL BEQ + + TYX - DEX LDA ESTKH,X PHA @@ -1320,7 +1320,9 @@ EMUSTKX STA TMP CLC ADC IP STA IP - +ACCMEM8 ; 8 BIT A/M + SEC ; SWITCH TO EMULATION MODE + XCE + !AS TSC ; MOVE HW EVAL STACK TO ZP EVAL STACK EOR #$FF SEC @@ -1379,7 +1381,6 @@ EMUSTKX STA TMP STA IPL PLA STA IPH - STX TMPL !IF DEBUG { TXA EOR #$FF @@ -1389,11 +1390,12 @@ EMUSTKX STA TMP ADC #$80+'0' STA $7D0+32 } + STX TMPL TSX ; RESTORE BASELINE HWSP STX HWSP - TYX - CPX TMPL + CPY TMPL BEQ + + TYX - DEX LDA ESTKH,X PHA @@ -1488,10 +1490,10 @@ LEAVEX INY ;+INC_IP EOR #$FF SEC ADC ESP ; ESP - STACK DEPTH - TAY TAX CPX ESP BEQ ++ + TAY - PLA STA ESTKL,X PLA @@ -1519,13 +1521,19 @@ LEAVEX INY ;+INC_IP STA PP PLA ; RESTORE PREVIOUS FRAME STA IFP - LDY PSR - PHY + SEC ; SWITCH TO EMULATION MODE + XCE + !AS + LDA PSR + PHA PLP RTS ; RETX STX ALTRDOFF -RET +ACCMEM8 ; 8 BIT A/M +RET SEC ; SWITCH TO EMULATION MODE + XCE + !AS + ;+ACCMEM8 ; 8 BIT A/M TSC ; MOVE HW EVAL STACK TO ZP EVAL STACK EOR #$FF SEC @@ -1541,10 +1549,10 @@ RET +ACCMEM8 ; 8 BIT A/M EOR #$FF SEC ADC ESP ; ESP - STACK DEPTH - TAY TAX CPX ESP BEQ ++ + TAY - PLA STA ESTKL,X PLA @@ -1564,8 +1572,8 @@ RET +ACCMEM8 ; 8 BIT A/M + } TYX -++ LDY PSR - PHY +++ LDA PSR + PHA PLP RTS !IF DEBUG { @@ -1741,9 +1749,9 @@ STEP STX TMPL TSX CMP #$10 BCC DBGKEY -; LDX TMPL -; CPX #$54 ; FORCE PAUSE AT 'CALL' -; BEQ DBGKEY + LDX TMPL + CPX #$00 ; FORCE PAUSE AT 'ZERO' + BEQ DBGKEY - LDX $C000 CPX #$9B BNE + From c2ee0a04ab1368ec8e58f15b43bcd1f05198eeca Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 24 Jan 2018 13:35:00 -0800 Subject: [PATCH 38/45] Last of the VM opts. For now --- src/makefile | 2 +- src/vmsrc/cmd.pla | 1 - src/vmsrc/plvm01.s | 2 +- src/vmsrc/plvm02.s | 7 ++++++- src/vmsrc/plvm802.s | 14 ++++++++++---- src/vmsrc/plvmzp.inc | 5 +++-- src/vmsrc/soscmd.pla | 1 - 7 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/makefile b/src/makefile index 787ac0e..fc46ea8 100755 --- a/src/makefile +++ b/src/makefile @@ -5,7 +5,7 @@ PLVM01 = A1PLASMA\#060280 PLVM02 = PLASMA.SYSTEM\#FF2000 PLVM802 = PLASMA16.SYSTEM\#FF2000 PLVM03 = SOS.INTERP\#050000 -CMD = CMD\#FF2000 +CMD = CMD\#061000 ED = ED\#FE1000 SB = SB\#FF2000 ROD = ROD\#FE1000 diff --git a/src/vmsrc/cmd.pla b/src/vmsrc/cmd.pla index 5265b72..76c6e58 100755 --- a/src/vmsrc/cmd.pla +++ b/src/vmsrc/cmd.pla @@ -193,7 +193,6 @@ REGVALS = SRC STY ESTKH,X PLP RTS -JMPTMP JMP (TMP) end // // CALL LOADED SYSTEM PROGRAM diff --git a/src/vmsrc/plvm01.s b/src/vmsrc/plvm01.s index 6faf1e1..9023221 100644 --- a/src/vmsrc/plvm01.s +++ b/src/vmsrc/plvm01.s @@ -908,7 +908,7 @@ CALLADR JSR $FFFF ;* ;* JUMP INDIRECT TRHOUGH TMP ;* -JMPTMP JMP (TMP) +;JMPTMP JMP (TMP) ;* ;* ENTER FUNCTION WITH FRAME SIZE AND PARAM COUNT ;* diff --git a/src/vmsrc/plvm02.s b/src/vmsrc/plvm02.s index 3951b7a..ee3c912 100755 --- a/src/vmsrc/plvm02.s +++ b/src/vmsrc/plvm02.s @@ -263,6 +263,11 @@ CMDENTRY = * DEY BPL - ; +; SET JMPTMP OPCODE +; + LDA #$4C + STA JMPTMP +; ; INSTALL PAGE 3 VECTORS ; LDY #$12 @@ -1428,7 +1433,7 @@ ICALX LDA ESTKL,X ;* ;* JUMP INDIRECT TRHOUGH TMP ;* -JMPTMP JMP (TMP) +;JMPTMP JMP (TMP) ;* ;* ENTER FUNCTION WITH FRAME SIZE AND PARAM COUNT ;* diff --git a/src/vmsrc/plvm802.s b/src/vmsrc/plvm802.s index 5e37e75..c1d10a7 100644 --- a/src/vmsrc/plvm802.s +++ b/src/vmsrc/plvm802.s @@ -361,6 +361,11 @@ CMDENTRY = * DEY BPL - ; +; SET JMPTMP OPCODE +; + LDA #$4C + STA JMPTMP +; ; INSTALL PAGE 3 VECTORS ; LDY #$12 @@ -1420,7 +1425,7 @@ EMUSTKX STA TMP ;* ;* JUMP INDIRECT THROUGH TMP ;* -JMPTMP JMP (TMP) +;JMPTMP JMP (TMP) ;* ;* ENTER FUNCTION WITH FRAME SIZE AND PARAM COUNT ;* @@ -1513,9 +1518,9 @@ LEAVEX INY ;+INC_IP + } TYX ; RESTORE NEW ESP -++ LDA TMPL ; DEALLOCATE POOL + FRAME - +ACCMEM16 ; 16 BIT A/M - AND #$00FF +++ +ACCMEM16 ; 16 BIT A/M + LDY TMPL ; DEALLOCATE POOL + FRAME + TYA CLC ADC IFP STA PP @@ -1528,6 +1533,7 @@ LEAVEX INY ;+INC_IP PHA PLP RTS + !AL ; RETX STX ALTRDOFF RET SEC ; SWITCH TO EMULATION MODE diff --git a/src/vmsrc/plvmzp.inc b/src/vmsrc/plvmzp.inc index e87f327..9517eeb 100755 --- a/src/vmsrc/plvmzp.inc +++ b/src/vmsrc/plvmzp.inc @@ -9,7 +9,7 @@ SRCH = SRC+1 DST = SRC+2 DSTL = DST DSTH = DST+1 -ESGUARD = $BE +ESGUARD = $BE ESTKSZ = $20 ESTK = $C0 ESTKH = ESTK @@ -23,6 +23,7 @@ PPL = PP PPH = PP+1 IPY = PP+2 ESP = IPY+1 -TMP = ESP+1 +JMPTMP = ESP+1 +TMP = JMPTMP+1 TMPL = TMP TMPH = TMP+1 diff --git a/src/vmsrc/soscmd.pla b/src/vmsrc/soscmd.pla index 2a9d18a..1beed56 100755 --- a/src/vmsrc/soscmd.pla +++ b/src/vmsrc/soscmd.pla @@ -177,7 +177,6 @@ REGVALS = SRC STY ESTKH,X PLP RTS -JMPTMP JMP (TMP) end // // SET MEMORY TO VALUE From b0535cd9721512e35062b1ef0729b7fb6578af39 Mon Sep 17 00:00:00 2001 From: Dave Schmenk Date: Wed, 24 Jan 2018 13:51:11 -0800 Subject: [PATCH 39/45] Rebuild image --- PLASMA-PRE3.PO | Bin 143360 -> 143360 bytes src/mkrel | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/PLASMA-PRE3.PO b/PLASMA-PRE3.PO index 902ce0d9fb3710b8a41aaf39dc0ac8bb7353c08f..f6494ac0f6d8d14fb42dbdd59b8efd9bf323c14b 100644 GIT binary patch delta 4206 zcma(Tdr%W+{`)oo0)lK313@0H7$a^YhFV*Sp0z48(iNg?9c!;GD(*$jQ}0@-W1W$< zu7^&wU<#|$YKnvtuMZ>Uta_Dbsb!efE?TFa-rRU9d@E{;sC|qrx!;C2UT2y=_WOSC z_xDTbWnJlI-N9Hbp5mspc6!qY!?H#h#)Y>^duJzHAW#vCviB<8E^RidD7buSu;eJmRiTkHf%;b)P3fGC4d*=XI z2@I71Z-@PS4=SglJS?PcfYjhHy@)yDy(%i7{kL2v&-RkfE+72eHY(sF+cbgJF4?kw z5D-%)-|iEZr+QEyDRVgyNj+Mwh)TnqxN+D(ntffOvgw)!`AAEp-0UOnH1h;g9~$Ha zQHsnT&g!FhkYBDK&Hg|Isl8@@oBIxdrpgoQr_nFJb^;<%RsSD$H=p1!f)o3f-w_ob z0gt-C>~h5&F*<)^AKpvW%3_ySSsM`V^yuzYwbQ)3%i+DV0y&s={Ozy9#9>UebG*t5giruM+9KP;eomkQE zOQJa^8X+C}bV7_eCOY@nrIrzsV){qO?OdAl@E|w?S>`xqI|q$acNWs3*R`Qp91zkBIM z0A!%?InDxp!65H8K~Oh_1=aA&veu6~0}kt7C}&(_HAnaJ%k+m$-L*K4l7F z5T4i>Mz)0oDy-YIfx=G^Juy}!KC6nYuomX-KN$ZBVkUNqA=cP1(h&SSmWoh00C1aH z9*!dB6*~JLDo=vW`7L9?)=MoDMk(z|U7J_2pFMx7{7hOqX(wLN@L|iE*@GjOCXU2I zQXx43F|>da3Y>GD`3w4M(fu~Wni)1UrP7`UV5}d^f(?ScXL3lH@B9# zdD;EOK)U-QsQlewm6x(&hdI6k5YdA>&yA^9s%V^`A+(kfQneU%s zT%*OV&27gvchtz6zxSZNjii!1xB-`mU9NueuM&@3+JdK0h8y(J8xO85bJnnh^{<|V z_1l+~+hLe<unGL~Yt<3$j}xeKvU@pkNpfL9bng%j!McAPerbjC%MmH({1`-uHi zQ?9wH$+VI(`A+S%LgwRhULsL%;m0wNroV-6O;guO<`rf;6*xq;YXWDxWM)4AJ{5p1 zGeTV~io;7BrM5nvQ_RF5g3ThW`49_IOF4c%i|o9@93rO}M|0mEI79~SJ3+FC4oU~m zA$`)43cPYUab00{fPAxE0}8mJZ$eMIYX=#MxWeqiA+|m%Dkw$nz$+p%mv@O>YUQL? zci=^_M19@GuFU(><_0sDcSujWabn)!#jt);8>|x84Vwv+y@_;2A8+vo9DdnxjmY=Z z!iQQxT{EsyEw}^S_Mpx&GY0J%2<|s%JqHb@YW?~$*p>e7#!o&+dYsHvU2QvXt*tX= zzpGMqRR)x6ZSuY2r3MWK9 zmjdq#{34`TRrue}R~uNm%8*Dm8SM1;hN*O?fuYT&EZS#yf{rlGp|2Vj(_7>ILSHg1 zqYL6T&=qlI^p~a`^a=eg`nKLfFErNC>BjeIm+=ri%gE7(;tS|A@gLJ0ji1o#rB@|9 zHHG+_;O~>{INa(#=kT9Z;J3N$fD8W4sask)BjJPu064_J_sm_*%AbSqe(2!+h&(LU z?ZlL%sm2#^oAjS*Y#&R2so589+u3N>Fm1-jQs&k#O+>zFD-9@x{s8l%H2EETLDy!K zBYfdZn-sen3()H&yCDTcs@jcTolJbXwWrRXERPlyIT8M@wH`Eil?q*%msIGy;VZOa zc=@sR2>Bnq|J0O~-FB+Sw=gY6D!G41ASTIDzsqTf}lxs3JCP16#`1Nmo5MH~+3NFA){7{F^2_ zdYKhc`ITmr!|9MKPfsuYSx9|2%?9?Ul2m6)P>5#3!lU_1rd25=3=)_%MQok{Y=x}$ zD&6oN9y=8{;)GOz;&1DPxDtb45Gbm|P{axb8>0C-Qwb$dD3?=$J%$A&#PO@8v+v<~ zxK?6n@FU3?X1icvwN#14c{wOp3c0yRFbkuFaKXYKkp5hQnb_O$lrtI$w4kGe6cG2+ zK>oH!jWswvKHbQTL}0duGzwfu6AZv}s|F_<{%C;U20~2YE2N}-*bFuouA-q&a=7uR z=pnVWMy{W)ck18-mihbe;#tsp+EC8nWNE5I>-;)sUmU^6nnm-lfC{0}(xA&A-*zWt zhGIYGIg=flNUf6rPM36RA5O$|Qe-WD3O7mfYw;8VjJ~1BpRkY zs0mc}WG%KpU$ocaTsShk_$lgmlH2DsTOqrsaHN3NfW_lUMbu&qID*z)Xhdo`ZHpQa zYvxZ#AA51iM(_x@G|B20nuOw>MMcp5%nL!a9vXf{vY_FzVVZ2ElVnciqr$dL6IE} zfLMxJ%CC-BZ(3@7uHN}g5Zb-R^>l5)vjvl(>+OJAA4Xe8(CZ^;YcvgUZ-}PR9L|hf z(JDfn0@Jz?G^A^x$?hDD(xc{O&tq~HWM^kt)RKK^;yYD05Jch%V(v7u1u>tI%wILK z^JnM~@7FuGB6jwS=n&zriFW6!h;_~wse7J~YFO_-FJgLX*r#q}cgIdMJo90)@uhuC{9eN)O9kups0Yz>pr*DQ6@~ lr}CffX)o&qI@E6fLCowiKEfDk#3S~@_yRr>b^zZO{|9@MVP^mU delta 3911 zcma)8eNYrf7Vn<@U|Cm~on>M9bi@U5Ty^m)#u($NAd(SQomlGS0}fO#!Cq3U-u-tACl;0f+(^|(it z=tpi*Xu_gpi_x%8dmic0O!|Qst!QYxrEUwyoo;_bzNX-67-A0(lupNIsKFE)qqER`iR8t#?h9@(|@6B zen7zXFsHwwYh)EHS=4-(rr7iKv^)>iZTo3?=CN9O&mkJ9_Jg#X3iJ7Tx0RWQk2Uhl z3)t<6RJ)r^tHDF*>Yv>SQO`vZf6LNdSFiz9bz}xb;(k3UeLiso{eekku1;FR1}~9L ze+wNRf>k@|l-1^ru9WDG*)8Q2cT-7f&`U1M-r$`;MYs#rcVriF-;H9Yb)E?EU5LGN zDdZ(pAW#+XcG@rZvobp?G=1uZwi>g{&taZ;zjXz__(z3KUgRZTTs!gj9xC7?dsKmr zZrOTd7%{e7{&5g2&+?$btvMTri!`7OL07P`Cwc;ANSm+Q72J86A{Am)qhPm2!;&*bbTGP~jg07i(kR&6^$8=KUN?#^A4MNu zKX|CVDx>zMMR-z|hV0PW*{)RVbzj*m<#g}OWJ}+tfpndbA;U||S zMc@&kkQ~4mnZSuF9ZMa#D<0(H{ysSC9L>m(N(UdpMJu4CxetPL|1E^kqj(hV)(~zW zw$`ON84rvB`u=gq{OwVhm*z%}a(o>y48tqWjj5NaX&kE}bwo;_@jNv-P)ANZP2<9( zaMIAb5iRXXA*U`(#dntMfXu)Jj{O(2H|i=$c|%wwX;4=Zzucx!+I}h|>--m?%g!pI z`z>2LhD!#9OAZ(Gj}RNFFciw$b)zZZ=j1Nj=F;s9Z))*(C`+<4c(kEcS9wB}Lv2WnjaEQNNVWh%0aF%rPeOx3Zy@?a0$ByAhDf>QYD@(eRmv3MDYb*^%7X6S8>5LD&`P_|DVoASnwgS0vBE_e5`@zcH_;S4D59_eGb}vUxAvVyvNW z8$I+IQ$3w-dY|58I!R}kc-kMclJ1E4hhNF6@?Q+W zx9i4HC;YvnvB!*@Cd=-bJuMc4R zcmhIgKCNwkvt7l8OyOnhzkd0g$hT}|fl!`5z}}N=Z{aJtkVy{nY1xoucpHo3NeJG! zFnGnZ$~{V}+T^=k@t~z`65XZsX}=(n`)&O4G~&~3J$t#O!r%(Z@$l!;al-5kR_e;V zq*CYAZdALp6(5r@`NM&q7U}U?JOS5A>uPb7A>J$^POsmHyD{pjV!Lf*(Nh~krxNZHT=VL(tZ`&$4e56};p1)yS}8SK7&2tSK&OZN`p zB$(nnIBv?^sA4rg1&L}KG6+AJinTcjhw?WxiXYT&j7VdJnU+<>G^9C`PeBEfc|B}zTW)mdU>5dCIq%}N z;kAsY?oW&FT|6$%A7ghwj3};E$Ti!c&XkNXFmIA>zKi2=gQTs)OK_`{Q-^0Ta3wGW zS?Z!JGyOD&*TboDI`dFJ3~ONpSnTmK_jhlouhQ%_0)c zBot6g6`D+Tn1JFaDqq+VqpZ}_wrr#0t6r%6elMr0SFTw(4O+kstZf=P zbqu{Nj7~MsaK!Bf8ZG86$Z1d*N=uka$IuY5Rc5;*4o%fB%UH%{uE@xkYgMu)n}r_5 z4FoMuml5ZfAEA)kIU!dndk;^| zg(`47hPYJ<;*ofV9dT3ULy$n#?nFm2;wI0xAmJ&a!q6rP`Xsxs+6b|CgrUBkw=1O@ Xi>7KaR;*C``mhOWs8gDw_@3*(0Fk{q diff --git a/src/mkrel b/src/mkrel index 8f15ac2..cc25938 100755 --- a/src/mkrel +++ b/src/mkrel @@ -1,4 +1,4 @@ -cp CMD#FF2000 prodos/CMD.BIN +cp CMD#061000 prodos/CMD.BIN cp PLASMA.SYSTEM#FF2000 prodos/PLASMA.SYSTEM.SYS cp PLASMA16.SYSTEM#FF2000 prodos/PLASMA16.SYSTEM.SYS From 5769cf67be82100c434b9b2f8f4b977239d06033 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 24 Jan 2018 18:08:18 -0800 Subject: [PATCH 40/45] Fix TCP/IP bitrot and last dataseg zero length symbol overlap with code seg --- src/libsrc/dhcp.pla | 40 ++++++++++++++++------------------------ src/libsrc/etherip.pla | 20 ++++++++++---------- src/libsrc/inet.pla | 4 ++-- src/libsrc/uthernet.pla | 28 ++++++++++++++-------------- src/samplesrc/httpd.pla | 9 +-------- src/toolsrc/codegen.c | 6 ++++++ src/toolsrc/codegen.pla | 6 ++++++ src/toolsrc/parse.pla | 1 + src/toolsrc/plasm.pla | 2 +- 9 files changed, 57 insertions(+), 59 deletions(-) diff --git a/src/libsrc/dhcp.pla b/src/libsrc/dhcp.pla index 69f0ecf..1a4f32f 100644 --- a/src/libsrc/dhcp.pla +++ b/src/libsrc/dhcp.pla @@ -87,22 +87,14 @@ byte[] endDHCP // // DEBUG // -//byte boundstr = "Apple II bound to:\n" -//byte dnsstr = "DNS: " -//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 -// puti(ipptr->[i]) -//end +def putip(ipptr)#0 + byte i + + for i = 0 to 2 + puti(ipptr->[i]); putc('.') + next + puti(ipptr->[i]) +end //def dumpbytes(buf, len) // word i // @@ -132,13 +124,13 @@ def parseopts(opts, match) i = 0 while opts->[i] <> $FF and i < 64 - while !opts->[i] and i < 64 - i = i + 1 - loop + while !opts->[i] and i < 64 + i++ + loop if opts->[i] == match - return i - fin - i = i + opts->[i + 1] + 2 + return i + fin + i = i + opts->[i + 1] + 2 loop return -1 end @@ -224,7 +216,7 @@ repeat until retry > 4 or optsOP.2 == DHCP_ACK iNet:closeUDP(portDHCP) iNet:setInterfaceIP(@localip, @localnet, @localgw) -//puts(@boundstr);putip(@localip);putc('/');putip(@localnet);putln +puts("Apple II bound to:\n");putip(@localip);putc('/');putip(@localnet);putln iNet:setDNS(@localdns) -//puts(@dnsstr);putip(@localdns);putln +//puts("DNS: ");putip(@localdns);putln done diff --git a/src/libsrc/etherip.pla b/src/libsrc/etherip.pla index 39432e8..43c1cde 100644 --- a/src/libsrc/etherip.pla +++ b/src/libsrc/etherip.pla @@ -198,15 +198,15 @@ asm sum1(prevsum, buf, len) STA ESTKL,X BEQ + !BYTE $A9 -- CLC +- CLC INC ESTKH,X -+ BCS - ++ BCS - CHKLP LDA (SRC),Y PHA INY BNE + INC SRCH -+ LDA (SRC),Y ++ LDA (SRC),Y ADC ESTKH+2,X STA ESTKH+2,X PLA @@ -215,7 +215,7 @@ CHKLP LDA (SRC),Y INY BNE + INC SRCH -+ DEC ESTKL,X ++ DEC ESTKL,X BNE CHKLP DEC ESTKH,X BNE CHKLP @@ -224,7 +224,7 @@ CHKLP LDA (SRC),Y BNE + INC ESTKL+2,X BEQ - -+ INX ++ INX INX RTS end @@ -255,10 +255,10 @@ def etherSendIP(ipdst, proto, seglist, size) memcpy(@hdr.ip_dst, ipdst, IP4ADR_SIZE) retry = 0 while hdr:ip_dst:0 <> remoteip:0 and hdr:ip_dst:2 <> remoteip:2 - if retry >= 3 + if retry >= 3 return -1 // ARP failed fin - retry = retry + 1 + retry++ memset(@dstMAC, MAC_BROADCAST, MAC_SIZE) memset(@remoteha, 0, MAC_SIZE) memcpy(@remoteip, @hdr.ip_dst, IP4ADR_SIZE) @@ -560,13 +560,13 @@ end // // Initialize the driver interface // -export def setEtherDriver(MAC, getlen, readframe, setlen, writeframe)#0 +export def setEtherDriver(MAC, getlen, readfrm, setlen, writefrm)#0 memcpy(@myMAC, MAC, MAC_SIZE) memcpy(@localha, MAC, MAC_SIZE) getFrameLen = getlen - readFrame = readframe + readFrame = readfrm setFrameLen = setlen - writeFrame = writeframe + writeFrame = writefrm end // // Set the local IP addresses diff --git a/src/libsrc/inet.pla b/src/libsrc/inet.pla index db0f59f..b25e0ed 100644 --- a/src/libsrc/inet.pla +++ b/src/libsrc/inet.pla @@ -211,7 +211,7 @@ def iNetInit // while ^driver //puts(driver);putln - if modexec(driver) >= 0 + if cmdsys:modexec(driver) >= 0 break fin driver = driver + ^driver + 1 @@ -222,7 +222,7 @@ def iNetInit // // Get an IP address // - modexec("DHCP") + cmdsys:modexec("DHCP") iNet:resolveIP = @iNetResolve return @iNet end diff --git a/src/libsrc/uthernet.pla b/src/libsrc/uthernet.pla index a21eff3..aa5ba21 100644 --- a/src/libsrc/uthernet.pla +++ b/src/libsrc/uthernet.pla @@ -6,7 +6,7 @@ include "inc/cmdsys.plh" // Include dependency on S/W IP stack // import etherip - predef setEtherDriver(MAC, getlen, readframe, setlen, writeframe)#0 + predef setEtherDriver(MAC, getlen, readfrm, setlen, writefrm)#0 end // // Uthernet register offsets @@ -100,9 +100,9 @@ asm pokefrm(buf, len) STA ESTKL,X BEQ + !BYTE $A9 -- CLC +- CLC INC ESTKH,X -+ BCS - ++ BCS - POKELP LDA (SRC),Y end asm _pokefrml @@ -114,8 +114,8 @@ asm _pokefrmh STA $C000 INY BNE + - INC SRCH -+ DEC ESTKL,X + INC SRCH ++ DEC ESTKL,X BNE POKELP DEC ESTKH,X BNE POKELP @@ -137,24 +137,24 @@ asm peekfrm(buf, len) ROR ADC #$00 STA ESTKL,X - BEQ + - !BYTE $A9 -- CLC - INC ESTKH,X -+ BCS - + BEQ + + !BYTE $A9 +- CLC + INC ESTKH,X ++ BCS - end asm _peekfrml -PEEKLP LDA $C000 +PEEKLP LDA $C000 STA (DST),Y INY end asm _peekfrmh + LDA $C000 - STA (DST),Y + STA (DST),Y INY BNE + - INC DSTH -+ DEC ESTKL,X + INC DSTH ++ DEC ESTKL,X BNE PEEKLP DEC ESTKH,X BNE PEEKLP diff --git a/src/samplesrc/httpd.pla b/src/samplesrc/httpd.pla index 4e8c2ca..ab73a90 100644 --- a/src/samplesrc/httpd.pla +++ b/src/samplesrc/httpd.pla @@ -40,12 +40,6 @@ byte mimeOctetStream = "application/octet-stream" // // DEBUG // -def putb(hexb)#0 - call($FDDA, hexb, 0, 0, 0) -end -def puth(hex)#0 - call($F941, hex >> 8, hex, 0, 0) -end def putip(ipptr)#0 byte i @@ -203,12 +197,11 @@ if !iNet:initIP() return -1 fin puts(@hello) -getpfx(@prefix) +fileio:getpfx(@prefix) // // Alloc aligned file/io buffers // filebuff = heapallocalign(1024, 8, 0) -//iobuff = heapallocalign(1024, 8, 0) // // Service IP // diff --git a/src/toolsrc/codegen.c b/src/toolsrc/codegen.c index 06b8791..2a7459e 100755 --- a/src/toolsrc/codegen.c +++ b/src/toolsrc/codegen.c @@ -17,6 +17,7 @@ static int defs = 0; static int asmdefs = 0; static int codetags = 1; // Fix check for break_tag and cont_tag static int fixups = 0; +static int lastglobalsize = 0; static char idconst_name[1024][ID_LEN+1]; static int idconst_value[1024]; static char idglobal_name[1024][ID_LEN+1]; @@ -465,7 +466,11 @@ void emit_sysflags(int val) void emit_bytecode_seg(void) { if ((outflags & MODULE) && !(outflags & BYTECODE_SEG)) + { + if (lastglobalsize == 0) // Pad a byte if last label is at end of data segment + printf("\t%s\t$00\t\t\t; PAD BYTE\n", DB); printf("_SUBSEG%c\t\t\t\t; BYTECODE STARTS\n", LBL); + } outflags |= BYTECODE_SEG; } void emit_comment(char *s) @@ -482,6 +487,7 @@ void emit_idlocal(char *name, int value) } void emit_idglobal(int tag, int size, char *name) { + lastglobalsize = size; if (size == 0) printf("_D%03d%c\t\t\t\t\t; %s\n", tag, LBL, name); else diff --git a/src/toolsrc/codegen.pla b/src/toolsrc/codegen.pla index bea16d4..ecda769 100644 --- a/src/toolsrc/codegen.pla +++ b/src/toolsrc/codegen.pla @@ -125,6 +125,11 @@ def emit_data(vartype, consttype, constval, constsize) fin return size end +def emit_codeseg#0 + if lastglobalsize == 0 + emit_byte($00) // Pad byte between last data tag and code seg + fin +end def emit_const(cval)#0 emit_pending_seq if cval == $0000 // ZERO @@ -421,6 +426,7 @@ def new_iddata(nameptr, len, type, size)#0 else lastglobal=>idval = new_tag(WORD_FIXUP)//datasize emit_tag(lastglobal=>idval) + lastglobalsize = size if size emit_fill(size) datasize = datasize + size diff --git a/src/toolsrc/parse.pla b/src/toolsrc/parse.pla index ce9644b..9ebbc89 100644 --- a/src/toolsrc/parse.pla +++ b/src/toolsrc/parse.pla @@ -1225,6 +1225,7 @@ def parse_module#0 // while parse_mods; nextln; loop while parse_vars(GLOBAL_TYPE); nextln; loop + emit_codeseg while parse_defs; nextln; loop entrypoint = codeptr prevstmnt = 0 diff --git a/src/toolsrc/plasm.pla b/src/toolsrc/plasm.pla index 5372e69..17b2fe3 100644 --- a/src/toolsrc/plasm.pla +++ b/src/toolsrc/plasm.pla @@ -246,7 +246,7 @@ word fixup_tag, fixup_addr word tag_addr, tag_type word idglobal_tbl, idlocal_tbl word pending_seq -word globals, lastglobal, lastlocal, savelast +word globals, lastglobal, lastglobalsize, lastlocal, savelast word tag_num, fixup_num, globalbufsz, localbufsz, codebufsz word datasize, framesize, savesize byte locals, savelocals From 1fd30c95360518f7ce8ab10b288fe088e21e274c Mon Sep 17 00:00:00 2001 From: Dave Schmenk Date: Wed, 24 Jan 2018 18:25:02 -0800 Subject: [PATCH 41/45] Update images --- PLASMA-BLD1.PO | Bin 143360 -> 143360 bytes PLASMA-DEM1.PO | Bin 143360 -> 143360 bytes PLASMA-PRE3.PO | Bin 143360 -> 143360 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/PLASMA-BLD1.PO b/PLASMA-BLD1.PO index 51d2d796e53563280eafb72415eabfe704b09203..d504cbf922818e31e99ad8e4e5f9c738406179d3 100644 GIT binary patch delta 18301 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 T-O^XNxwVI7RcjB$lJNfkGT!Zo diff --git a/PLASMA-DEM1.PO b/PLASMA-DEM1.PO index 9ecdcfb77eaf4de5ea191be318bf4ff2d2bf4d14..5d686dac5d9aa0cc763826a83a9bbe19aa36c140 100644 GIT binary patch delta 7512 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 delta 1868 zcmb_cT}+c#7=GXLeUt)HK9G&5{967t89`0RL}V6Pex$Uu)Cx=#`RNz}Zd`a_7Hh*u z)Znt?mu$;|&as6pCMM1rQ8EO_7A|(NWShydB@3AsBUxNF_e-4Jo)$Z#@oHI<=R5EF zoadbL_I+~B@de}Y1>+@EO}^){Tbi3JrB+*$lk`-zoXvW@T8Qsqwa{;-+Z6c;DssCV zH5Pl#a!wSgBqPlv)6@9{i4j>i5VY3qv_>W2F;qiL!yGHiu-3Ufwq{RM8nQx0B1Tq3 zx7^OUJ+`QdD8;s{3o|Rl=`23EY%m!(Cz!IvAl8^^t|)nVky+0(X?$_gDg5Z$Xa@7%=T5$?IXqOuByx}4|ODmHq}}@d)*Bl zo3*(yd_<_2RQfJ%^buarJoG)Wl{nch~za&lM9q5*KxAk&Z?|pMYeOE zJj5d4XOi!OyU1~Y>xjSPO!*V?UpOo9JMtxHvxO>)M3$_>Xa}4^@yiY&WS3B+Pvpsy zAYTC_@;60_d|TwmcSUaCJwbsBzz4t;U{a8r0zZv-7MKUV0KNx)#vChZKvhV_E2?}P z@jApC6(JqS+mN>-?^YfQ^eLN34k0)O;v^^K$SX`v4`pgg6 z`sv|#-QRO;+-poK`qzuG6)*N5+akFNQQC8T*~wZTM;)#Dv- zr}OF~+?ntC-`tU}!-+ADlap}ebHumc%2#mZ8&(28GDRHPfX3&;of?ewKx5dQeQ@Uh z+~|ZmBOp%!r;)z~ch16{^CCC!4!S-8Tm&uwK{#*~{B^`10&~D;z-{0T=I#qMKxn9f zhNh$08HjV?&MxF$C zi@CnOtO^5V7*}7%t+c+uVYRiC)_a=lk#|9@z@t!3F*01g6P)yfA$<2{(h_MQnAE$( zybb(4KGT2G+#-)a&7Pxw4Z6Zuqmby7iEi?K@{X4`=n$81f`IP?Fz*2B(u{I%o z`;Mw-c3P^j(-L3)Rn>HLG&QF5(GC7OilZvS>Z)vbtHZBmgELY&J|R1ro2bOf3hg$p z&AvIRBGpL=q@+ArR<9wz-#ETvHK`q=FXVxII+A0^T` zZM9726L%&IEY#ZihF$2vUp$e>M$y=WIK&g_tQsAz-R@@39xs?bd3;J)hNl)Mrxv-k?jL?= Bu#x}( diff --git a/PLASMA-PRE3.PO b/PLASMA-PRE3.PO index f6494ac0f6d8d14fb42dbdd59b8efd9bf323c14b..6a7c747ec337e6fa9fcfb7ad0dfb544e632171c8 100644 GIT binary patch delta 7201 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 XQ+xb<9!H;`>7p#&B-P@V<)i-vM@(uG delta 6971 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 From ba6e15feeffcd2b75917b07aaa56d80373e965c3 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 24 Jan 2018 19:18:05 -0800 Subject: [PATCH 42/45] Replace PRODOS 1.9 *again* --- PLASMA-PRE3.PO | Bin 143360 -> 143360 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/PLASMA-PRE3.PO b/PLASMA-PRE3.PO index 6a7c747ec337e6fa9fcfb7ad0dfb544e632171c8..b161b6701a251408a60d881063cfe6d896e5ca8f 100644 GIT binary patch delta 11853 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 DFY|a% delta 12499 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 From 6e217f5519ed74eea706dd8de2edb238e2b8fe73 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 24 Jan 2018 20:20:08 -0800 Subject: [PATCH 43/45] Update Preview Version 1.0.md --- doc/Preview Version 1.0.md | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/doc/Preview Version 1.0.md b/doc/Preview Version 1.0.md index 4efc165..19ebf2b 100644 --- a/doc/Preview Version 1.0.md +++ b/doc/Preview Version 1.0.md @@ -1,19 +1,23 @@ -# Developer Preview #2 Version 1.0 +# Developer Preview #3 Version 1.0 PLASMA is approaching a 1.0 release after _only_ 12 years. Hopefully it was worth the wait. To work out the remaining kinks, this Developer Preview will allow programmers to kick the tires, so to speak, to provide feedback on the system. -Download the two disk images: +Download the three disk images: -[PLASMA Preview #2 1.0 System](https://github.com/dschmenk/PLASMA/blob/master/PLASMA-PRE2.PO?raw=true) +[PLASMA Preview #3 1.0 System](https://github.com/dschmenk/PLASMA/blob/master/PLASMA-PRE3.PO?raw=true) [PLASMA 1.0 Build System](https://github.com/dschmenk/PLASMA/blob/master/PLASMA-BLD1.PO?raw=true) +[PLASMA 1.0 Demos](https://github.com/dschmenk/PLASMA/blob/master/PLASMA-DEM1.PO?raw=true) + PLASMA can be run from floppies, System in drive 1, and Build in drive 2. All Apple II computers are supported, from the earliest Rev 0 to the last Apple IIGS. However, an accelerator and hard disk/CFFA are highly recommended. The recommended mass storage installation looks like: -System Files => /HARDISK/PLASMA.PRE2/ +System Files => /HARDISK/PLASMA.PRE3/ Build Files => /HARDISK/BLD/ +Demo Files => /HARDISK/DEMOS/ + Keeping the system files seperate from the build directory will make upgrading to the final 1.0 Release later a little easier. 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. ## 65802/65816 Support @@ -56,17 +60,17 @@ Compiler warnings are enabled with `-W`. The optional optimizer is enabled with ### 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 +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. There may be problems if there is a CP/M card present when detecting the MockingBoard. A minimal Web server if you have an Uthernet2 card (required). Bug reports appreciated. ## Source Code -This is a Developers Preview, so sample source code is included from the project. It all builds without alteration and should be a good starting point for further explorations. There was a PLASMA SANDBOX in previous versions that was a minimal editor+compiler playground. It wasn't the full language and has been superceded by the real PLASMA compiler. However, the examples that accompanied the SANDBOX are included here. They have been updated to use the `INCLUDE "INC/CMDSYS.PLH"` line so that they may compile arnd run, but no gaurentees. You will probably have to fix whatever differences you come accross. An exercise, as they say, left up to the student. +This is a Developers Preview, all sample source code is included from the project. It builds 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. Previously, examples from the sandbox were included but they have been removed to make room for all the project samples and include files. ## 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. -- Many modules in the project aren't included in the Developer Preview. Only those modules that have gotten a good workout are included. The rest of the modules will be tested and included for the final 1.0 release. Feel free to try them out, and give feedback. Chances are they will work out of the box, or just a small tweak. +- All the project modules are included. They have been tested, with the exception of the Uthernet2 driver. I seem to have misplaced mine. If someone can try the Web Server demo in /PLASMA.DEMOS/NET and leave feedback would be very appreciated. - The documentation is sparse and incomplete. Yep, could use your help... @@ -131,6 +135,8 @@ To generate compiler warning for this issue, and a few others, use the `-W` opti 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: From 6a51ad78793f6b493e1a280a6fc7280b9679fe49 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 24 Jan 2018 20:21:02 -0800 Subject: [PATCH 44/45] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1258760..e95a88f 100755 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# 1/20/2018 Developer Preview #2 1.0 Available +# 1/24/2018 Developer Preview #3 1.0 Available [Download and read the Release Notes](https://github.com/dschmenk/PLASMA/blob/master/doc/Preview%20Version%201.0.md) # The PLASMA Programming Language From da22d6882de4ead97226f55127055081090ce8ad Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 24 Jan 2018 21:40:41 -0800 Subject: [PATCH 45/45] fix and update fiber library --- PLASMA-PRE3.PO | Bin 143360 -> 143360 bytes src/libsrc/fiber.pla | 10 ++++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/PLASMA-PRE3.PO b/PLASMA-PRE3.PO index b161b6701a251408a60d881063cfe6d896e5ca8f..592b9d2296601cb5a0c7d002f08bba65d5ef2171 100644 GIT binary patch delta 350 zcmZp8z|ru4W5X;K77G;((arN%GT0|)edC_Y&%?P{isxA{W9Vkas@sgpD;fCIgalGp zm=d%Y9eidmXfZ>$1!_S+QMsf%R-MWJ6E}(2GO#e*XJN2VQ4>{Wc+3D~08KrbWG&8Y zU}wLXk?Akvq&g>7pEOo2waNB%HjE*YYwDhGb_g*r?E_-P$(i-V^#M!_jmbcq2E^Gw zTmr=9K->ew{Xjegh-U-w0w7)t#4CV!H4twC;;lfu3y2Q^@o6Bw1jILi_&E^20^;{T z{0WG^1Mxo~W@ct+WCLPuAm#&NQDz3EMhPH87Kl}W*aV2Jf!Gd+oq^Z~i2WzmHaJRj l2pv0g>BPY^AsqWatV>5PUp?!}p(qUWr4nOP!?Fg(4FCeiWuX87 delta 423 zcmZp8z|ru4W5X;K76u^LJdY)VeR9q>&dHoi+?%C%o(0!4Fg#quB%lPQm_d}q?~Du5 z>lm0;>fdEx`oMbX!jA@?Q+*6f3Jm*?1q-cYNRaq_NMI40f`YxE#c!bCks_f9JU}r6 zg*O5d-dg;&NMK}OVs2n!kYQi~*$K2*0Yo!`SRlZ~zz<=7$V@O(+Bq>#y+om?G*2Nf zwW35Jv7jI)GdZy&Ge1vHB%mnY#XnfVwWuh+NWoS?MF9vH!~=3t6N^(7GV_X4i%Jwq zGEx;%GK;gVcpa0IQwvJ06r}lm`6Rf3<|e1+SSh#`CvRqCl46|9l(b&N4(O8WEDRPZ zf%}0~0#Tk7!GbY?-RA0!zrzRwj!orlG#pvKOfkBHI!Yxn>0*cBd<+188 z*xEY)P5jF^sm5utSB)iO%;c7uC!7sJ3{2aASaNbhwsp = $FB - vmstate=>$FE = @fbrExit - 1 - vmstate=>$FC = defaddr - 1 + vmstate->jmptmp = $4C + vmstate->hwsp = $FB + vmstate=>$FE = @fbrExit - 1 + vmstate=>$FC = defaddr - 1 // // Link into RUN list //