commit 1066a69950300a7b9209f15324069215132d153c Author: David Schmenk Date: Wed Apr 25 09:13:44 2018 -0700 Initial import diff --git a/BUILD.TXT b/BUILD.TXT new file mode 100755 index 0000000..e36b03c --- /dev/null +++ b/BUILD.TXT @@ -0,0 +1,13 @@ +This is the initial build process based on my very crusty and horrible makefile. This should improve as help arrives. + +1. Download/build/install cc65 +2. Install Java developers kit +3. Check out vm02 source +4. 'cd vm02/src' +5. 'make clean' +6. 'make' +7. 'make image' + +This will put the binary files into the vm02/release-$(VERSION) and vm02/samples-$(VERSION) directories in Virtual ][ name format. You can use something like CiderPress to copy the files into a disk image if you don't use Virtual ][. + +Dave... diff --git a/DESIGN.TXT b/DESIGN.TXT new file mode 100755 index 0000000..eebc783 --- /dev/null +++ b/DESIGN.TXT @@ -0,0 +1,317 @@ +VM02 V1.0 Design +================ +Author: Dave Schmenk +Date: 4/2/2010 +Revision: 1.3 + +Introduction +============ +VM02 is a Java compatible VM written in 6502 assembly language for the Apple II series of computers. Everything has been implemented from scratch using the JVM specification and black-boxing the Sun JVM with sample code. Certian aspects of the JVM have been simplified or removed to fit the target machine. This document is an attempt to record the design of VM02 for other developers to come up to speed, as well as to jog the memory of the original developer who has a tendency to forget what he has done. + +VM02 has quite a diversity of technology. Some is rather sophisticated and not deeply discussed. Floating point operations, DVM implementation, IRQ support, and other details are left out, but a perusal of the source should answer most questions. + +The design document will follow the implementation of VM02 as that was how many decisions were made along the way. Starting with the memory manager and class file loader which drives much of the following implementation through the class database, frame manager, thread scheduler, device drivers, and ending with DVM, the hope is that many questions can be answered by reading through this document. + +Before delving into the design, a little history is in order. The genesis for VM02 starts way back with the development of Apple Pascal around 1978. UCSD Pascal was brought to the Apple II and became one of the most powerful development environments for the fledging microcomputer market. Indeed, Apple Pascal was the first real computer language I learned in 1979 (after toying with with a TRS-80 Model 1 in school). Many years later, the retro-computing bug hit and I wanted to bring a modern, up-to-date programming environment to my favorite computer. After thinking about developing my own custom VM and language, a post on comp.sys.apple2 from Oliver Schmidt about porting a very limited Java-like VM to the Apple II got me thinking. Oliver's experiment was a success in that he got it working, but it was much too slow and cumbersome to be really useful. I decided then that a real JVM was possible and the performance issues could be solved with a clever assembly language implementation. The beginning of VM02 involved deciding what could be feasibly incorporated into a VM and what had to be left out. Ultimately I picked 64 bit data types as the cut-off for functionality. Everything else should be implemented in some fashion. Lastly, a JVM is only part of the equation when it comes to supporting a language like Java. Most of the language involves a huge library of classes that provide the functionality to be useful. I have attempted to write the bare minimum of classes to make the Apple II a viable Java target. + + +External Linkeage (global.inc) +------------------------------ +Page 3 ($0300-$03EF) is used for external entrypoints into VM02. Since the 6502 doesn't support indirect subroutine calls, the values have to be copied to a suitable location for calling. DVM has an indirect call opcode to simplify calling VM02 from native methods. Device drivers are accessed through function pointers as well as a few choice variables for global access. These links will remain stable for all of version 1. + + +Initiallization (vm02.s thread.s) +--------------------------------- +Initialization is a process to get every module of VM02 ready to execute the main class. All module's init code is called, then the inital class is searched for. Either a command string can be passed in from a previous program, the existance of a STARTUP class, or the user is prompted for an initial class to execute. The command string or command line is then parsed for parameters and installed into and argument string. An initial thread is created and the name of the main class is pushed on the stack for the thread to load and call. The thread is then started. Execution returns to VM_EXIT after all threads have finished. VM02 then reloads itself and begins the search again. Command strings and return values can be passed from one class to the next to create an exec chain. + + +Memory Management (memmgr.s fames.s ops.s sysclass.s) +----------------------------------------------------- +Even before the decision to implement a JVM, a memory manager had been worked out to provide a handle-based manager for a VM. The reason was to allow for ease of garbage collection, memory flexibility, and eventually memory swapping to disk. Memory blocks can be allocated, freed, moved, locked, and unlocked. The memory handle table is defined at the top of main memory, right below ProDOS, in the 64K configuration. The 128K VM places the handle table in the second bank of the AUX language card area. The number of memory handles is a define in global.inc. In the 64K configuration, the memory table takes up space in main memory so there is a tradeoff between the size of the table and free main memory. + +A memory handle is an entry in the handle table that points to the actual memory block, plus some flags in the low-order 3 bits. These bits are masked off when converting to an address. It also means that the memory blocks are multiples of 8 bytes. An allocated memory block has a 4 byte header containing the size of the block, the reference count of the block, and an accessed flag. A free block contains the size of the block and a handle to the next free block in the free list. The free list header is located in zero page. The smallest available memory block is thus 4 bytes (8 byte block minimum - 4 header bytes). It makes sense to try and allocate blocks that are as large as possible to avoid wasting memory and handles, thus causing fragmentation. + +Memory blocks can be allocated, freed, locked, unlocked, and reference counted. Memory can be optionally allocated at fixed addresses to support mapping the framebuffer or fullfilling the alignment requirements of ProDOS and other hardware/software. Memory can be code or data. In the 128K configuration, bytecode is actually stored in AUX memory, but the details are retained in a main memory block. This gives the system enough flexibility to manage memory in a very constrained environment. + +In the apple2/ProDOS.java class is a method: ioAllocBuffer() which calls an internal VM02 routine to allocate a fixed memory block. It actually scans from the bottom of memory to the top until it succeeds in allocating the block. If it fails, it forces GC and tries again. It will fail eventually, so it is best to allocate the IO buffer early on in the program to guarantee getting it. The HGR2 buffer is allocated using the same call in apple2/AppleStuff.java, although it fails immediately if it can't get the memory. VM02 uses it's own buffers for class loading and swapping that are independent of the Java class's file I/O. All operate independently. Java threads should use the Java synchronization features if doing I/O to the same file, otherwise they too are independent. The number of files open is only limited by available memory and ProDOS. + +Reference count incrementing is handled throught the VM, but reference decrementing is only handled through the object unreference routine (UNREF_OBJ) in sysclass.s. Whenever a new value is written into a variable or a local method frame is destroyed, reference counts to the current values are decremented. If the reference count goes to zero, then any objects made reference to by the object to be freed must also be decremented. It can get quite recursive. The finalize() method on any object to be freed is called immediately. This way memory can be returned to the pool as quickly as possible. Background memory collection is expensive both in time and space; VM02 has neither. Reference counting goes hand-in-hand with garbage collecting. + +Garbage collection is discussed in more detail later, but briefly it combines adjacent free space and shifts free memory down in memory. The concept is to keep allocated memory blocks as high up in memory as possible. One reason is that the VM itself exists in low memory, right below the second hi-res page. Keeping low memory free makes usage of the hi-res graphics more possible. There is a routine called from the scheduler and any time free memory is exhausted to first combine any adjacent free space, the move and allocated blocks up in memory. This process is repeated a given number of times. If called from the memory allocator and it is unable to satisfy the request, an out-of-memory error will be thrown. These algorithms can be combined with a build-optional demand swapping feature described next. + +Demand memory swapping to disk is supported through the use of a SWAP directory. Handles are converted to filenames and the data is read/written from/to the file. Accessed tags are incrementally cleared through the THREAD_YIELD routine. The memory allocator will now call two swapping routines when RAM is exhausted. The first will swap out all unaccessed blocks, the other will aggressively swap out all unlocked blocks. The idle loop garbage collector will combine any free blocks, try to move free space to lower memory, and write out any blocks which have been unaccessed for some time. Swap volumes are intelligently determined at init time. RAM disks of sufficient size have precedence over hard media. Finally, the SWAP directory is cleaned up at exit time. + + +Strings (strpools.s) +-------------------- +Strings in Jave are immutable - they don't change. Whenever a change is made, a new String object is created. VM02 works in concert with the memory manager to reference count strings. Only one copy of a string is kept. In VM02, if two strings are the same, their object references are the same too. Only strings of 255 charcters or less are permitted, and they are only 8 bit characters (UTF8), so no unicode support. Strings are hashed and searched through a linked list per hash table entry. Efficient searching, adding, and deleting of strings is important. + + +Class File Loader (classload.s class.inc) +----------------------------------------- +Class file loading is one of the most fundamental operations of VM02. One of the most important requirements for VM02 was that it use the well defined Java Class File Format. Many other small JVM implementations remove this requirement and create their own file format that eases the class field and offset resolution operations. Luckily, ProDOS provides a fairly sophisticated file system for directory and file management. + +The Java Class File Format is available on-line and should be reviewed to understand the internals of VM02. It is the basis for the single inheritence model of Java, as well as the exception and bytecode definitions. The class file maps the Java class into a binary representation, similar to a .o file in UNIX, or a .OBJ in MS-DOS/Windows. Linking occurs at runtime, and can be either lazy or immediate. VM02 chooses the lazy linking method as it only allocates resources for a class when it is called. This keeps the memory footprint as small as possible but can pause a running program to load referenced classes. The class file has four major sections: the constant pool, the interfaces, the fields, and the methods. Due to the way the class file is laid out, the size of the sections isn't known until each section is read in. This creates a little difficulty in allocating a data structure to contain the full class. Instead, the class loader allocates a data structure big enough to contain counts and handles for the interface descriptors, field descriptors, and method descriptors as well as the constant pool itself. Each constant pool entry is 5 bytes: one type bye and 4 data bytes. In the class file, they are dynamic in size, but to make the offset calculation easy, they are fixed in the class data structure. All the other sections are read in order, allocating a memory block to hold each section's descriptors. Method sections also call a code loader to install the method's code into the code manager (codemgr.s). After all the sections have been successfully loaded, a check is made to see if the superclass has beenn loaded. If not, the class loader is recursively called to load the superclass. Once all superclasses are available, the fields and methods are fixed up based on the superclass. This is probably the hardest code in all of VM02 to follow. This is where the fundamentals of the inheritance model come in to play. Fields shadow any superclass fields. Static methods shadow any superclass methods, whereas virtual methods have to override any superclass virtual methods in a virtual method table. This is not pretty code to write in 6502 assembly, it was rewritten in DVM code and makes following the code somewhat easier when you get accustomed to it. Finally, any class initializer is called to set up the class. Calling code asynchronously, as the class initializer is done, is covered in the frame manager code (frame.s). + + +Class Class (classclass.s) +-------------------------- +Class references are held in a table. There can be no more than 128 classes loaded in a program. With the other memory constraints of VM02, this shouldn't be a problem. In fact, the default table size is currently 64 entries. Class data strutures can be interrogated through the routines found in this file. If the class data structure changes in the future, most of the changes can be limited to this file. Java uses strings from the class file to name classes, methods, and fields. Routines to search the class table and class structure to resolve the name and description are here. These are called from the (ops.s) bytecode interpreter whenever method invokations are made or fields are accessed. The interpreter will stick the handles resolved by the routines here into the class structure so that the string names will no longer have to be resolved, the handle will be used directly. + + +Threads (thread.s) +------------------ +Again, pre-emptive multithreading was a design requirement even before a JVM was settled on. The Apple II is probably the least friendly to pre-emptive multi-threading of any computer. The 6502 just doesn't fit well into a threaded environment, unless that environment is a VM. Then, adding pre-emptive multi-threading to a virtual instruction set becomes pretty easy. Since the 6502 will be interpreting the Java bytecodes, I simply implemented a byte counter after each interpreted bytecode and call the scheduler when it reaches zero. The scheduler can also be called directly by way of THREAD_YIELD. If an asynchronous event requires the scheduler to run immediately (such as an interrupt waking up a thread), the count can be set to one so that the scheduler will run after the current bytecode finishes up. The scheduler itself has a table of threads which it scans looking for the best candidate to execute. This table is fixed and represents the maximum threads in the system. A define in global.inc sets the maximum number of threads (current default is 4). Each thread has 20 bytes of zero page for the bytecode interpreter state plus the 6502 hardware stack. Both are swapped during a thread re-schedule. Only the active part of the 6502 stack is read/written which is rarely more than 16 bytes. Swapping threads is pretty light-weight. If there are no threads ready to run, the idle loop will call the garbage collector to iteratively do any collecting and swapping of unaccessed memory. The GC will wait for a configurable time before starting, then it will delay between each iteration. Threads can wait on I/O events, synchronized objects, or just sleep. Threads wait on I/O by using a bitmask to identify which slot it is waiting on. Multiple slots can be waited on by setting the appropriate bits. The notifying slot will be returned to the thread in the accumulator (or multiple slots if more than one had pending I/O). If a timeout is included, VM02 will wake the thread after the timeout expires with an InterruptedException. Because the Apple II has no time base by default, it will estimate time based on the number of bytecodes interpreted. This is a pretty coarse estimate, but is a good first order approximation. The Apple IIc and any Apple II with a mouse card can use the VBL interrupt to establish a consistent time base. Timing then becomes quite accurate, at least to the resolution of 60 Hz. Other timing hardware can implement the time base with the addition of a device driver. + + +Execution Frames and Code Manager (frames.s codemgr.s) +------------------------------------------------------ +Whenever a thread of execution invokes a new method, a frame must be created to hold the local state for that method. Conversely, when a method is exited it's frame must be broken down and cleaned up. With Java and automatic garbage collection and exception handling, this becomes somewhat of an involved task. There are two ways to invoke methods. The most common is through the invoke bytecodes that call interfaces, static, and virtual methods. The other way to call is asynchronously by way of class loading or finalizers. Current state is pushed in a way that it can be restored when it exits. Either way, the called method is checked for a native vs bytecode implementation. Native, 6502 machine code, is then called directly without further ado, making native methods very lightweight. For bytecode methods, the code manager is used to recall important details about the method so a stack frame can be allocated. Once allocated, the current frame execution state is saved and the new frame is prepared for execution. The parameters are pulled off the stack and copied into the local variables. Object parameters get their reference count incremented. Finally, all the local variable types are set to zero. + +When the method exits, the local variables are scanned for object references and reference count decremented. If the method is returning due to an exception, then exception handling code is searched for and run if found. If the method was asynchronous, the previous execution state is restored and returned to. Realize that asynchronous method calls return to 6502 code (usually the class loader for () or the object unreference routine for finalize()). + + +Bytecode Interpreter (ops.s) +---------------------------- +The Java bytecode interpreter is mostly located in the 2nd bank of the Language Card memory. Due to the large size of the interpreter, some of the code lies in main memory. Floating point instructions are optional although the are built by default. They can be disabled by a define in global.inc, freeing up valuable main memory. In the 128K configuration, bytecodes are be read from auxiliary memory. Care must be taken to keep code that reference aux main memory in the language card. Main memory code cannot directly read from aux main memory. The unenhanced IIe doesn't like the aux memory mapped in when interrupts are enabled. The same is true when accessing other tables in aux langauage card space (memmgr.s strpool.s classclass.s). Interrupts are disabled whenever aux memory is accessed. + +The interpreter optimizes access to fields and methods by caching handles and offsets (classclass.s) in the constant pool the first time they are accessed. The MSB will be set for cached values. Class, field, and method reference code will check the MSB to determine if a full lookup is required. With classes, this can lead to loading a class (and it's superclasses) the first time it is referenced. Once a class is in memory, it can never be removed. + +The bytecode interpreter implements pre-emptive mutlithreading by calling the scheduler whenever opcount reaches zero. Runtime errors and exceptions are implemented by asynchronously calling a class - apple2/SystemException, that will throw the exception associated with parameter. This keeps all the exceptions themselves out of memory unless they are required. The asynchronous call is described more in the frame manager. + + +System Calls (sysclass.s) +------------------------- +VM02 provides a low level interface into the VM itself. Memory $0300-$03E0 is a jump table to various routines, as well as the device drivers. The apple2/vm02 class has an interface which provides a system level call into the VM or ROM, depending on the address. Addresses below $0100 will be treated as calls through the jump table, not zero page calls as this makes no sense with VM02. Global.inc contains the definitions of the jump table entries. + + +Garbage Collection and Finalizers (memmgr.s sysclass.s) +------------------------------------------------------- +The UNREF_OBJECT routine is located here. All object reference decrements are done here so that the recursive calls to unreference other objects can be somewhat managed. This is one of the most nerve-wracking routines you will ever encounter. Instance field references and array references are recursively dereferenced. Oh my head. + +GC and finalizers are closely related in VM02. Memory is reference counted and reclaimed immediately when the count reaches zero. VM02 is extremely resource constrained, so deferring GC makes little sense. When the memory being freed is an object, it's finalizer is asynchronously called first. Once the finalizer is called, all the object referenced from this object have their reference counts decremented, and recursively freed if zero. This code gets quite messy with all the possible recursion. Care must be taken when modifying any of it. + +It must be noted that reference counted GC is hardly robust. It is quite easy to have a dangling reference keep memory around, or mutually reference objects to never be freed (even if indirectly referenced). One can help the GC recover memory by explicitly setting unused references to null. This is been known to help other GC implementations as well, so isn't as horrible and anti-GC as it sounds. + + +Exceptions (except.s) +--------------------- +Exceptions are handled through a combination of the bytecode interpreter and the frame manager. When built with DEBUG enabled, VM02 will spit out a stack trace with a little extra information. VM02 doesn't incorporate all the exception logging and trace information that a real JVM does. + + +Device Drivers and I/O (io.s *drvr.s) +----------------------------- +Device drivers were one of the last things added to VM02. In the middle of functional development, it was clear that adding support for additional hardware was needed but ProDOS didn't provide a driver model and VM02 didn't want to be loaded down with static hardware support. So, basic device driver laoding was added. Interrupts are fully supported through a pseudo-priority scheme that scans lower numbered slots first. Read/write and control entry points in the VM02 jump table call into the device drivers for each slot. Every slot has a real or dummy control routine that will identify the device (or no device) in that slot. One requirement of the device driver is address independence. The driver can be laoded into any avaiable memory, so it must be written position independent. With the very simple functions required of the device driver, this isn't too much of a problem. Some fixups can also be done at driver load time (mousedrvr.s) Look to the included drivers for examples. Interrupts from devices can wake up threads waiting on I/O for that slot. + +Device I/O is abstracted using a slot index, not unlike file descriptors in unix. However, the Apple only has seven slots so things are a little simpler. In io.s, all the devices VM02 supports with a device driver are scanned and the driver is attached to whichever slot the hardware is found. Entries in the LINK page are fixed up to point to the driver entrypoints for that slot (global.inc). The only slot that is hard-coded is slot #3, defined as the console. Java code can interrogate each slot in turn, looking for a unique ID (defined in global.h) for the type of hardware it's looking for. Once the slot(s) is identified, it can proceed to make IOCTL calls and READ/WRITE calls. The calls are handled in a device dependent way - the mouse driver will respond to READ differently than a serial port driver. A thread will block waiting for input if nothing is available. Output usually waits for available space to write before returning. A thread can wait on multiple devices at the same time. See TestSelect.java to see how a thread can wait on keyboard and mouse input simultaneously. A bitmask is returned signaling which slot(s) have available input. A thread can also set a timeout before waiting on input. If the timeout occurs before input arrives, an InterruptedException will be generated. Again, TestSelect.java is a good example as well as org/vm02/cui/cui.java. + +One nice thing that the architecture of VM02 allowed was to treat the Uthernet card just like an interrupting device. Devices are polled during THREAD_YIELD if no timer hardware is installed, originally to have a type-ahead buffer for the keyboard. I tweaked it slightly when I added the Uthernet driver to generalize it for all devices. If timer hardware (like the mouse) exists, everything gets polled 60 times a second - regardless wether they generate IRQs or not. The Uthernet driver checks for any new packets when finished servicing the current packet to keep bandwidth high. + +Dave's Virtual Machine (dvm.s) +------------------------------ +In order to overcome some deficencies of the 6502 processor, namely 16 bit operations and position independence, a small pseudo, or virtual, machine was written. Somewhat of a cross between the Pascal p-machine and Sweet-16, it offers a compact code representation with full 16 bit operation and position independence. This allows non-time critical code to be implemented in a manner to take up less space, be moveable (and swappable), or both. The file class loader and fixed-address memory allocater was re-implemented using DVM to reduce space, simplify code, and allow it to be swapped in and out when needed. See below for a thorough description. + +I originally pulled VM02 back out of mothballs to add Uthernet and TCP/IP support. I quickly ran out of memory, so that is why I had to implement swapping. What a round-about way to get networking! It quickly became apparent that a Java solution to TCP/IP would be just too big. My ARP test pretty much consumes a 64K machine. So DVM to the rescue. VM02 has a requirement of position independent code for native methods - doing an entire TCP/IP stack in 6502 like that would be killer. I created DVM to fill just such a problem The screen driver for the CUI classes (org/vm02/cui/cuiDriver.clasm) is written in a DVM+6502 hybrid, so I'm pretty confident in it's ability. 6502 code can be easily inserted for inner loop performance critical stuff. + + +Object Reference Definition +=========================== +Object references are 32 bits, just like the other basic data types, int and float. The value is broken up into three parts. The lower 16 bits are the memory handle to the object memory. The next higher byte is the class index, and the highest byte is class specific type data. For strings, it's the hash value of the string. For arrays, it's the type and dimension of the array. If a class doesn't have a specific use for the fourth byte, just replicate the class index byte - this makes it easy to identify object handles when debugging. + + +Psuedo Machine for VM coding +============================ +Because the JVM is such a large app, a more sophisticated and compact code representation was needed to make it fit in the limited space of the Apple II. Macros were created to assemble into a p-code that is interpreted by yet another VM. Non-performance critical code is interpreted to save space. Native methods have access to DVM through a LINK_TABLE entrypoint. This is quite beneficial as native methods require position independence. Look at org/vm02/cui/cuiDriver.clasm for a sophisticated DVM method implementation. It is also quite easy to intersperse 6502 code inside DVM blocks. Use DVM for the position independence and overall control, 6502 for tight inner loops. + +The p-code is defined as such: + +$00-$07/$80-$87 +LD0B (Load 0 Byte) - load zero value byte on stack +LD0W (Load 0 Word) - load zero value word on stack +LD1B (Load 1 Byte) - load one value byte on stack +LD1W (Load 1 Word) - load one value word on stack +LD2B (Load 2 Byte) - load two value byte on stack +LD2W (Load 2 Word) - load two value word on stack +LD3B (Load 3 Byte) - load three value byte on stack +LD3W (Load 3 Word) - load three value word on stack +LD4B (Load 4 Byte) - load four value byte on stack +LD4W (Load 4 Word) - load four value word on stack +LD5B (Load 5 Byte) - load five value byte on stack +LD5W (Load 5 Word) - load five value word on stack +DUPB (DUPlicate Byte) - copy top byte on stack +DUPW (DUPlicate Word) - copy top word on stack +DUP2B (DUPlicate 2 Bytes) - copy top two bytes on stack (same as DUPW) +DUP2W (DUPlicate 2 Words) - copy top two words on stack + +$08-$0F/$88-$8F +SWAPB (SWAP Bytes) - swap bytes on stack +SWAPW (SWAP Words) - swap words on stack +LDCB (LoaD Constant Byte) - load constant value byte onto stack +LDCW (LoaD Constant Word) - load constant value word onto stack +LDZPB (LoaD Zero Page Byte) - load zero page memory onto stack +LDZPW (LoaD Zero Page Word) - load zero page memory onto stack +LDB (LoaD Byte) - load absolute memory onto stack +LDW (LoaD Word) - load absolute memory onto stack +LDPB (LoaD Pointer Byte) - load memory thru pointer+offset onto + stack +LDPW (LoaD Pointer Word) - load memory thru pointer+offset onto + stack +LDPINCB (LoaD Pointer Inc Byte) - load memory thru pointer onto stack + and increment pointer +LDPINCW (LoaD Pointer Inc Word) - load memory thru pointer onto stack + and increment pointer +LDPDECB (LoaD Pointer Dec Byte) - load memory thru pointer onto stack + and decrement pointer +LDPDECW (LoaD Pointer Dec Word) - load memory thru pointer onto stack + and decrement pointer +LDINDB (LoaD INDirect Byte) - load memory thru pointer from stack + onto stack +LDINDW (LoaD INDirect Word) - load memory thru pointer from stack + onto stack + +$10-$17/$90-$97 +POPB (POP Byte) - remove top byte on stack +POPW (POP Word) - remove top word on stack +POP2B (POP 2 Bytes) - remove top two bytes on stack (POPW) +POP2W (POP 2 Words) - remove top two words on stack +STZPB (STore Zero Page Byte) - store zero page memory from stack +STZPW (STore Zero Page Word) - store zero page memory from stack +STB (STore Byte) - store absolute memory from stack +STW (STore Word) - store absolute memory from stack +STPB (STore Pointer Byte) - store memory thru pointer+offset from + stack +STPW (STore Pointer Word) - store memory thru pointer+offset from + stack +STPINCB (STore Pointer INC Byte) - store memory thru pointer from stack + and increment pointer +STPINCW (STore Pointer INC Word) - store memory thru pointer from stack + and increment pointer +STPDECB (STore Pointer DEC Byte) - store memory thru pointer from stack + and decrement pointer +STPDECW (STore Pointer DEC Word) - store memory thru pointer from stack + and decrement pointer +STINDB (STore INDirect Byte) - store memory thru pointer, both from + stack +STINDW (STore INDirect Word) - store memory thru pointer, both from + stack + +$18-$1F/$98-$9F +ZEXTB (Zero EXTend Byte) - zero extend byte to word +SEXTB (Sign EXTend Byte) - sign extend byte to word +NEGB (NEGate Byte) - negate top byte on stack +NEGW (NEGate Word) - negate top word on stack +NOTB (NOT Byte) - not top byte on stack +NOTW (NOT Word) - not top word on stack +ADDB (ADD Byte) - add top bytes on stack +ADDW (ADD Word) - add top words on stack +SUBB (SUBtract Byte) - add top bytes on stack +SUBW (SUBtract Word) - add top words on stack +ANDB (AND Bytes) - and top bytes on stack +ANDW (AND Words) - and top words on stack +ORB (OR Bytes) - or top bytes on stack +ORW (OR Words) - or top words on stack +XORB (XOR Bytes) - xor top bytes on stack +XORW (XOR Words) - xor top words on stack + +$20-$27/$A0-$A7 +BRZB (BRanch Zero Byte) - branch byte on stack zero +BRZW (BRanch Zero Word) - branch word on stack zero +BRNZB (BRanch Not Zero Byte) - branch byte on stack not zero +BRNZW (BRanch Not Zero Word) - branch word on stack not zero +BRPOSB (BRanch Positive Byte) - branch byte on stack positive +BRPOSW (BRanch Positive Word) - branch word on stack positive +BRNEGB (BRanch NEGative Byte) - branch byte on stack negative +BRNEGW (BRanch NEGative Word) - branch word on stack negative +BREQUB (BRanch EQUal Bytes) - branch if top bytes equal +BREQUW (BRanch EQUal Words) - branch if top words equal +BRNEQB (BRanch Not EQual Bytes) - branch if top bytes not equal +BRNEQW (BRanch Not EQual Words) - branch if top words not equal +BRGTB (BRanch Greater Than Bytes) - branch if top-1 byte greater than top +BRGTW (BRanch Greater Than Words) - branch if top-1 word greater than top +BRLEB (BRanch Less than or Equal Bytes) - branch if top-1 byte less or equal than top +BRLEW (BRanch Less than or Equal Words) - branch if top-1 word less or equal than top + +$28-$2F/$A8-$AF +BRAB (BRanch Above Bytes) - branch if top-1 byte bigger than top +BRAW (BRanch Above Words) - branch if top-1 word bigger than top +BRBEB (BRanch Below or Equal Bytes) - branch if top-1 byte bigger than top +BRBEW (BRanch Below or Equal Words) - branch if top-1 word bigger than top +BRNCH (BRaNCH) - branch to offset +"" +DECJNZB (DECrement memory Jump Not Zero Byte) - decrement memory byte and + jump not zero +DECJNZW (DECrement memory Jump Not Zero Word) - decrement memory word and + jump not zero +SHLB (SHift Left Byte) - shift byte on stack left +SHLW (SHift Left Word) - shift word on stack left +SHRB (SHift Right Byte) - shift byte on stack right +SHRW (SHift Right Word) - shift word on stack right +INCRB (INCRement Byte) - increment byte on stack +INCRW (INCRement Word) - increment word on stack +DECRB (DECRement Byte) - decrement byte on stack +DECRW (DECRement Word) - decrement word on stack + +$30-$37/$B0-$B7 +EXIT (EXIT) - exit VM +"" +JUMP (JUMP) - jump to address +JUMPIND (JUMP) - jump to address on stack +CALL (CALL) - call subroutine address +CALLIND (CALL) - call subroutine address on stack +RET (RETurn) - return from subroutine +"" +CALL_02 (CALL 6502) - call 6502 subroutine address +CALLIND_02 (CALL 6502) - call 6502 subroutine address on stack +SWTCHB (SWiTCH Byte) - switch to matching byte value on stack +SWTCHW (SWiTCH Word) - switch to matching word value on stack + + +This is what an example DVM program looks like that fills the hi-res screen in an incrementing value until a key is pressed: + + .INCLUDE "dvm.inc" + +HRPTR = $60 + + .CODE + + LDX #$FF + TXS + DVM_BEGIN + CALL GRAPHMODE ; BASIC CALL TO SUBROUTINE + LD0B ; SET INITIAL VALUE TO ZERO + STB HRVAL +HRFILL: LDCW $4000 ; HR ADDRESS + STZPW HRPTR ; STORE IN ZP + LDCW $1000 ; HR SIZE IN WORDS + STW HRCOUNT + LDB HRVAL + DUPB ; EXPAND FILL TO WORD SIZE +HRLOOP: DUPW + STPIW (HRPTR) ; FILL SCREEN A WORD AT A TIME + DECJNZW HRCOUNT, HRLOOP ; HANDY LOOP OPCODE + POPB + INCRB + STB HRVAL + LDB $C000 ; CHECK KEYBOARD + BRPOSB HRFILL + LDB $C010 ; CLEAR STROBE + POPB ; THROW AWAY VALUE + LDCW TEXTMODE ; INDIRECT CALL TO SUBROUTINE + CALLIND ; CALL ADDRESS IS ABSOLUTE + JUMP HREXIT ; SIGNED 16 BIT OFFSET DEST +GRAPHMODE: LDB $C057 + POPB + LDB $C050 + POPB + LDB $C055 + POPB + RET +TEXTMODE: DVM_END ; POP OUT OF DVM FOR THINGS + LDA $C051 ; BETTER DONE IN 6502 + LDA $C054 + DVM_BEGIN + RET +HREXIT: DVM_END + RTS +HRVAL: .BYTE 0 +HRCOUNT: .WORD 0 \ No newline at end of file diff --git a/LICENSE.TXT b/LICENSE.TXT new file mode 100755 index 0000000..e37680c --- /dev/null +++ b/LICENSE.TXT @@ -0,0 +1,280 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/README.TXT b/README.TXT new file mode 100755 index 0000000..187d610 --- /dev/null +++ b/README.TXT @@ -0,0 +1,88 @@ +VM02 Apple II Java Virtual Machine +================================== + +Introduction: +------------- +VM02 is a Java compatible environment for the Apple II series of computers. Most basic features of a Java VM are implemented to allow direct execution of standard Java class files. + +However, in order to fit in the constraints of a 64K, 8 bit, 1 MHz computer, some aspects of a JVM have been reduced or removed. + +What is implemented: +- Standard Java class file loading and execution. +- Full object inheritence +- Multithreading (4 threads max by default) +- Exception handling +- Arrays up to 15 dimension +- 32 bit integers and single precision floating point +- Garbage collection +- Demand memory swapping to RAM disk or other available volume +- Finalizers +- Software and hardware implemented timing +- Device drivers for common hardware +- 128K memory support for //e and //c +- Exec-ing another class + +What is missing: +- 64 bit data types unimplemented +- Standard class library missing or limited implementation +- Lots of memory + +Running VM02: +------------- +VM02 is run by executing the JAVA.SYSTEM file. You must start JAVA.SYSTEM from the prefix where it exists. This is required to find the class base path to the support classes. Parameter passing is supported if your shell implements it. If no paramter is passed in and a file named STARTUP exists, it will be loaded as the initial class. Otherwise, you will be greeted with with a prompt to type in the class name to execute. You can start classes in other directories by typing in the fully qualified path. Class filenames under ProDOS are missing the ".class" suffix due to limited filename lengths. For example, to execute the Hello.class file on the /VM02.EXTRAS/SAMPLES volume, with VM02 you would type: + +/VM02.EXTRAS/SAMPLES/HELLO + +at the "Main class:" prompt. You would see this: + +Main class:/VM02.EXTRAS/SAMPLES/HELLO + +and then VM02 would attempt to find and load the class file. If an error occurs along the way, you will get an Unhandled Exception message, probably because the file (or superclass file) was not found. The preferred directory structure is to place all classes as subdirectories of the main VM02 directory. + +Model Compatibility: +-------------------- +VM02 has been tested on a variety of Apple II models from a Rev 0 Apple ][ with Integer Basic to a //c+ and much in-between. Most models run without issue, however some need a little support. Noteably, my ROM 1 IIgs needs to run VM02 under GS/OS to run without problems. Without pathces applied by GS/OS, the system quickly gets random values blasted throughout memory. When I added support for 128K and more sophisticated memory management, it caused the IIgs to falter more and more. Rock solid under GS/OS. I was unable to test a ROM 3 IIgs, so I don't know if those problems persist. Earlier models of the //c might lose VBL interrupts after being run for awhile. The unenhanced IIe should run the CUI programs but will look funny without the MouseText characters. Pre-IIe models won't run the CUI programs at all. + +Implementation of VM02: +----------------------- +VM02 is implemented from scratch in 6502 assembly, optimized for the 6502 and Apple II platform. The entire VM fits in about 20K of RAM. This leaves about 30K of RAM available for data and code in the 64K version, or about 32K for data and 44K for bytecode in the 128K version. Not a lot, but Java was defined for small platforms so you can get some reasonable programs even in such a small space. Swapping from main memory extends the available RAM, dependent on the swap volume. A new low level pseudo-machine was written to implement some of the non-time critical routines. Somewhat of a cross between the Pascal p-machine and Sweet-16, DVM (Dave's Virtual Machine) is optimized for position independent 16 bit operations. The class loader and some memory manager routines are implemented in DVM to save code space (about 4X) or allow for on-the-fly relocation. A high-resolution graphics page is available for use with small programs. Performance is acceptable for a 1 MHz, 8 bit CPU; on par with the UCSD p-System VM used in Apple Pascal. All features of the Apple II are made available through either specific classes, a low-level class that can call ROM routines, or both. There is a device driver architecture that currently supports 80 column cards, the Super Serial card, and the Apple Mouse card with preliminary support of the Uthernet card and Apple Graphics Tablet. Probing for the Uthernet card can cause problems in some machines with hardware VM02 doesn't detect. If probing for the Uthernet card causes the machine to hang at VM02 init time, hold down the Open-Apple key (or PushButton 1) during initialization and the Uthernet probe will be skipped. + +As noted earlier, class filenames are missing the ".class" suffix, however the file type of $ED is used to identify class files and are given the type identifier of JVM. System classes are in the JAVA/* subdirectories. Apple II specific classes are found in the APPLE2/ directory. VM02 specific class are found in the ORG/VM02/* subdirectories. + +Developing for VM02: +-------------------- +There isn't a native Java compiler for the Apple II (yet). All Java source must be cross-developed on a capable computer. The resulting class file needs to be transferred to an Apple or emulator using any number of available tools. One way is to use a tool like a2tools, AppleCommander, or CiderPress to copy the class file to a .DSK disk image file. The disk image can be run directly from an emulator or copied to real hardware with ADT or ADTPro. To compile against the Apple II specific classes, either download the source package (you will also need cc65, the 6502 C compiler package) or copy the APPLE2/ directory contents and rename the files with mixed case and add the .class suffix. + +The sample classes: +------------------- +Included with VM02 are sample classes that show off the capabilites of the environment. They can be executed from the samples disk or copied to another location. + +HELLO - A simple text entry program +HELLOWORLD - sample multi-threaded program +MOIRE - Hires example, requires AppleSoft in ROM +HIRESDEMO - Another hires demo +RODSCOLORS - Lores demo +SIMPLEPONG - Lores demo with paddle input +TERMINAL - Simple terminal program using the SSC +VOLUMES - List online volumes +CATALOG - Catalog a directory +LIST - List a text file to the screen +STRESSMEM - Allocate 64K 2D array. Stresses swapping code +TESTSELECT - select() type call using mouse, keyboard, and timeouts +TESTCHAIN - Chain to another class passing parameters and exit status +TESTCUI - Show off the CUI's controls (needs 128K) + +The Launcher class: +------------------- +With the release of version 1.0, a file launcher is included to navigate through volumes and directories and execute Java classes. Files of type $ED show up as JVM executable files. + +Release Version 1.0: +-------------------- +This represents the first release of VM02. Much of the implementation exists as skeletons of a complete Java environment. There is enough to run basic programs and do minimalistic file I/O. + +Known issues: +------------- +No know issues exist. + +March 31st 2010, 11:59:59 PM +Dave Schmenk... diff --git a/plasma2/FIRE.PLA#040000 b/plasma2/FIRE.PLA#040000 new file mode 100755 index 0000000..6dff92e --- /dev/null +++ b/plasma2/FIRE.PLA#040000 @@ -0,0 +1,126 @@ +CONST FALSE = 0 +CONST TRUE = NOT FALSE +CONST SHOWLORES = $C056 +CONST KEYBOARD = $C000 +CONST KEYSTROBE = $C010 +CONST EMPTY = 0 +CONST TREE = 4 +CONST FIRE = 13 +CONST FORESTSIZE = 42*42 +BYTE HELLOMSG[] = "PRESS ANY KEY TO BEGIN..." +BYTE EXITMSG[] = "PRESS ANY KEY TO EXIT." +BYTE GOODBYE[] = "THAT'S ALL FOLKS!" +BYTE TREES1[FORESTSIZE] +BYTE TREES2[FORESTSIZE] +WORD RNDNUM + +DEF TEXTMODE + DROP ROMCALL(0, 0, 0, 0, $FB39) +END + +DEF HOME + DROP ROMCALL(0, 0, 0, 0, $FC58) +END + +DEF GOTOXY(X, Y) + ^($24) = X + DROP ROMCALL(Y, 0, 0, 0, $FB5B) +END + +DEF GRMODE + DROP ROMCALL(0, 0, 0, 0, $FB40) + DROP ^SHOWLORES +END + +DEF RANDOMIZE(SEED) + RNDNUM = (SEED >> 8) + (SEED << 8) + SEED +END + +DEF RND + RNDNUM = (RNDNUM << 8) + RNDNUM + 12345 + RETURN RNDNUM & $7FFF +END + +DEF BYFIRE(TREEPTR) + IF ^(TREEPTR - 43) == FIRE + RETURN TRUE + ELSIF ^(TREEPTR - 42) == FIRE + RETURN TRUE + ELSIF ^(TREEPTR - 41) == FIRE + RETURN TRUE + ELSIF ^(TREEPTR - 1) == FIRE + RETURN TRUE + ELSIF ^(TREEPTR + 1) == FIRE + RETURN TRUE + ELSIF ^(TREEPTR + 41) == FIRE + RETURN TRUE + ELSIF ^(TREEPTR + 42) == FIRE + RETURN TRUE + ELSIF ^(TREEPTR + 43) == FIRE + RETURN TRUE + FIN + RETURN FALSE +END +DEF FORESTFIRE + WORD NEWTREES, OLDTREES, NEWTREE, OLDTREE, YROW + BYTE X, Y + + MEMSET(EMPTY, @TREES1, FORESTSIZE) + MEMSET(EMPTY, @TREES2, FORESTSIZE) + OLDTREES = @TREES1 + NEWTREES = @TREES2 + + FOR Y = 1 TO 40 + YROW = Y * 42 + FOR X = 1 TO 40 + IF RND < 8000 + ^(OLDTREES + X + YROW) = TREE + FIN + NEXT + NEXT + WHILE ^$C000 < 128 + FOR Y = 1 TO 40 + YROW = Y * 42 + FOR X = 1 TO 40 + OLDTREE = OLDTREES + X + YROW + NEWTREE = NEWTREES + X + YROW + WHEN ^OLDTREE + IS EMPTY + IF RND < 5000 + ^NEWTREE = TREE + ELSE + ^NEWTREE = EMPTY + FIN + IS TREE + IF RND < 5 OR BYFIRE(OLDTREE) + ^NEWTREE = FIRE + ELSE + ^NEWTREE = TREE + FIN + IS FIRE + ^NEWTREE = EMPTY + WEND + DROP ROMCALL(^NEWTREE, 0, 0, 0, $F864) + DROP ROMCALL(Y - 1, 0, X - 1, 0, $F800) + NEXT + NEXT + NEWTREES =, OLDTREES = OLDTREES, NEWTREES + LOOP + DROP ^$C010 +END + +PRSTR(@HELLOMSG) +WHILE ^$C000 < 128 + RNDNUM = RNDNUM + 1 +LOOP +RANDOMIZE(RNDNUM) +DROP ^$C010 +GRMODE +HOME +GOTOXY(10,22) +PRSTR(@EXITMSG) +FORESTFIRE +TEXTMODE +HOME +PRSTR(@GOODBYE) +DONE diff --git a/plasma2/autorun#040000 b/plasma2/autorun#040000 new file mode 100755 index 0000000..69fd4bd --- /dev/null +++ b/plasma2/autorun#040000 @@ -0,0 +1 @@ +PLED READ.ME diff --git a/plasma2/bytedump b/plasma2/bytedump new file mode 100755 index 0000000..7f9bea4 Binary files /dev/null and b/plasma2/bytedump differ diff --git a/plasma2/bytedump.c b/plasma2/bytedump.c new file mode 100755 index 0000000..e78f48e --- /dev/null +++ b/plasma2/bytedump.c @@ -0,0 +1,29 @@ +#include +#include +#include + +unsigned char buf[256]; + +int main(int argc, char **argv) +{ + int fd, offset; + + if (argc < 2) + { + printf("Usage: %s \n", argv[0]); + return (1); + } + if ((fd = open(argv[1], O_RDONLY, 0)) > 0) + { + offset = 0; + while (read(fd, buf, 1) == 1) + { + if (offset++ & 0x0F) + printf(",$%02X", buf[0]); + else + printf("\n\t.BYTE\t$%02X", buf[0]); + } + printf("\n"); + } + close(fd); +} \ No newline at end of file diff --git a/plasma2/cmd.pla b/plasma2/cmd.pla new file mode 100755 index 0000000..09b6ddd --- /dev/null +++ b/plasma2/cmd.pla @@ -0,0 +1,492 @@ +const iobuffer = $0800 +const databuff = $0C00 +const autorun = $01FF +byte version[] = "PLASMA ][ VM VERSION 0.8" +byte errorstr[] = "ERROR: $" +byte okstr[] = "OK" +byte prefix[32] = "" +byte perr +word cmdptr + +; +; Utility functions +; +; CALL PRODOS +; SYSCALL(CMD, PARAMS) +; +asm prodos + LDA ESTKL,X + LDY ESTKH,X + STA PARAMS + STY PARAMS+1 + INX + LDA ESTKL,X + STA CMD + STX ESP + JSR $BF00 +CMD: DB 00 +PARAMS: DW 0000 + BIT LCBNK2 + LDX ESP + STA ESTKL,X + LDY #$00 + STY ESTKH,X +end +; +; CALL LOADED SYSTEM PROGRAM +; +asm exec + LDX #$FF + TXS + BIT ROMIN + JMP $2000 +end +; +; SET MEMORY TO 0 +; MEMCLR(ADDR, SIZE) +; +asm memclr + LDY #$00 + LDA ESTKL+1,X + STA DSTL + LDA ESTKH+1,X + STA DSTH + INC ESTKL,X + INC ESTKH,X + TYA +SETMLP: DEC ESTKL,X + BNE :+ + DEC ESTKH,X + BEQ :++ +: STA (DST),Y + INY + BNE SETMLP + INC DSTH + BNE SETMLP +: INX + INX +end +; +; COPY MEMORY +; MEMCPY(SRCADDR, DSTADDR, SIZE) +; +asm memcpy + LDY #$00 + LDA ESTKL,X + BNE :+ + LDA ESTKH,X + BEQ MEMEXIT +: LDA ESTKL+1,X + STA DSTL + LDA ESTKH+1,X + STA DSTH + LDA ESTKL+2,X + STA SRCL + LDA ESTKH+2,X + STA SRCH + CMP DSTH + BCC REVCPY + BNE FORCPY + LDA SRCL + CMP DSTL + BCS FORCPY +REVCPY: ; REVERSE DIRECTION COPY +; CLC + LDA ESTKL,X + ADC DSTL + STA DSTL + LDA ESTKH,X + ADC DSTH + STA DSTH + CLC + LDA ESTKL,X + ADC SRCL + STA SRCL + LDA ESTKH,X + ADC SRCH + STA SRCH + INC ESTKH,X +REVCPYLP: + LDA DSTL + BNE :+ + DEC DSTH +: DEC DSTL + LDA SRCL + BNE :+ + DEC SRCH +: DEC SRCL + LDA (SRC),Y + STA (DST),Y + DEC ESTKL,X + BNE REVCPYLP + DEC ESTKH,X + BNE REVCPYLP + BEQ MEMEXIT +FORCPY: INC ESTKH,X +FORCPYLP: + LDA (SRC),Y + STA (DST),Y + INC DSTL + BNE :+ + INC DSTH +: INC SRCL + BNE :+ + INC SRCH +: DEC ESTKL,X + BNE FORCPYLP + DEC ESTKH,X + BNE FORCPYLP +MEMEXIT: INX + INX + INX +end +; +; CHAR OUT +; COUT(CHAR) +; +asm cout + LDA ESTKL,X + INX + ORA #$80 + BIT ROMIN + JSR $FDED + BIT LCBNK2 +end +; +; CHAR IN +; RDKEY() +; +asm cin + BIT ROMIN + STX ESP + JSR $FD0C + LDX ESP + BIT LCBNK2 + DEX + STA ESTKL,X + LDY #$00 + STY ESTKH,X +end +; +; PRINT STRING +; PRSTR(STR) +; +asm prstr + LDY #$00 + LDA ESTKL,X + STA SRCL + LDA ESTKH,X + STA SRCH + BIT ROMIN + LDA (SRC),Y + STA ESTKL,X + BEQ :+ +_PRS1: INY + LDA (SRC),Y + ORA #$80 + JSR $FDED + TYA + CMP ESTKL,X + BNE _PRS1 +: INX + BIT LCBNK2 +end +; +; PRINT BYTE +; +asm prbyte + LDA ESTKL,X + INX + STX ESP + BIT ROMIN + JSR $FDDA + BIT LCBNK2 + LDX ESP +end +; +; READ STRING +; STR = RDSTR(PROMPTCHAR) +; +asm rdstr + LDA ESTKL,X + STA $33 + STX ESP + BIT ROMIN + JSR $FD6A + BIT LCBNK2 + STX $01FF +: LDA $01FF,X + AND #$7F + STA $01FF,X + DEX + BPL :- + LDX ESP + LDA #$FF + STA ESTKL,X + LDA #$01 + STA ESTKH,X +end +asm toupper + LDA ESTKL,X + CMP #'a' + BCC :+ + CMP #'z'+1 + BCS :+ + SEC + SBC #$20 + STA ESTKL,X +: +end +; +; EXIT +; +asm reboot + BIT ROMIN + LDA #$00 + STA $3F4 ; INVALIDATE POWER-UP BYTE + JMP ($FFFC) ; RESET +end +def crout + cout($0D) +end +; +; ProDOS routines +; +def getpfx(path) + byte params[3] + + ^path = 0 + params.0 = 1 + params:1 = path + perr = prodos($C7, @params) + return path +end +def setpfx(path) + byte params[3] + + params.0 = 1 + params:1 = path + perr = prodos($C6, @params) + return path +end +def online + byte params[4] + + params.0 = 2 + params.1 = 0 + params:2 = $2000 + perr = prodos($C5, @params) + return $2000 +end +def open(path, buff) + byte params[6] + + params.0 = 3 + params:1 = path + params:3 = buff + params.5 = 0 + perr = prodos($C8, @params) + return params.5 +end +def close(refnum) + byte params[2] + + params.0 = 1 + params.1 = refnum + perr = prodos($CC, @params) + return perr +end +def read(refnum, buff, len) + byte params[8] + + params.0 = 4 + params.1 = refnum + params:2 = buff + params:4 = len + params:6 = 0 + perr = prodos($CA, @params) + return params:6 +end +; +; Command mode +; +def volumes + word strbuf + byte i + + strbuf = online() + for i = 0 to 15 + ^strbuf = ^strbuf & $0F + if ^strbuf + cout('/') + prstr(strbuf) + crout() + fin + strbuf = strbuf + 16 + next +end +def catalog(optpath) + byte path[64] + byte refnum + byte firstblk + byte entrylen, entriesblk + byte i, type, len + word entry, filecnt + + if ^optpath + memcpy(optpath, @path, ^optpath + 1) + else + drop getpfx(@path) + prstr(@path) + crout() + fin + refnum = open(@path, iobuffer); + if perr + return perr + fin + firstblk = 1 + repeat + if read(refnum, databuff, 512) == 512 + entry = databuff + 4 + if firstblk + entrylen = databuff.$23 + entriesblk = databuff.$24 + filecnt = databuff:$25 + entry = entry + entrylen + fin + for i = firstblk to entriesblk + type = ^entry + if type <> 0 + 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 + fin + for len = 19 - len downto 0 + cout(' ') + next + filecnt = filecnt - 1 + fin + entry = entry + entrylen + next + firstblk = 0 + else + filecnt = 0 + fin + until filecnt == 0 + drop close(refnum) + crout() + return 0 +end +def stripchars(strptr) + while ^strptr and ^(strptr + 1) <> ' ' + memcpy(strptr + 2, strptr + 1, ^strptr) + ^strptr = ^strptr - 1 + loop + return ^strptr +end +def stripspaces(strptr) + while ^strptr and ^(strptr + ^strptr) <= ' ' + ^strptr = ^strptr - 1 + loop + while ^strptr and ^(strptr + 1) <= ' ' + memcpy(strptr + 2, strptr + 1, ^strptr) + ^strptr = ^strptr - 1 + loop +end +def striptrail(strptr) + byte i + + for i = 1 to ^strptr + if (strptr)[i] == ' ' + ^strptr = i - 1 + return + fin + next +end +def parsecmd(strptr) + byte cmd + + cmd = 0 + stripspaces(strptr) + if ^strptr + cmd = ^(strptr + 1) + memcpy(strptr + 2, strptr + 1, ^strptr) + ^strptr = ^strptr - 1 + fin + stripspaces(strptr) + return cmd +end +def resetmemfiles + ; + ; Close all files + ; + ^$BFD8 = 0 + drop close(0) + ; + ; Set memory bitmap + ; + memclr($BF58, 24) + ^$BF58 = $CF + ^$BF6F = $01 +end +def execsys(sysfile) + byte refnum + word len + + if ^sysfile + memcpy(sysfile, $280, ^sysfile + 1) + striptrail(sysfile) + refnum = open(sysfile, iobuffer) + if refnum + len = read(refnum, $2000, $FFFF) + resetmemfiles() + if len + memcpy($280, sysfile, ^$280 + 1) + if stripchars(sysfile) and ^$2000 == $4C and *$2003 == $EEEE + stripspaces(sysfile) + if ^$2006 <= ^sysfile + memcpy(sysfile, $2006, ^sysfile + 1) + fin + fin + striptrail($280) + exec() + fin + fin + fin +end + +resetmemfiles() +execsys(autorun) +prstr(@version) +crout(); +while 1 + prstr(getpfx(@prefix)) + cmdptr = rdstr($BA) + when toupper(parsecmd(cmdptr)) + is 'Q' + reboot() + is 'C' + drop catalog(cmdptr) + is 'P' + drop setpfx(cmdptr) + is 'V' + volumes(); + is '-' + execsys(cmdptr) + perr = $46 + wend + if perr + prstr(@errorstr) + prbyte(perr) + else + prstr(@okstr) + fin + crout() +loop +done diff --git a/plasma2/cmd.s b/plasma2/cmd.s new file mode 100755 index 0000000..8547958 --- /dev/null +++ b/plasma2/cmd.s @@ -0,0 +1,1372 @@ +; 1: const iobuffer = $0800 + ; iobuffer = 2048 +; 2: const databuff = $0C00 + ; databuff = 3072 +; 3: const autorun = $01FF + ; autorun = 511 +; 4: byte version[] = "PLASMA ][ VM VERSION 0.8" +D0000: ; version + DB $18 + DB $50,$4C,$41,$53,$4D,$41,$20,$5D + DB $5B,$20,$56,$4D,$20,$56,$45,$52 + DB $53,$49,$4F,$4E,$20,$30,$2E,$38 +; 5: byte errorstr[] = "ERROR: $" +D0025: ; errorstr + DB $08 + DB $45,$52,$52,$4F,$52,$3A,$20,$24 +; 6: byte okstr[] = "OK" +D0034: ; okstr + DB $02 + DB $4F,$4B +; 7: byte prefix[32] = "" +D0037: ; prefix + DB $00 + DS $1F +; 8: byte perr +D0068: DS 1 ; perr +; 9: word cmdptr +D0069: DS 2 ; cmdptr +; 10: +; 11: ; +; 12: ; Utility functions +; 13: ; +; 14: ; CALL PRODOS +; 15: ; SYSCALL(CMD, PARAMS) +; 16: ; +; 17: asm prodos +C0000: ; prodos() +; 18: LDA ESTKL,X + LDA ESTKL,X +; 19: LDY ESTKH,X + LDY ESTKH,X +; 20: STA PARAMS + STA PARAMS +; 21: STY PARAMS+1 + STY PARAMS+1 +; 22: INX + INX +; 23: LDA ESTKL,X + LDA ESTKL,X +; 24: STA CMD + STA CMD +; 25: STX ESP + STX ESP +; 26: JSR $BF00 + JSR $BF00 +; 27: CMD: DB 00 +CMD: DB 00 +; 28: PARAMS: DW 0000 +PARAMS: DW 0000 +; 29: BIT LCBNK2 + BIT LCBNK2 +; 30: LDX ESP + LDX ESP +; 31: STA ESTKL,X + STA ESTKL,X +; 32: LDY #$00 + LDY #$00 +; 33: STY ESTKH,X + STY ESTKH,X +; 34: end + RTS +; 35: ; +; 36: ; CALL LOADED SYSTEM PROGRAM +; 37: ; +; 38: asm exec +C0002: ; exec() +; 39: LDX #$FF + LDX #$FF +; 40: TXS + TXS +; 41: BIT ROMIN + BIT ROMIN +; 42: JMP $2000 + JMP $2000 +; 43: end + RTS +; 44: ; +; 45: ; SET MEMORY TO 0 +; 46: ; MEMCLR(ADDR, SIZE) +; 47: ; +; 48: asm memclr +C0004: ; memclr() +; 49: LDY #$00 + LDY #$00 +; 50: LDA ESTKL+1,X + LDA ESTKL+1,X +; 51: STA DSTL + STA DSTL +; 52: LDA ESTKH+1,X + LDA ESTKH+1,X +; 53: STA DSTH + STA DSTH +; 54: INC ESTKL,X + INC ESTKL,X +; 55: INC ESTKH,X + INC ESTKH,X +; 56: TYA + TYA +; 57: SETMLP: DEC ESTKL,X +SETMLP: DEC ESTKL,X +; 58: BNE :+ + BNE :+ +; 59: DEC ESTKH,X + DEC ESTKH,X +; 60: BEQ :++ + BEQ :++ +; 61: : STA (DST),Y +: STA (DST),Y +; 62: INY + INY +; 63: BNE SETMLP + BNE SETMLP +; 64: INC DSTH + INC DSTH +; 65: BNE SETMLP + BNE SETMLP +; 66: : INX +: INX +; 67: INX + INX +; 68: end + RTS +; 69: ; +; 70: ; COPY MEMORY +; 71: ; MEMCPY(SRCADDR, DSTADDR, SIZE) +; 72: ; +; 73: asm memcpy +C0006: ; memcpy() +; 74: LDY #$00 + LDY #$00 +; 75: LDA ESTKL,X + LDA ESTKL,X +; 76: BNE :+ + BNE :+ +; 77: LDA ESTKH,X + LDA ESTKH,X +; 78: BEQ MEMEXIT + BEQ MEMEXIT +; 79: : LDA ESTKL+1,X +: LDA ESTKL+1,X +; 80: STA DSTL + STA DSTL +; 81: LDA ESTKH+1,X + LDA ESTKH+1,X +; 82: STA DSTH + STA DSTH +; 83: LDA ESTKL+2,X + LDA ESTKL+2,X +; 84: STA SRCL + STA SRCL +; 85: LDA ESTKH+2,X + LDA ESTKH+2,X +; 86: STA SRCH + STA SRCH +; 87: CMP DSTH + CMP DSTH +; 88: BCC REVCPY + BCC REVCPY +; 89: BNE FORCPY + BNE FORCPY +; 90: LDA SRCL + LDA SRCL +; 91: CMP DSTL + CMP DSTL +; 92: BCS FORCPY + BCS FORCPY +; 93: REVCPY: ; REVERSE DIRECTION COPY +REVCPY: ; REVERSE DIRECTION COPY +; 94: ; CLC +; 95: LDA ESTKL,X + LDA ESTKL,X +; 96: ADC DSTL + ADC DSTL +; 97: STA DSTL + STA DSTL +; 98: LDA ESTKH,X + LDA ESTKH,X +; 99: ADC DSTH + ADC DSTH +; 100: STA DSTH + STA DSTH +; 101: CLC + CLC +; 102: LDA ESTKL,X + LDA ESTKL,X +; 103: ADC SRCL + ADC SRCL +; 104: STA SRCL + STA SRCL +; 105: LDA ESTKH,X + LDA ESTKH,X +; 106: ADC SRCH + ADC SRCH +; 107: STA SRCH + STA SRCH +; 108: INC ESTKH,X + INC ESTKH,X +; 109: REVCPYLP: +REVCPYLP: +; 110: LDA DSTL + LDA DSTL +; 111: BNE :+ + BNE :+ +; 112: DEC DSTH + DEC DSTH +; 113: : DEC DSTL +: DEC DSTL +; 114: LDA SRCL + LDA SRCL +; 115: BNE :+ + BNE :+ +; 116: DEC SRCH + DEC SRCH +; 117: : DEC SRCL +: DEC SRCL +; 118: LDA (SRC),Y + LDA (SRC),Y +; 119: STA (DST),Y + STA (DST),Y +; 120: DEC ESTKL,X + DEC ESTKL,X +; 121: BNE REVCPYLP + BNE REVCPYLP +; 122: DEC ESTKH,X + DEC ESTKH,X +; 123: BNE REVCPYLP + BNE REVCPYLP +; 124: BEQ MEMEXIT + BEQ MEMEXIT +; 125: FORCPY: INC ESTKH,X +FORCPY: INC ESTKH,X +; 126: FORCPYLP: +FORCPYLP: +; 127: LDA (SRC),Y + LDA (SRC),Y +; 128: STA (DST),Y + STA (DST),Y +; 129: INC DSTL + INC DSTL +; 130: BNE :+ + BNE :+ +; 131: INC DSTH + INC DSTH +; 132: : INC SRCL +: INC SRCL +; 133: BNE :+ + BNE :+ +; 134: INC SRCH + INC SRCH +; 135: : DEC ESTKL,X +: DEC ESTKL,X +; 136: BNE FORCPYLP + BNE FORCPYLP +; 137: DEC ESTKH,X + DEC ESTKH,X +; 138: BNE FORCPYLP + BNE FORCPYLP +; 139: MEMEXIT: INX +MEMEXIT: INX +; 140: INX + INX +; 141: INX + INX +; 142: end + RTS +; 143: ; +; 144: ; CHAR OUT +; 145: ; COUT(CHAR) +; 146: ; +; 147: asm cout +C0008: ; cout() +; 148: LDA ESTKL,X + LDA ESTKL,X +; 149: INX + INX +; 150: ORA #$80 + ORA #$80 +; 151: BIT ROMIN + BIT ROMIN +; 152: JSR $FDED + JSR $FDED +; 153: BIT LCBNK2 + BIT LCBNK2 +; 154: end + RTS +; 155: ; +; 156: ; CHAR IN +; 157: ; RDKEY() +; 158: ; +; 159: asm cin +C0010: ; cin() +; 160: BIT ROMIN + BIT ROMIN +; 161: STX ESP + STX ESP +; 162: JSR $FD0C + JSR $FD0C +; 163: LDX ESP + LDX ESP +; 164: BIT LCBNK2 + BIT LCBNK2 +; 165: DEX + DEX +; 166: STA ESTKL,X + STA ESTKL,X +; 167: LDY #$00 + LDY #$00 +; 168: STY ESTKH,X + STY ESTKH,X +; 169: end + RTS +; 170: ; +; 171: ; PRINT STRING +; 172: ; PRSTR(STR) +; 173: ; +; 174: asm prstr +C0012: ; prstr() +; 175: LDY #$00 + LDY #$00 +; 176: LDA ESTKL,X + LDA ESTKL,X +; 177: STA SRCL + STA SRCL +; 178: LDA ESTKH,X + LDA ESTKH,X +; 179: STA SRCH + STA SRCH +; 180: BIT ROMIN + BIT ROMIN +; 181: LDA (SRC),Y + LDA (SRC),Y +; 182: STA ESTKL,X + STA ESTKL,X +; 183: BEQ :+ + BEQ :+ +; 184: _PRS1: INY +_PRS1: INY +; 185: LDA (SRC),Y + LDA (SRC),Y +; 186: ORA #$80 + ORA #$80 +; 187: JSR $FDED + JSR $FDED +; 188: TYA + TYA +; 189: CMP ESTKL,X + CMP ESTKL,X +; 190: BNE _PRS1 + BNE _PRS1 +; 191: : INX +: INX +; 192: BIT LCBNK2 + BIT LCBNK2 +; 193: end + RTS +; 194: ; +; 195: ; PRINT BYTE +; 196: ; +; 197: asm prbyte +C0014: ; prbyte() +; 198: LDA ESTKL,X + LDA ESTKL,X +; 199: INX + INX +; 200: STX ESP + STX ESP +; 201: BIT ROMIN + BIT ROMIN +; 202: JSR $FDDA + JSR $FDDA +; 203: BIT LCBNK2 + BIT LCBNK2 +; 204: LDX ESP + LDX ESP +; 205: end + RTS +; 206: ; +; 207: ; READ STRING +; 208: ; STR = RDSTR(PROMPTCHAR) +; 209: ; +; 210: asm rdstr +C0016: ; rdstr() +; 211: LDA ESTKL,X + LDA ESTKL,X +; 212: STA $33 + STA $33 +; 213: STX ESP + STX ESP +; 214: BIT ROMIN + BIT ROMIN +; 215: JSR $FD6A + JSR $FD6A +; 216: BIT LCBNK2 + BIT LCBNK2 +; 217: STX $01FF + STX $01FF +; 218: : LDA $01FF,X +: LDA $01FF,X +; 219: AND #$7F + AND #$7F +; 220: STA $01FF,X + STA $01FF,X +; 221: DEX + DEX +; 222: BPL :- + BPL :- +; 223: LDX ESP + LDX ESP +; 224: LDA #$FF + LDA #$FF +; 225: STA ESTKL,X + STA ESTKL,X +; 226: LDA #$01 + LDA #$01 +; 227: STA ESTKH,X + STA ESTKH,X +; 228: end + RTS +; 229: asm toupper +C0018: ; toupper() +; 230: LDA ESTKL,X + LDA ESTKL,X +; 231: CMP #'a' + CMP #'a' +; 232: BCC :+ + BCC :+ +; 233: CMP #'z'+1 + CMP #'z'+1 +; 234: BCS :+ + BCS :+ +; 235: SEC + SEC +; 236: SBC #$20 + SBC #$20 +; 237: STA ESTKL,X + STA ESTKL,X +; 238: : +: +; 239: end + RTS +; 240: ; +; 241: ; EXIT +; 242: ; +; 243: asm reboot +C0020: ; reboot() +; 244: BIT ROMIN + BIT ROMIN +; 245: LDA #$00 + LDA #$00 +; 246: STA $3F4 ; INVALIDATE POWER-UP BYTE + STA $3F4 ; INVALIDATE POWER-UP BYTE +; 247: JMP ($FFFC) ; RESET + JMP ($FFFC) ; RESET +; 248: end + RTS +; 249: def crout +C0022: ; crout() +; 250: cout($0D) + JSR INTERP + DB $2A,$0D ; CB 13 + DB $54,C0008 ; CALL C0008 +; 251: end + DB $5C ; RET +; 252: ; +; 253: ; ProDOS routines +; 254: ; +; 255: def getpfx(path) +C0024: ; getpfx() + ; path = 2 +; 256: byte params[3] + ; params = 4 +; 257: +; 258: ^path = 0 + JSR INTERP + DB $58,$07,$01 ; ENTER 7,1 + DB $66,$02 ; LLW 2 + DB $00 ; ZERO + DB $70 ; SB +; 259: params.0 = 1 + DB $28,$04 ; LLA 4 + DB $2A,$01 ; CB 1 + DB $70 ; SB +; 260: params:1 = path + DB $28,$05 ; LLA 5 + DB $66,$02 ; LLW 2 + DB $72 ; SW +; 261: perr = prodos($C7, @params) + DB $2A,$C7 ; CB 199 + DB $28,$04 ; LLA 4 + DB $54,C0000 ; CALL C0000 + DB $78,D0068 ; SAB D0068 +; 262: return path + DB $66,$02 ; LLW 2 + DB $5A ; LEAVE +; 263: end +; 264: def setpfx(path) +C0026: ; setpfx() + ; path = 2 +; 265: byte params[3] + ; params = 4 +; 266: +; 267: params.0 = 1 + JSR INTERP + DB $58,$07,$01 ; ENTER 7,1 + DB $28,$04 ; LLA 4 + DB $2A,$01 ; CB 1 + DB $70 ; SB +; 268: params:1 = path + DB $28,$05 ; LLA 5 + DB $66,$02 ; LLW 2 + DB $72 ; SW +; 269: perr = prodos($C6, @params) + DB $2A,$C6 ; CB 198 + DB $28,$04 ; LLA 4 + DB $54,C0000 ; CALL C0000 + DB $78,D0068 ; SAB D0068 +; 270: return path + DB $66,$02 ; LLW 2 + DB $5A ; LEAVE +; 271: end +; 272: def online +C0028: ; online() +; 273: byte params[4] + ; params = 2 +; 274: +; 275: params.0 = 2 + JSR INTERP + DB $58,$06,$00 ; ENTER 6,0 + DB $28,$02 ; LLA 2 + DB $2A,$02 ; CB 2 + DB $70 ; SB +; 276: params.1 = 0 + DB $28,$03 ; LLA 3 + DB $00 ; ZERO + DB $70 ; SB +; 277: params:2 = $2000 + DB $28,$04 ; LLA 4 + DB $2C,$00,$20 ; CW 8192 + DB $72 ; SW +; 278: perr = prodos($C5, @params) + DB $2A,$C5 ; CB 197 + DB $28,$02 ; LLA 2 + DB $54,C0000 ; CALL C0000 + DB $78,D0068 ; SAB D0068 +; 279: return $2000 + DB $2C,$00,$20 ; CW 8192 + DB $5A ; LEAVE +; 280: end +; 281: def open(path, buff) +C0030: ; open() + ; path = 2 + ; buff = 4 +; 282: byte params[6] + ; params = 6 +; 283: +; 284: params.0 = 3 + JSR INTERP + DB $58,$0C,$02 ; ENTER 12,2 + DB $28,$06 ; LLA 6 + DB $2A,$03 ; CB 3 + DB $70 ; SB +; 285: params:1 = path + DB $28,$07 ; LLA 7 + DB $66,$02 ; LLW 2 + DB $72 ; SW +; 286: params:3 = buff + DB $28,$09 ; LLA 9 + DB $66,$04 ; LLW 4 + DB $72 ; SW +; 287: params.5 = 0 + DB $28,$0B ; LLA 11 + DB $00 ; ZERO + DB $70 ; SB +; 288: perr = prodos($C8, @params) + DB $2A,$C8 ; CB 200 + DB $28,$06 ; LLA 6 + DB $54,C0000 ; CALL C0000 + DB $78,D0068 ; SAB D0068 +; 289: return params.5 + DB $28,$0B ; LLA 11 + DB $60 ; LB + DB $5A ; LEAVE +; 290: end +; 291: def close(refnum) +C0032: ; close() + ; refnum = 2 +; 292: byte params[2] + ; params = 4 +; 293: +; 294: params.0 = 1 + JSR INTERP + DB $58,$06,$01 ; ENTER 6,1 + DB $28,$04 ; LLA 4 + DB $2A,$01 ; CB 1 + DB $70 ; SB +; 295: params.1 = refnum + DB $28,$05 ; LLA 5 + DB $66,$02 ; LLW 2 + DB $70 ; SB +; 296: perr = prodos($CC, @params) + DB $2A,$CC ; CB 204 + DB $28,$04 ; LLA 4 + DB $54,C0000 ; CALL C0000 + DB $78,D0068 ; SAB D0068 +; 297: return perr + DB $68,D0068 ; LAB D0068 + DB $5A ; LEAVE +; 298: end +; 299: def read(refnum, buff, len) +C0034: ; read() + ; refnum = 2 + ; buff = 4 + ; len = 6 +; 300: byte params[8] + ; params = 8 +; 301: +; 302: params.0 = 4 + JSR INTERP + DB $58,$10,$03 ; ENTER 16,3 + DB $28,$08 ; LLA 8 + DB $2A,$04 ; CB 4 + DB $70 ; SB +; 303: params.1 = refnum + DB $28,$09 ; LLA 9 + DB $66,$02 ; LLW 2 + DB $70 ; SB +; 304: params:2 = buff + DB $28,$0A ; LLA 10 + DB $66,$04 ; LLW 4 + DB $72 ; SW +; 305: params:4 = len + DB $28,$0C ; LLA 12 + DB $66,$06 ; LLW 6 + DB $72 ; SW +; 306: params:6 = 0 + DB $28,$0E ; LLA 14 + DB $00 ; ZERO + DB $72 ; SW +; 307: perr = prodos($CA, @params) + DB $2A,$CA ; CB 202 + DB $28,$08 ; LLA 8 + DB $54,C0000 ; CALL C0000 + DB $78,D0068 ; SAB D0068 +; 308: return params:6 + DB $28,$0E ; LLA 14 + DB $62 ; LW + DB $5A ; LEAVE +; 309: end +; 310: ; +; 311: ; Command mode +; 312: ; +; 313: def volumes +C0036: ; volumes() +; 314: word strbuf + ; strbuf = 2 +; 315: byte i + ; i = 4 +; 316: +; 317: strbuf = online() + JSR INTERP + DB $58,$05,$00 ; ENTER 5,0 + DB $54,C0028 ; CALL C0028 + DB $76,$02 ; SLW 2 +; 318: for i = 0 to 15 + DB $00 ; ZERO +C0039: + DB $6C,$04 ; DLB 4 + DB $2A,$0F ; CB 15 + DB $3A,C0038 ; SKPGT C0038 + DB $0C ; INCR +; 319: ^strbuf = ^strbuf & $0F + DB $66,$02 ; LLW 2 + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $2A,$0F ; CB 15 + DB $14 ; BAND + DB $70 ; SB +; 320: if ^strbuf + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $4C,C0040 ; SKPFLS C0040 +; 321: cout('/') + DB $2A,$2F ; CB 47 + DB $54,C0008 ; CALL C0008 +; 322: prstr(strbuf) + DB $66,$02 ; LLW 2 + DB $54,C0012 ; CALL C0012 +; 323: crout() + DB $54,C0022 ; CALL C0022 +; 324: fin +C0040: +C0041: +; 325: strbuf = strbuf + 16 + DB $66,$02 ; LLW 2 + DB $2A,$10 ; CB 16 + DB $02 ; ADD + DB $76,$02 ; SLW 2 +; 326: next + DB $50,C0039 ; SKIP C0039 +C0038: + DB $30 ; DROP +; 327: end + DB $5A ; LEAVE +; 328: def catalog(optpath) +C0042: ; catalog() + ; optpath = 2 +; 329: byte path[64] + ; path = 4 +; 330: byte refnum + ; refnum = 68 +; 331: byte firstblk + ; firstblk = 69 +; 332: byte entrylen, entriesblk + ; entrylen = 70 + ; entriesblk = 71 +; 333: byte i, type, len + ; i = 72 + ; type = 73 + ; len = 74 +; 334: word entry, filecnt + ; entry = 75 + ; filecnt = 77 +; 335: +; 336: if ^optpath + JSR INTERP + DB $58,$4F,$01 ; ENTER 79,1 + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $4C,C0044 ; SKPFLS C0044 +; 337: memcpy(optpath, @path, ^optpath + 1) + DB $66,$02 ; LLW 2 + DB $28,$04 ; LLA 4 + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $54,C0006 ; CALL C0006 +; 338: else + DB $50,C0045 ; SKIP C0045 +C0044: +; 339: drop getpfx(@path) + DB $28,$04 ; LLA 4 + DB $54,C0024 ; CALL C0024 + DB $30 ; DROP +; 340: prstr(@path) + DB $28,$04 ; LLA 4 + DB $54,C0012 ; CALL C0012 +; 341: crout() + DB $54,C0022 ; CALL C0022 +; 342: fin +C0045: +; 343: refnum = open(@path, iobuffer); + DB $28,$04 ; LLA 4 + DB $2C,$00,$08 ; CW 2048 + DB $54,C0030 ; CALL C0030 + DB $74,$44 ; SLB 68 +; 344: if perr + DB $68,D0068 ; LAB D0068 + DB $4C,C0046 ; SKPFLS C0046 +; 345: return perr + DB $68,D0068 ; LAB D0068 + DB $5A ; LEAVE +; 346: fin +C0046: +C0047: +; 347: firstblk = 1 + DB $2A,$01 ; CB 1 + DB $74,$45 ; SLB 69 +; 348: repeat +C0049: +; 349: if read(refnum, databuff, 512) == 512 + DB $64,$44 ; LLB 68 + DB $2C,$00,$0C ; CW 3072 + DB $2C,$00,$02 ; CW 512 + DB $54,C0034 ; CALL C0034 + DB $2C,$00,$02 ; CW 512 + DB $40 ; ISEQ + DB $4C,C0050 ; SKPFLS C0050 +; 350: entry = databuff + 4 + DB $2C,$00,$0C ; CW 3072 + DB $2A,$04 ; CB 4 + DB $02 ; ADD + DB $76,$4B ; SLW 75 +; 351: if firstblk + DB $64,$45 ; LLB 69 + DB $4C,C0052 ; SKPFLS C0052 +; 352: entrylen = databuff.$23 + DB $2C,$23,$0C ; CW 3107 + DB $60 ; LB + DB $74,$46 ; SLB 70 +; 353: entriesblk = databuff.$24 + DB $2C,$24,$0C ; CW 3108 + DB $60 ; LB + DB $74,$47 ; SLB 71 +; 354: filecnt = databuff:$25 + DB $2C,$25,$0C ; CW 3109 + DB $62 ; LW + DB $76,$4D ; SLW 77 +; 355: entry = entry + entrylen + DB $66,$4B ; LLW 75 + DB $64,$46 ; LLB 70 + DB $02 ; ADD + DB $76,$4B ; SLW 75 +; 356: fin +C0052: +C0053: +; 357: for i = firstblk to entriesblk + DB $64,$45 ; LLB 69 +C0055: + DB $6C,$48 ; DLB 72 + DB $64,$47 ; LLB 71 + DB $3A,C0054 ; SKPGT C0054 + DB $0C ; INCR +; 358: type = ^entry + DB $66,$4B ; LLW 75 + DB $60 ; LB + DB $74,$49 ; SLB 73 +; 359: if type <> 0 + DB $64,$49 ; LLB 73 + DB $00 ; ZERO + DB $42 ; ISNE + DB $4C,C0056 ; SKPFLS C0056 +; 360: len = type & $0F + DB $64,$49 ; LLB 73 + DB $2A,$0F ; CB 15 + DB $14 ; BAND + DB $74,$4A ; SLB 74 +; 361: ^entry = len + DB $66,$4B ; LLW 75 + DB $64,$4A ; LLB 74 + DB $70 ; SB +; 362: prstr(entry) + DB $66,$4B ; LLW 75 + DB $54,C0012 ; CALL C0012 +; 363: if type & $F0 == $D0 ; Is it a directory? + DB $64,$49 ; LLB 73 + DB $2A,$F0 ; CB 240 + DB $14 ; BAND + DB $2A,$D0 ; CB 208 + DB $40 ; ISEQ + DB $4C,C0058 ; SKPFLS C0058 +; 364: cout('/') + DB $2A,$2F ; CB 47 + DB $54,C0008 ; CALL C0008 +; 365: len = len + 1 + DB $64,$4A ; LLB 74 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $74,$4A ; SLB 74 +; 366: elsif (entry).$10 == $FF + DB $50,C0059 ; SKIP C0059 +C0058: + DB $66,$4B ; LLW 75 + DB $2A,$10 ; CB 16 + DB $02 ; ADD + DB $60 ; LB + DB $2A,$FF ; CB 255 + DB $40 ; ISEQ + DB $4C,C0060 ; SKPFLS C0060 +; 367: cout('*') + DB $2A,$2A ; CB 42 + DB $54,C0008 ; CALL C0008 +; 368: len = len + 1 + DB $64,$4A ; LLB 74 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $74,$4A ; SLB 74 +; 369: fin +C0060: +C0059: +; 370: for len = 19 - len downto 0 + DB $2A,$13 ; CB 19 + DB $64,$4A ; LLB 74 + DB $04 ; SUB +C0062: + DB $6C,$4A ; DLB 74 + DB $00 ; ZERO + DB $38,C0061 ; SKPLT C0061 + DB $0E ; DECR +; 371: cout(' ') + DB $2A,$20 ; CB 32 + DB $54,C0008 ; CALL C0008 +; 372: next + DB $50,C0062 ; SKIP C0062 +C0061: + DB $30 ; DROP +; 373: filecnt = filecnt - 1 + DB $66,$4D ; LLW 77 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $76,$4D ; SLW 77 +; 374: fin +C0056: +C0057: +; 375: entry = entry + entrylen + DB $66,$4B ; LLW 75 + DB $64,$46 ; LLB 70 + DB $02 ; ADD + DB $76,$4B ; SLW 75 +; 376: next + DB $50,C0055 ; SKIP C0055 +C0054: + DB $30 ; DROP +; 377: firstblk = 0 + DB $00 ; ZERO + DB $74,$45 ; SLB 69 +; 378: else + DB $50,C0051 ; SKIP C0051 +C0050: +; 379: filecnt = 0 + DB $00 ; ZERO + DB $76,$4D ; SLW 77 +; 380: fin +C0051: +; 381: until filecnt == 0 + DB $66,$4D ; LLW 77 + DB $00 ; ZERO + DB $40 ; ISEQ + DB $4C,C0049 ; SKPFLS C0049 +C0048: +; 382: drop close(refnum) + DB $64,$44 ; LLB 68 + DB $54,C0032 ; CALL C0032 + DB $30 ; DROP +; 383: crout() + DB $54,C0022 ; CALL C0022 +; 384: return 0 + DB $00 ; ZERO + DB $5A ; LEAVE +; 385: end +; 386: def stripchars(strptr) +C0063: ; stripchars() + ; strptr = 2 +; 387: while ^strptr and ^(strptr + 1) <> ' ' + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 +C0065: + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $66,$02 ; LLW 2 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $60 ; LB + DB $2A,$20 ; CB 32 + DB $42 ; ISNE + DB $24 ; LAND + DB $4C,C0066 ; SKPFLS C0066 +; 388: memcpy(strptr + 2, strptr + 1, ^strptr) + DB $66,$02 ; LLW 2 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $66,$02 ; LLW 2 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $54,C0006 ; CALL C0006 +; 389: ^strptr = ^strptr - 1 + DB $66,$02 ; LLW 2 + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $70 ; SB +; 390: loop + DB $50,C0065 ; SKIP C0065 +C0066: +; 391: return ^strptr + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $5A ; LEAVE +; 392: end +; 393: def stripspaces(strptr) +C0067: ; stripspaces() + ; strptr = 2 +; 394: while ^strptr and ^(strptr + ^strptr) <= ' ' + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 +C0069: + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $66,$02 ; LLW 2 + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $02 ; ADD + DB $60 ; LB + DB $2A,$20 ; CB 32 + DB $4A ; ISLE + DB $24 ; LAND + DB $4C,C0070 ; SKPFLS C0070 +; 395: ^strptr = ^strptr - 1 + DB $66,$02 ; LLW 2 + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $70 ; SB +; 396: loop + DB $50,C0069 ; SKIP C0069 +C0070: +; 397: while ^strptr and ^(strptr + 1) <= ' ' +C0071: + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $66,$02 ; LLW 2 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $60 ; LB + DB $2A,$20 ; CB 32 + DB $4A ; ISLE + DB $24 ; LAND + DB $4C,C0072 ; SKPFLS C0072 +; 398: memcpy(strptr + 2, strptr + 1, ^strptr) + DB $66,$02 ; LLW 2 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $66,$02 ; LLW 2 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $54,C0006 ; CALL C0006 +; 399: ^strptr = ^strptr - 1 + DB $66,$02 ; LLW 2 + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $70 ; SB +; 400: loop + DB $50,C0071 ; SKIP C0071 +C0072: +; 401: end + DB $5A ; LEAVE +; 402: def striptrail(strptr) +C0073: ; striptrail() + ; strptr = 2 +; 403: byte i + ; i = 4 +; 404: +; 405: for i = 1 to ^strptr + JSR INTERP + DB $58,$05,$01 ; ENTER 5,1 + DB $2A,$01 ; CB 1 +C0076: + DB $6C,$04 ; DLB 4 + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $3A,C0075 ; SKPGT C0075 + DB $0C ; INCR +; 406: if (strptr)[i] == ' ' + DB $66,$02 ; LLW 2 + DB $64,$04 ; LLB 4 + DB $02 ; IDXB + DB $60 ; LB + DB $2A,$20 ; CB 32 + DB $40 ; ISEQ + DB $4C,C0077 ; SKPFLS C0077 +; 407: ^strptr = i - 1 + DB $66,$02 ; LLW 2 + DB $64,$04 ; LLB 4 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $70 ; SB +; 408: return + DB $30 ; DROP + DB $5A ; LEAVE +; 409: fin +C0077: +C0078: +; 410: next + DB $50,C0076 ; SKIP C0076 +C0075: + DB $30 ; DROP +; 411: end + DB $5A ; LEAVE +; 412: def parsecmd(strptr) +C0079: ; parsecmd() + ; strptr = 2 +; 413: byte cmd + ; cmd = 4 +; 414: +; 415: cmd = 0 + JSR INTERP + DB $58,$05,$01 ; ENTER 5,1 + DB $00 ; ZERO + DB $74,$04 ; SLB 4 +; 416: stripspaces(strptr) + DB $66,$02 ; LLW 2 + DB $54,C0067 ; CALL C0067 +; 417: if ^strptr + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $4C,C0081 ; SKPFLS C0081 +; 418: cmd = ^(strptr + 1) + DB $66,$02 ; LLW 2 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $60 ; LB + DB $74,$04 ; SLB 4 +; 419: memcpy(strptr + 2, strptr + 1, ^strptr) + DB $66,$02 ; LLW 2 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $66,$02 ; LLW 2 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $54,C0006 ; CALL C0006 +; 420: ^strptr = ^strptr - 1 + DB $66,$02 ; LLW 2 + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $70 ; SB +; 421: fin +C0081: +C0082: +; 422: stripspaces(strptr) + DB $66,$02 ; LLW 2 + DB $54,C0067 ; CALL C0067 +; 423: return cmd + DB $64,$04 ; LLB 4 + DB $5A ; LEAVE +; 424: end +; 425: def resetmemfiles +C0083: ; resetmemfiles() +; 426: ; +; 427: ; Close all files +; 428: ; +; 429: ^$BFD8 = 0 + JSR INTERP + DB $2C,$D8,$BF ; CW 49112 + DB $00 ; ZERO + DB $70 ; SB +; 430: drop close(0) + DB $00 ; ZERO + DB $54,C0032 ; CALL C0032 + DB $30 ; DROP +; 431: ; +; 432: ; Set memory bitmap +; 433: ; +; 434: memclr($BF58, 24) + DB $2C,$58,$BF ; CW 48984 + DB $2A,$18 ; CB 24 + DB $54,C0004 ; CALL C0004 +; 435: ^$BF58 = $CF + DB $2C,$58,$BF ; CW 48984 + DB $2A,$CF ; CB 207 + DB $70 ; SB +; 436: ^$BF6F = $01 + DB $2C,$6F,$BF ; CW 49007 + DB $2A,$01 ; CB 1 + DB $70 ; SB +; 437: end + DB $5C ; RET +; 438: def execsys(sysfile) +C0085: ; execsys() + ; sysfile = 2 +; 439: byte refnum + ; refnum = 4 +; 440: word len + ; len = 5 +; 441: +; 442: if ^sysfile + JSR INTERP + DB $58,$07,$01 ; ENTER 7,1 + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $4C,C0087 ; SKPFLS C0087 +; 443: memcpy(sysfile, $280, ^sysfile + 1) + DB $66,$02 ; LLW 2 + DB $2C,$80,$02 ; CW 640 + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $54,C0006 ; CALL C0006 +; 444: striptrail(sysfile) + DB $66,$02 ; LLW 2 + DB $54,C0073 ; CALL C0073 +; 445: refnum = open(sysfile, iobuffer) + DB $66,$02 ; LLW 2 + DB $2C,$00,$08 ; CW 2048 + DB $54,C0030 ; CALL C0030 + DB $74,$04 ; SLB 4 +; 446: if refnum + DB $64,$04 ; LLB 4 + DB $4C,C0089 ; SKPFLS C0089 +; 447: len = read(refnum, $2000, $FFFF) + DB $64,$04 ; LLB 4 + DB $2C,$00,$20 ; CW 8192 + DB $2C,$FF,$FF ; CW 65535 + DB $54,C0034 ; CALL C0034 + DB $76,$05 ; SLW 5 +; 448: resetmemfiles() + DB $54,C0083 ; CALL C0083 +; 449: if len + DB $66,$05 ; LLW 5 + DB $4C,C0091 ; SKPFLS C0091 +; 450: memcpy($280, sysfile, ^$280 + 1) + DB $2C,$80,$02 ; CW 640 + DB $66,$02 ; LLW 2 + DB $2C,$80,$02 ; CW 640 + DB $60 ; LB + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $54,C0006 ; CALL C0006 +; 451: if stripchars(sysfile) and ^$2000 == $4C and *$2003 == $EEEE + DB $66,$02 ; LLW 2 + DB $54,C0063 ; CALL C0063 + DB $2C,$00,$20 ; CW 8192 + DB $60 ; LB + DB $2A,$4C ; CB 76 + DB $40 ; ISEQ + DB $2C,$03,$20 ; CW 8195 + DB $62 ; LW + DB $2C,$EE,$EE ; CW 61166 + DB $40 ; ISEQ + DB $24 ; LAND + DB $24 ; LAND + DB $4C,C0093 ; SKPFLS C0093 +; 452: stripspaces(sysfile) + DB $66,$02 ; LLW 2 + DB $54,C0067 ; CALL C0067 +; 453: if ^$2006 <= ^sysfile + DB $2C,$06,$20 ; CW 8198 + DB $60 ; LB + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $4A ; ISLE + DB $4C,C0095 ; SKPFLS C0095 +; 454: memcpy(sysfile, $2006, ^sysfile + 1) + DB $66,$02 ; LLW 2 + DB $2C,$06,$20 ; CW 8198 + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $54,C0006 ; CALL C0006 +; 455: fin +C0095: +C0096: +; 456: fin +C0093: +C0094: +; 457: striptrail($280) + DB $2C,$80,$02 ; CW 640 + DB $54,C0073 ; CALL C0073 +; 458: exec() + DB $54,C0002 ; CALL C0002 +; 459: fin +C0091: +C0092: +; 460: fin +C0089: +C0090: +; 461: fin +C0087: +C0088: +; 462: end + DB $5A ; LEAVE +; 463: +; 464: resetmemfiles() +START: ; JSR INTERP + DB $54,C0083 ; CALL C0083 +; 465: execsys(autorun) + DB $2C,$FF,$01 ; CW 511 + DB $54,C0085 ; CALL C0085 +; 466: prstr(@version) + DB $26,D0000 ; LA D0000 + DB $54,C0012 ; CALL C0012 +; 467: crout(); + DB $54,C0022 ; CALL C0022 +; 468: while 1 +C0097: + DB $2A,$01 ; CB 1 + DB $4C,C0098 ; SKPFLS C0098 +; 469: prstr(getpfx(@prefix)) + DB $26,D0037 ; LA D0037 + DB $54,C0024 ; CALL C0024 + DB $54,C0012 ; CALL C0012 +; 470: cmdptr = rdstr($BA) + DB $2A,$BA ; CB 186 + DB $54,C0016 ; CALL C0016 + DB $7A,D0069 ; SAW D0069 +; 471: when toupper(parsecmd(cmdptr)) + DB $6A,D0069 ; LAW D0069 + DB $54,C0079 ; CALL C0079 + DB $54,C0018 ; CALL C0018 +; 472: is 'Q' + DB $2A,$51 ; CB 81 + DB $3E,C0100 ; SKPNE C0100 +; 473: reboot() + DB $54,C0020 ; CALL C0020 +; 474: is 'C' + DB $50,C0099 ; SKIP C0099 +C0100: + DB $2A,$43 ; CB 67 + DB $3E,C0101 ; SKPNE C0101 +; 475: drop catalog(cmdptr) + DB $6A,D0069 ; LAW D0069 + DB $54,C0042 ; CALL C0042 + DB $30 ; DROP +; 476: is 'P' + DB $50,C0099 ; SKIP C0099 +C0101: + DB $2A,$50 ; CB 80 + DB $3E,C0102 ; SKPNE C0102 +; 477: drop setpfx(cmdptr) + DB $6A,D0069 ; LAW D0069 + DB $54,C0026 ; CALL C0026 + DB $30 ; DROP +; 478: is 'V' + DB $50,C0099 ; SKIP C0099 +C0102: + DB $2A,$56 ; CB 86 + DB $3E,C0103 ; SKPNE C0103 +; 479: volumes(); + DB $54,C0036 ; CALL C0036 +; 480: is '-' + DB $50,C0099 ; SKIP C0099 +C0103: + DB $2A,$2D ; CB 45 + DB $3E,C0104 ; SKPNE C0104 +; 481: execsys(cmdptr) + DB $6A,D0069 ; LAW D0069 + DB $54,C0085 ; CALL C0085 +; 482: perr = $46 + DB $2A,$46 ; CB 70 + DB $78,D0068 ; SAB D0068 +; 483: wend + DB $50,C0099 ; SKIP C0099 +C0104: +C0099: + DB $30 ; DROP +; 484: if perr + DB $68,D0068 ; LAB D0068 + DB $4C,C0106 ; SKPFLS C0106 +; 485: prstr(@errorstr) + DB $26,D0025 ; LA D0025 + DB $54,C0012 ; CALL C0012 +; 486: prbyte(perr) + DB $68,D0068 ; LAB D0068 + DB $54,C0014 ; CALL C0014 +; 487: else + DB $50,C0107 ; SKIP C0107 +C0106: +; 488: prstr(@okstr) + DB $26,D0034 ; LA D0034 + DB $54,C0012 ; CALL C0012 +; 489: fin +C0107: +; 490: crout() + DB $54,C0022 ; CALL C0022 +; 491: loop + DB $50,C0097 ; SKIP C0097 +C0098: +; 492: done + DB $5C ; RET diff --git a/plasma2/cmdloader.cfg b/plasma2/cmdloader.cfg new file mode 100755 index 0000000..ef0a7c7 --- /dev/null +++ b/plasma2/cmdloader.cfg @@ -0,0 +1,10 @@ +MEMORY { + RAM: start = $1007, size = $1000, file = %O; +} +SEGMENTS { + CODE: load = RAM, type = rw; + DATA: load = RAM, type = rw; + BSS: load = RAM, type = rw; +} + + diff --git a/plasma2/codegen.c b/plasma2/codegen.c new file mode 100755 index 0000000..c094475 --- /dev/null +++ b/plasma2/codegen.c @@ -0,0 +1,1098 @@ +#include +#include "tokens.h" +#include "codegen.h" + +#define DEX if (xreg < 1){printf("\tDEX\n");}else{xreg--;} +#define INX if (xreg > 1){printf("\tINX\n");}else{xreg++;} +#define SYNC_X while (xreg != 0){if (xreg > 0){printf("\tINX\n");xreg--;}else{printf("\tDEX\n");xreg++;}} +#define INVALID_Y {y_valid = 0;} +#define VALID_Y {y_valid = 1;} +#define VALIDATE_Y if (!y_valid){printf("\tLDY\t#$00\n");y_valid=1;} + +int xreg = 0; +int y_valid = 0; +int opt = 0; +int outflags = 0; + +int optimization(int newopt) +{ + int oldopt = opt; + opt = newopt ? 1 : 0; + return (oldopt); +} +static int vsp_saved; +void emit_flags(int flags) +{ + outflags = flags; +} +void emit_header(void) +{ + if (outflags & EDASM) + printf("; EDASM COMPATIBLE OUTPUT\n"); + else + printf("\t.INCLUDE\t\"plstub.s\"\n"); +} +void emit_trailer(void) +{ +// if (!(outflags & EDASM)) +// printf("\t.INCLUDE\t\"vmcore.s\"\n"); +} +void emit_comment(char *s) +{ + if (!(outflags & EDASM)) + printf("\t\t\t\t\t; %s\n", s); +} +void emit_asm(char *s) +{ + printf("%s\n", s); +} +void emit_idlocal(char *name, int value) +{ + if (!(outflags & EDASM)) + printf("\t\t\t\t\t; %s = %d\n", name, value); +} +void emit_idglobal(int value, int size, char *name) +{ + if (size == 0) + { + if (outflags & EDASM) + printf("D%04d: EQU * ; %s\n", value, name); + else + printf("D%04d:\t\t\t\t\t; %s\n", value, name); + } + else + { + if (outflags & EDASM) + printf("D%04d: DS %d ; %s\n", value, size, name); + else + printf("D%04d:\tDS\t%d\t\t\t; %s\n", value, size, name); + } +} +void emit_idfunc(int value, char *name) +{ + if (outflags & EDASM) + printf("C%04d: EQU * ; %s()\n", value, name); + else + printf("C%04d:\t\t\t\t\t; %s()\n", value, name); +} +void emit_idconst(char *name, int value) +{ + if (!(outflags & EDASM)) + printf("\t\t\t\t\t; %s = %d\n", name, value); +} +int emit_data(int vartype, int consttype, long constval, int constsize) +{ + int datasize, i; + char *str; + if (consttype == 0) + { + datasize = constsize; + printf("\tDS\t$%02X\n", constsize); + } + else if (consttype == STRING_TYPE) + { + datasize = constsize; + str = (char *)constval; + printf("\tDB\t$%02X\n", --constsize); + while (constsize-- > 0) + { + printf("\tDB\t$%02X", *str++); + for (i = 0; i < 7; i++) + { + if (constsize-- > 0) + printf(",$%02X", *str++); + else + break; + } + printf("\n"); + } + } + else if (consttype == TAG_TYPE) + { + datasize = 2; + if (constval & 0x8000) + printf("\tDW\tC%04ld\t; C%04ld\n", constval & 0x7FFF, constval & 0x7FFF); + else + printf("\tDW\tD%04ld\t; D%04ld\n", constval, constval); + } + else + { + if (vartype == WORD_TYPE) + { + datasize = 2; + printf("\tDW\t$%04lX\n", constval & 0xFFFF); + } + else + { + datasize = 1; + printf("\tDB\t$%02lX\n", constval & 0xFF); + } + } + return (datasize); +} +void emit_codetag(int tag) +{ + if (opt) + { + SYNC_X; + } + if (outflags & EDASM) + printf("C%04d: EQU *\n", tag); + else + printf("C%04d:\n", tag); + if (opt) + INVALID_Y; +} +void emit_const(int cval) +{ + if (opt) + { + int lo = cval & 0xFF; + int hi = (cval >> 8) & 0xFF; + DEX;//printf("\tDEX\n"); + if (lo == 0) + { + VALIDATE_Y; + printf("\tSTY\tESTKL,X\n"); + } + else + { + printf("\tLDA\t#$%02X\n", lo); + printf("\tSTA\tESTKL,X\n"); + } + if (hi == 0) + { + VALIDATE_Y; + printf("\tSTY\tESTKH,X\n"); + } + else + { + if (hi != lo) + printf("\tLDA\t#$%02X\n", hi); + printf("\tSTA\tESTKH,X\n"); + } + } + else + { + if (cval == 0) + printf("\tDB\t$00\t\t\t; ZERO\n"); + else if (cval > 0 && cval < 256) + printf("\tDB\t$2A,$%02X\t\t\t; CB\t%d\n", cval, cval); + else + printf("\tDB\t$2C,$%02X,$%02X\t\t; CW\t%d\n", cval&0xFF,(cval>>8)&0xFF, cval); + } +} +void emit_lb(void) +{ + if (opt) + { + VALIDATE_Y; + SYNC_X; + printf("\tJSR\tLB\n"); + } + else + printf("\tDB\t$60\t\t\t; LB\n"); +} +void emit_lw(void) +{ + if (opt) + { + VALIDATE_Y; + SYNC_X; + printf("\tJSR\tLW\n"); + INVALID_Y; + } + else + printf("\tDB\t$62\t\t\t; LW\n"); +} +void emit_llb(int index) +{ + if (opt) + { + DEX;//printf("\tDEX\n"); + printf("\tLDY\t#$%02X\n", index); + printf("\tLDA\t(FRMP),Y\n"); + printf("\tSTA\tESTKL,X\n"); + printf("\tLDY\t#$00\n"); + printf("\tSTY\tESTKH,X\n"); + VALID_Y; + } + else + printf("\tDB\t$64,$%02X\t\t\t; LLB\t%d\n", index, index); +} +void emit_llw(int index) +{ + if (opt) + { + DEX;//printf("\tDEX\n"); + printf("\tLDY\t#$%02X\n", index); + printf("\tLDA\t(FRMP),Y\n"); + printf("\tSTA\tESTKL,X\n"); + printf("\tINY\n"); + printf("\tLDA\t(FRMP),Y\n"); + printf("\tSTA\tESTKH,X\n"); + INVALID_Y; + } + else + printf("\tDB\t$66,$%02X\t\t\t; LLW\t%d\n", index, index); +} +void emit_lab(int tag) +{ + if (opt) + { + DEX;//printf("\tDEX\n"); + printf("\tLDA\tD%04d\n", tag); + printf("\tSTA\tESTKL,X\n"); + VALIDATE_Y; + printf("\tSTY\tESTKH,X\n"); + } + else + { + if (outflags & EDASM) + printf("\tDB\t$68,>D%04d,D%04d\t; LAB\tD%04d\n", tag, tag, tag); + } +} +void emit_law(int tag) +{ + if (opt) + { + DEX;//printf("\tDEX\n"); + printf("\tLDA\tD%04d\n", tag); + printf("\tSTA\tESTKL,X\n"); + printf("\tLDA\tD%04d+1\n", tag); + printf("\tSTA\tESTKH,X\n"); + } + else + { + if (outflags & EDASM) + printf("\tDB\t$6A,>D%04d,D%04d\t; LAW\tD%04d\n", tag, tag, tag); + } +} +void emit_sb(void) +{ + if (opt) + { + VALIDATE_Y; + SYNC_X; + printf("\tJSR\tSB\n"); + } + else + printf("\tDB\t$70\t\t\t; SB\n"); +} +void emit_sw(void) +{ + if (opt) + { + VALIDATE_Y; + SYNC_X; + printf("\tJSR\tSW\n"); + INVALID_Y; + } + else + printf("\tDB\t$72\t\t\t; SW\n"); +} +void emit_slb(int index) +{ + if (opt) + { + SYNC_X; + printf("\tLDY\t#$%02X\n", index); + printf("\tLDA\tESTKL,X\n"); + printf("\tSTA\t(FRMP),Y\n"); + INX;//printf("\tINX\n"); + INVALID_Y; + } + else + printf("\tDB\t$74,$%02X\t\t\t; SLB\t%d\n", index, index); +} +void emit_slw(int index) +{ + if (opt) + { + SYNC_X; + printf("\tLDY\t#$%02X\n", index); + printf("\tLDA\tESTKL,X\n"); + printf("\tSTA\t(FRMP),Y\n"); + printf("\tINY\n"); + printf("\tLDA\tESTKH,X\n"); + printf("\tSTA\t(FRMP),Y\n"); + INX;//printf("\tINX\n"); + INVALID_Y; + } + else + printf("\tDB\t$76,$%02X\t\t\t; SLW\t%d\n", index, index); +} +void emit_dlb(int index) +{ + if (opt) + { + SYNC_X; + printf("\tLDY\t#$%02X\n", index); + printf("\tLDA\tESTKL,X\n"); + printf("\tSTA\t(FRMP),Y\n"); + INVALID_Y; + } + else + printf("\tDB\t$6C,$%02X\t\t\t; DLB\t%d\n", index, index); +} +void emit_dlw(int index) +{ + if (opt) + { + SYNC_X; + printf("\tLDY\t#$%02X\n", index); + printf("\tLDA\tESTKL,X\n"); + printf("\tSTA\t(FRMP),Y\n"); + printf("\tINY\n"); + printf("\tLDA\tESTKH,X\n"); + printf("\tSTA\t(FRMP),Y\n"); + INVALID_Y; + } + else + printf("\tDB\t$6E,$%02X\t\t\t; DLW\t%d\n", index, index); +} +void emit_sab(int tag) +{ + if (opt) + { + SYNC_X; + printf("\tLDA\tESTKL,X\n"); + printf("\tSTA\tD%04d\n", tag); + INX;//printf("\tINX\n"); + } + else + { + if (outflags & EDASM) + printf("\tDB\t$78,>D%04d,D%04d\t; SAB\tD%04d\n", tag, tag, tag); + } +} +void emit_saw(int tag) +{ + if (opt) + { + SYNC_X; + printf("\tLDA\tESTKL,X\n"); + printf("\tSTA\tD%04d\n", tag); + printf("\tLDA\tESTKH,X\n"); + printf("\tSTA\tD%04d+1\n", tag); + INX;//printf("\tINX\n"); + } + else + { + if (outflags & EDASM) + printf("\tDB\t$7A,>D%04d,D%04d\t; SAW\tD%04d\n", tag, tag, tag); + } +} +void emit_dab(int tag) +{ + if (opt) + { + SYNC_X; + printf("\tLDA\tESTKL,X\n"); + printf("\tSTA\tD%04d\n", tag); + } + else + { + if (outflags & EDASM) + printf("\tDB\t$7C,>D%04d,D%04d\t; DAB\tD%04d\n", tag, tag, tag); + } +} +void emit_daw(int tag) +{ + if (opt) + { + SYNC_X; + printf("\tLDA\tESTKL,X\n"); + printf("\tSTA\tD%04d\n", tag); + printf("\tLDA\tESTKH,X\n"); + printf("\tSTA\tD%04d+1\n", tag); + } + else + { + if (outflags & EDASM) + printf("\tDB\t$7E,>D%04d,D%04d\t; DAW\tD%04d\n", tag, tag, tag); + } +} +void emit_localaddr(int index) +{ + if (opt) + { + VALIDATE_Y; + DEX;//printf("\tDEX\n"); + printf("\tLDA\t#$%02X\n", index); + printf("\tCLC\n"); + printf("\tADC\tFRMPL\n"); + printf("\tSTA\tESTKL,X\n"); + printf("\tTYA\n"); + printf("\tADC\tFRMPH\n"); + printf("\tSTA\tESTKH,X\n"); + } + else + printf("\tDB\t$28,$%02X\t\t\t; LLA\t%d\n", index, index); +} +void emit_globaladdr(int tag, int type) +{ + if (opt) + { + DEX;//printf("\tDEX\n"); + if (type & FUNC_TYPE) + { + if (outflags & EDASM) + printf("\tLDA\t#>C%04d\n", tag); + else + printf("\tLDA\t#C%04d\n", tag); + printf("\tSTA\tESTKH,X\n"); + } + else + { + if (outflags & EDASM) + printf("\tLDA\t#>D%04d\n", tag); + else + printf("\tLDA\t#D%04d\n", tag); + printf("\tSTA\tESTKH,X\n"); + } + } + else + { + if (type & FUNC_TYPE) + { + if (outflags & EDASM) + printf("\tDB\t$26,>C%04d,C%04d\t; LA\tC%04d\n", tag, tag, tag); + } + else + { + if (outflags & EDASM) + printf("\tDB\t$26,>D%04d,D%04d\t; LA\tD%04d\n", tag, tag, tag); + } + } +} +void emit_globaladdrofst(int tag, int ofst, int type) +{ + if (opt) + { + DEX;//printf("\tDEX\n"); + if (type & FUNC_TYPE) + { + if (outflags & EDASM) + printf("\tLDA\t#>C%04d+%d\n", tag, ofst); + else + printf("\tLDA\t#C%04d+%d\n", tag, ofst); + printf("\tSTA\tESTKH,X\n"); + } + else + { + if (outflags & EDASM) + printf("\tLDA\t#>D%04d+%d\n", tag, ofst); + else + printf("\tLDA\t#D%04d+%d\n", tag, ofst); + printf("\tSTA\tESTKH,X\n"); + } + } + else + { + if (type & FUNC_TYPE) + { + if (outflags & EDASM) + printf("\tDB\t$26,>C%04d+%d,(C%04d+%d)\t; LA\tC%04d+%d\n", tag, ofst, tag, ofst, tag, ofst); + } + else + { + if (outflags & EDASM) + printf("\tDB\t$26,>D%04d+%d,(D%04d+%d)\t; LA\tD%04d+%d\n", tag, ofst, tag, ofst, tag, ofst); + } + } +} +void emit_indexbyte(void) +{ + if (opt) + { + SYNC_X; + printf("\tJSR\tADD\n"); + } + else + printf("\tDB\t$02\t\t\t; IDXB\n"); +} +void emit_indexword(void) +{ + if (opt) + { + SYNC_X; + printf("\tJSR\tIDXW\n"); + } + else + printf("\tDB\t$1E\t\t\t; IDXW\n"); +} +void emit_skpfls(int tag) +{ + if (opt) + { + INX;//printf("\tINX\n"); + SYNC_X; + printf("\tLDA\tESTKL-1,X\n"); + printf("\tORA\tESTKH-1,X\n"); + printf("\tBNE\t:+\n"); + printf("\tJMP\tC%04d\n", tag); + printf(":\n"); + } + else + { + if (outflags & EDASM) + printf("\tDB\t$4C,>C%04d,C%04d\t; SKPFLS\tC%04d\n", tag, tag, tag); + } +} +void emit_skptru(int tag) +{ + if (opt) + { + INX;//printf("\tINX\n"); + SYNC_X; + printf("\tLDA\tESTKL-1,X\n"); + printf("\tORA\tESTKH-1,X\n"); + printf("\tBEQ\t:+\n"); + printf("\tJMP\tC%04d\n", tag); + printf(":\n"); + } + else + { + if (outflags & EDASM) + printf("\tDB\t$4E,>C%04d,C%04d\t; SKPTRU\tC%04d\n", tag, tag, tag); + } +} +void emit_skip(int tag) +{ + if (opt > 0) + { + SYNC_X; + printf("\tJMP\tC%04d\n", tag); + } + else + { + if (outflags & EDASM) + printf("\tDB\t$50,>C%04d,C%04d\t; SKIP\tC%04d\n", tag, tag, tag); + } +} +void emit_skpeq(int tag) +{ + if (opt) + { + INX;//printf("\tINX\n"); + SYNC_X; + printf("\tLDA\tESTKL-1,X\n"); + printf("\tCMP\tESTKL,X\n"); + printf("\tBNE\t:+\n"); + printf("\tLDA\tESTKH-1,X\n"); + printf("\tCMP\tESTKH,X\n"); + printf("\tBNE\t:+\n"); + printf("\tJMP\tC%04d\n", tag); + printf(":\n"); + } + else + { + if (outflags & EDASM) + printf("\tDB\t$3C,>C%04d,C%04d\t; SKPEQ\tC%04d\n", tag, tag, tag); + } +} +void emit_skpne(int tag) +{ + if (opt) + { + INX;//printf("\tINX\n"); + SYNC_X; + printf("\tLDA\tESTKL-1,X\n"); + printf("\tCMP\tESTKL,X\n"); + printf("\tBNE\t:+\n"); + printf("\tLDA\tESTKH-1,X\n"); + printf("\tCMP\tESTKH,X\n"); + printf("\tBEQ\t:++\n"); + printf(":\tJMP\tC%04d\n", tag); + printf(":\n"); + } + else + { + if (outflags & EDASM) + printf("\tDB\t$3E,>C%04d,C%04d\t; SKPNE\tC%04d\n", tag, tag, tag); + } +} +void emit_skplt(int tag) +{ + if (opt) + { + INX;//printf("\tINX\n"); + SYNC_X; + printf("\tLDA\tESTKL,X\n"); + printf("\tCMP\tESTKL-1,X\n"); + printf("\tLDA\tESTKH,X\n"); + printf("\tSBC\tESTKH-1,X\n"); + printf("\tBPL\t:+\n"); + printf("\tJMP\tC%04d\n", tag); + printf(":\n"); + } + else + { + if (outflags & EDASM) + printf("\tDB\t$38,>C%04d,C%04d\t; SKPLT\tC%04d\n", tag, tag, tag); + } +} +void emit_skpgt(int tag) +{ + if (opt) + { + INX;//printf("\tINX\n"); + SYNC_X; + printf("\tLDA\tESTKL-1,X\n"); + printf("\tCMP\tESTKL,X\n"); + printf("\tLDA\tESTKH-1,X\n"); + printf("\tSBC\tESTKH,X\n"); + printf("\tBPL\t:+\n"); + printf("\tJMP\tC%04d\n", tag); + printf(":\n"); + } + else + { + if (outflags & EDASM) + printf("\tDB\t$3A,>C%04d,C%04d\t; SKPGT\tC%04d\n", tag, tag, tag); + } +} +void emit_call(int tag) +{ + if (opt) + { + SYNC_X; + printf("\tJSR\tC%04d\n", tag); + INVALID_Y; + } + else + { + if (outflags & EDASM) + (tag & 0x8000) ? printf("\tDB\t$54,>D%04d,C%04d,D%04d\t; CALL\tD%04d\n", tag&0x7FFF, tag&0x7FFF, tag&0x7FFF) + : printf("\tDB\t$54,C%04d\t; CALL\tC%04d\n", tag, tag, tag); + } +} +void emit_ical(void) +{ + if (opt) + { + SYNC_X; + printf("\tJSR\tICAL\n"); + INVALID_Y; + } + else + printf("\tDB\t$56\t\t\t; ICAL\n"); +} +void emit_leave(int framesize) +{ + if (framesize > 2) + { + if (opt) + { + SYNC_X; + printf("\tJMP\tLEAVE\n"); + } + else + printf("\tDB\t$5A\t\t\t; LEAVE\n"); + } + else + { + if (opt) + printf("\tRTS\n"); + else + printf("\tDB\t$5C\t\t\t; RET\n"); + } +} +void emit_ret(void) +{ + if (opt) + { + SYNC_X; + printf("\tRTS\n"); + } + else + printf("\tDB\t$5C\t\t\t; RET\n"); +} +void emit_def(int defopt) +{ + opt = defopt; + if (!opt) + printf("\tJSR\t_INTERP\n"); +} +void emit_enter(int framesize, int cparams) +{ + if (framesize > 2) + { + if (opt) + { + printf("\tLDY\t#%d\n", framesize); + printf("\tLDA\t#%d\n", cparams); + printf("\tJSR\tENTER\n"); + VALID_Y; + } + else + printf("\tDB\t$58,$%02X,$%02X\t\t; ENTER\t%d,%d\n", framesize, cparams, framesize, cparams); + } +} +void emit_start(void) +{ + printf("START:\t; JSR\tINTERP\n"); +} +void emit_dup(void) +{ + if (opt) + { + DEX;//printf("\tDEX\n"); + printf("\tLDA\tESTKL+1,X\n"); + printf("\tSTA\tESTKL,X\n"); + printf("\tLDA\tESTKH+1,X\n"); + printf("\tSTA\tESTKH,X\n"); + } + else + printf("\tDB\t$32\t\t\t; DUP\n"); +} +void emit_push(void) +{ + if (opt) + { + printf("\tLDA\tESTKL,X\n"); + printf("\tPHA\n"); + printf("\tLDA\tESTKH,X\n"); + printf("\tPHA\n"); + INX;//printf("\tINX\n"); + } + else + printf("\tDB\t$34\t\t\t; PUSH\n"); +} +void emit_pull(void) +{ + if (opt) + { + DEX;//printf("\tDEX\n"); + printf("\tPLA\n"); + printf("\tSTA\tESTKH,X\n"); + printf("\tPLA\n"); + printf("\tSTA\tESTKL,X\n"); + } + else + printf("\tDB\t$36\t\t\t; PULL\n"); +} +void emit_swap(void) +{ + if (opt) + { + SYNC_X; + printf("\tJSR\tSWAP\n"); + INVALID_Y; + } + else + printf("\tDB\t$2E\t\t\t; SWAP\n"); +} +void emit_drop(void) +{ + if (opt) + { + INX;//printf("\tINX\t\t\t\t; DROP\n"); + } + else + printf("\tDB\t$30\t\t\t; DROP\n"); +} +int emit_unaryop(int op) +{ + if (opt) + SYNC_X; + switch (op) + { + case NEG_TOKEN: + if (opt) + { + VALIDATE_Y; + printf("\tJSR\tNEG\n"); + } + else + printf("\tDB\t$10\t\t\t; NEG\n"); + break; + case COMP_TOKEN: + if (opt) + printf("\tJSR\tCOMP\n"); + else + printf("\tDB\t$12\t\t\t; COMP\n"); + break; + case LOGIC_NOT_TOKEN: + if (opt) + { + VALIDATE_Y; + printf("\tJSR\tNOT\n"); + } + else + printf("\tDB\t$20\t\t\t; NOT\n"); + break; + case INC_TOKEN: + if (opt) + { + printf("\tINC\tESTKL,X\n"); + printf("\tBNE\t:+\n"); + printf("\tINC\tESTKH,X\n"); + printf(":\n"); + } + else + printf("\tDB\t$0C\t\t\t; INCR\n"); + break; + case DEC_TOKEN: + if (opt) + { + printf("\tLDA\tESTKL,X\n"); + printf("\tBNE\t:+\n"); + printf("\tDEC\tESTKH,X\n"); + printf(":\tDEC\tESTKL,X\n"); + } + else + printf("\tDB\t$0E\t\t\t; DECR\n"); + break; + case BPTR_TOKEN: + emit_lb(); + break; + case WPTR_TOKEN: + emit_lw(); + break; + default: + printf("emit_unaryop(%c) ? \n", op & 0x7F); + return (0); + } + return (1); +} +int emit_op(t_token op) +{ + if (opt) + SYNC_X; + switch (op) + { + case MUL_TOKEN: + if (opt) + { + VALIDATE_Y; + printf("\tJSR\tMUL\n"); + } + else + printf("\tDB\t$06\t\t\t; MUL\n"); + break; + case DIV_TOKEN: + if (opt) + { + VALIDATE_Y; + printf("\tJSR\tDIV\n"); + INVALID_Y; + } + else + printf("\tDB\t$08\t\t\t; DIV\n"); + break; + case DIVMOD_TOKEN: + if (opt) + { + VALIDATE_Y; + printf("\tJSR\tDIVMOD\n"); + INVALID_Y; + } + else + printf("\tDB\t$0A\t\t\t; DIV,MOD\n"); + break; + case ADD_TOKEN: + if (opt) + { + printf("\tJSR\tADD\n"); +// printf("\tLDA\tESTKL,X\n"); +// printf("\tCLC\n"); +// printf("\tADC\tESTKL+1,X\n"); +// printf("\tSTA\tESTKL+1,X\n"); +// printf("\tLDA\tESTKH,X\n"); +// printf("\tADC\tESTKH+1,X\n"); +// printf("\tSTA\tESTKH+1,X\n"); +// INX; + } + else + printf("\tDB\t$02\t\t\t; ADD\n"); + break; + case SUB_TOKEN: + if (opt) + { + printf("\tJSR\tSUB\n"); +// printf("\tLDA\tESTKL+1,X\n"); +// printf("\tSEC\n"); +// printf("\tSBC\tESTKL,X\n"); +// printf("\tSTA\tESTKL+1,X\n"); +// printf("\tLDA\tESTKH+1,X\n"); +// printf("\tSBC\tESTKH,X\n"); +// printf("\tSTA\tESTKH+1,X\n"); +// INX; + } + else + printf("\tDB\t$04\t\t\t; SUB\n"); + break; + case SHL_TOKEN: + if (opt) + { + printf("\tJSR\tSHL\n"); + VALID_Y; + } + else + printf("\tDB\t$1A\t\t\t; SHL\n"); + break; + case SHR_TOKEN: + if (opt) + { + printf("\tJSR\tSHR\n"); + VALID_Y; + } + else + printf("\tDB\t$1C\t\t\t; SHR\n"); + break; + case AND_TOKEN: + if (opt) + printf("\tJSR\tBAND\n"); + else + printf("\tDB\t$14\t\t\t; BAND\n"); + break; + case OR_TOKEN: + if (opt) + printf("\tJSR\tIOR\n"); + else + printf("\tDB\t$16\t\t\t; IOR\n"); + break; + case EOR_TOKEN: + if (opt) + printf("\tJSR\tXOR\n"); + else + printf("\tDB\t$18\t\t\t; XOR\n"); + break; + case EQ_TOKEN: + if (opt) + { + VALIDATE_Y; + printf("\tJSR\tISEQ\n"); + INVALID_Y; + } + else + printf("\tDB\t$40\t\t\t; ISEQ\n"); + break; + case NE_TOKEN: + if (opt) + { + VALIDATE_Y; + printf("\tJSR\tISNE\n"); + INVALID_Y; + } + else + printf("\tDB\t$42\t\t\t; ISNE\n"); + break; + case GE_TOKEN: + if (opt) + { + VALIDATE_Y; + printf("\tJSR\tISGE\n"); + INVALID_Y; + } + else + printf("\tDB\t$48\t\t\t; ISGE\n"); + break; + case LT_TOKEN: + if (opt) + { + VALIDATE_Y; + printf("\tJSR\tISLT\n"); + INVALID_Y; + } + else + printf("\tDB\t$46\t\t\t; ISLT\n"); + break; + case GT_TOKEN: + if (opt) + { + VALIDATE_Y; + printf("\tJSR\tISGT\n"); + INVALID_Y; + } + else + printf("\tDB\t$44\t\t\t; ISGT\n"); + break; + case LE_TOKEN: + if (opt) + { + VALIDATE_Y; + printf("\tJSR\tISLE\n"); + INVALID_Y; + } + else + printf("\tDB\t$4A\t\t\t; ISLE\n"); + break; + case LOGIC_OR_TOKEN: + if (opt) + printf("\tJSR\tLOR\n"); + else + printf("\tDB\t$22\t\t\t; LOR\n"); + break; + case LOGIC_AND_TOKEN: + if (opt) + printf("\tJSR\tLAND\n"); + else + printf("\tDB\t$24\t\t\t; LAND\n"); + break; + case COMMA_TOKEN: + break; + default: + return (0); + } + return (1); +} diff --git a/plasma2/codegen.h b/plasma2/codegen.h new file mode 100755 index 0000000..050229e --- /dev/null +++ b/plasma2/codegen.h @@ -0,0 +1,55 @@ +#define EDASM 1 +void emit_flags(int flags); +int optimization(int level); +void emit_header(void); +void emit_trailer(void); +void emit_comment(char *s); +void emit_asm(char *s); +void emit_idlocal(char *name, int value); +void emit_idglobal(int value, int size, char *name); +void emit_idfunc(int value, char *name); +void emit_idconst(char *name, int value); +int emit_data(int vartype, int consttype, long constval, int constsize); +void emit_codetag(int tag); +void emit_const(int cval); +void emit_lb(void); +void emit_lw(void); +void emit_llb(int index); +void emit_llw(int index); +void emit_lab(int tag); +void emit_law(int tag); +void emit_sb(void); +void emit_sw(void); +void emit_slb(int index); +void emit_slw(int index); +void emit_dlb(int index); +void emit_dlw(int index); +void emit_sab(int tag); +void emit_saw(int tag); +void emit_dab(int tag); +void emit_daw(int tag); +void emit_call(int tag); +void emit_ical(void); +void emit_localaddr(int index); +void emit_globaladdr(int tag, int type); +void emit_globaladdrofst(int tag, int offset, int type); +void emit_indexbyte(void); +void emit_indexword(void); +int emit_unaryop(int op); +int emit_op(t_token op); +void emit_skptru(int tag); +void emit_skpfls(int tag); +void emit_skpgt(int tag); +void emit_skplt(int tag); +void emit_skpne(int tag); +void emit_skip(int tag); +void emit_swap(void); +void emit_dup(void); +void emit_push(void); +void emit_pull(void); +void emit_drop(void); +void emit_leave(int framesize); +void emit_ret(void); +void emit_def(int defopt); +void emit_enter(int framesize, int cparams); +void emit_start(void); diff --git a/plasma2/codegen.o b/plasma2/codegen.o new file mode 100755 index 0000000..cc21559 Binary files /dev/null and b/plasma2/codegen.o differ diff --git a/plasma2/default.cfg b/plasma2/default.cfg new file mode 100755 index 0000000..ebaf9ce --- /dev/null +++ b/plasma2/default.cfg @@ -0,0 +1,10 @@ +MEMORY { + RAM: start = $2000, size = $2800, file = %O; +} +SEGMENTS { + CODE: load = RAM, type = rw; + DATA: load = RAM, type = rw; + BSS: load = RAM, type = rw; +} + + diff --git a/plasma2/dumprel.pla b/plasma2/dumprel.pla new file mode 100755 index 0000000..8a7cc99 --- /dev/null +++ b/plasma2/dumprel.pla @@ -0,0 +1,189 @@ +const keyboard=$C000 +const keystrobe=$C010 +const iobuffer=$0800 +const databuff=$0C00 +const inbuff=$01FF +byte loadadr[] = "LOAD ADDRESS: $" +byte datasz[] = "DATA SIZE: $" +byte RLD[] = "RELOCATION DIRECTORY:" +byte ESD[] = "SYMBOL TABLE:" +byte errstr[] = "ERROR: " +byte perr + +def home + drop romcall(0, 0, 0, 0, $FC58) +end + +def gotoxy(x, y) + ^($24) = x + drop romcall(y, 0, 0, 0, $FB5B) +end + +def prbyte(val) + drop romcall(val, 0, 0, 0, $FDDA) +end + +def prword(val) + drop romcall(val >> 8, val, 0, 0, $F941) +end + +def crout + drop romcall(0, 0, 0, 0, $FD8E) +end + +def getpfx(path) + byte params[3] + + ^(path) = 0 + params.0 = 1 + params:1 = path + perr = syscall($C7, @params) + return path +end + +def getfileinfo(path, infoptr) + byte params[18] + + params.0 = 10 + params:1 = path + perr = syscall($C4, @params) + if not perr + memcpy(@params.3, infoptr, 15) + fin + return perr +end + +def open(path, buff) + byte params[6] + + params.0 = 3 + params:1 = path + params:3 = buff + params.5 = 0 + perr = syscall($C8, @params) + return params.5 +end + +def close(refnum) + byte params[2] + + params.0 = 1 + params.1 = refnum + perr = syscall($CC, @params) + return perr +end + +def read(refnum, buff, len) + byte params[8] + + params.0 = 4 + params.1 = refnum + params:2 = buff + params:4 = len + params:6 = 0 + perr = syscall($CA, @params) + return params:6 +end + +def dumpln(memptr, ofst, len) + byte i + + cout('$') + prword(ofst) + cout(':') + cout(' ') + len = len - 1 + for i = 0 to len + prbyte((memptr).[i]) + if i & 1 + cout(' ') + fin + next + cout(' ') + for i = 0 to len + if (memptr).[i] & $7F < ' ' + cout ('.') + else + cout((memptr).[i]) + fin + next + crout +end + +def dumprld(rld) + cout('$') + prbyte(^rld) + cout(':') + cout(' ') + cout('$') + prword(*(rld + 1)) + cout(' ') + cout('$') + prbyte(^(rld + 3)) + crout + return rld + 4 +end + +def dumpesd(esd) + while ^esd & $80 + cout(^esd) + esd = esd + 1 + loop + cout(^esd) + cout(':') + cout(' ') + cout('$') + prbyte(^(esd + 1)) + cout(' ') + cout('$') + prword(^(esd + 2)) + crout + return esd + 4 +end + +def dump(path) + byte refnum, info[15] + word len, ofst, datalen, rld, esd + + getfileinfo(path, @info) + prstr(@loadadr) + prword(info:2) + crout + refnum = open(path, iobuffer) + len = read(refnum, databuff, 512) + datalen = databuff:0 + prstr(@datasz) + prword(datalen) + crout + rld = databuff + datalen + 2 + ofst = 0 + while datalen > 8 + dumpln(databuff + 2 + ofst, ofst, 8) + ofst = ofst + 8 + datalen = datalen - 8 + loop + dumpln(databuff + 2 + ofst, ofst, datalen) + crout + prstr(@RLD) + crout + while ^rld + rld = dumprld(rld) + loop + crout + prstr(@ESD) + crout + esd = rld + 1 + while ^esd + esd = dumpesd(esd) + loop + drop close(refnum) +end + +def getlin + ^inbuff = romcall(0, 0, 0, 0, $FD6A).1 + return inbuff +end + +home +dump(getlin) +done diff --git a/plasma2/fire#ff0000 b/plasma2/fire#ff0000 new file mode 100755 index 0000000..ec761a7 Binary files /dev/null and b/plasma2/fire#ff0000 differ diff --git a/plasma2/fire.pla b/plasma2/fire.pla new file mode 100755 index 0000000..ca83a23 --- /dev/null +++ b/plasma2/fire.pla @@ -0,0 +1,269 @@ +CONST FALSE = 0 +CONST TRUE = NOT FALSE +CONST SHOWLORES = $C056 +CONST KEYBOARD = $C000 +CONST KEYSTROBE = $C010 +CONST EMPTY = 0 +CONST TREE = 4 +CONST FIRE = 13 +CONST FORESTSIZE = 42*42 +BYTE HELLOMSG[] = "PRESS ANY KEY TO BEGIN..." +BYTE EXITMSG[] = "PRESS ANY KEY TO EXIT." +BYTE GOODBYE[] = "THAT'S ALL FOLKS!" +BYTE TREES1[FORESTSIZE] +BYTE TREES2[FORESTSIZE] +WORD RNDNUM +; +; Defines for ASM routines +; +ASM EQUATES + SRC EQU $F0 + SRCL EQU SRC + SRCH EQU SRC+1 + DST EQU SRC+2 + DSTL EQU DST + DSTH EQU DST+1 + ESP EQU DST+2 +END +; +; CALL 6502 ROUTINE +; ROMCALL(AREG, XREG, YREG, STATUS, ADDR) +; +ASM ROMCALL +TMP EQU $06 + + PHP + LDA ESTKL,X + STA TMP + LDA ESTKH,X + STA TMP+1 + INX + LDA ESTKL,X + PHA + INX + LDA ESTKL,X + TAY + INX + LDA ESTKL+1,X + PHA + LDA ESTKL,X + INX + STX TMP+2 + TAX + PLA + BIT ROMIN + PLP + JSR JMPTMP + PHP + BIT LCBNK2 + STA REGVALS+0 + STX REGVALS+1 + STY REGVALS+2 + PLA + STA REGVALS+3 + LDX TMP+2 + LDA #REGVALS + STA ESTKL,X + STY ESTKH,X + PLP + RTS +JMPTMP: JMP (TMP) +REGVALS: DS 4 +END +; +; GRCOLOR(COLOR) +; +ASM GRCOLOR + LDA ESTKL,X + INX + STX TMP+2 + BIT $C081 + JSR $F864 + BIT $C080 + LDX TMP+2 +END +; +; GRPLOT(X, Y) +; +ASM GRPLOT + LDA ESTKL,X + INX + LDY ESTKL,X + INX + STX TMP+2 + BIT $C081 + JSR $F800 + BIT $C080 + LDX TMP+2 +END +; +; SET MEMORY TO VALUE +; MEMSET(VALUE, ADDR, SIZE) +; +ASM MEMSET + LDY #$00 + LDA ESTKL+1,X + STA DSTL + LDA ESTKH+1,X + STA DSTH + INC ESTKL,X + INC ESTKH,X +SETMEM: DEC ESTKL,X + BNE :+ + DEC ESTKH,X + BEQ MEMEXIT +: LDA ESTKL+2,X + STA (DST),Y + INY + BNE :+ + INC DSTH +: DEC ESTKL,X + BNE :+ + DEC ESTKH,X + BEQ MEMEXIT +: LDA ESTKH+2,X + STA (DST),Y + INY + BNE SETMEM + INC DSTH + BNE SETMEM +MEMEXIT: INX + INX + INX +END +; +; PRINT STRING +; PRSTR(STR) +; +ASM PRSTR + LDY #$00 + LDA ESTKL,X + STA SRCL + LDA ESTKH,X + STA SRCH + BIT ROMIN + LDA (SRC),Y + STA ESTKL,X + BEQ :+ +_PRS1: INY + LDA (SRC),Y + ORA #$80 + JSR $FDED + TYA + CMP ESTKL,X + BNE _PRS1 +: INX + BIT LCBNK2 +END +DEF TEXTMODE + DROP ROMCALL(0, 0, 0, 0, $FB39) +END + +DEF HOME + DROP ROMCALL(0, 0, 0, 0, $FC58) +END + +DEF GOTOXY(X, Y) + ^($24) = X + DROP ROMCALL(Y, 0, 0, 0, $FB5B) +END + +DEF GRMODE + DROP ROMCALL(0, 0, 0, 0, $FB40) + DROP ^SHOWLORES +END + +DEF RANDOMIZE(SEED) + RNDNUM = (SEED << 8) ? (SEED >> 8 & $FF) + SEED +END + +DEFOPT RND + RNDNUM = (RNDNUM << 8) + RNDNUM + 12345 + RETURN RNDNUM & $7FFF +END + +DEFOPT BYFIRE(TREEPTR) + IF ^(TREEPTR - 43) == FIRE + RETURN TRUE + ELSIF ^(TREEPTR - 42) == FIRE + RETURN TRUE + ELSIF ^(TREEPTR - 41) == FIRE + RETURN TRUE + ELSIF ^(TREEPTR - 1) == FIRE + RETURN TRUE + ELSIF ^(TREEPTR + 1) == FIRE + RETURN TRUE + ELSIF ^(TREEPTR + 41) == FIRE + RETURN TRUE + ELSIF ^(TREEPTR + 42) == FIRE + RETURN TRUE + ELSIF ^(TREEPTR + 43) == FIRE + RETURN TRUE + FIN + RETURN FALSE +END +DEFOPT FORESTFIRE + WORD NEWTREES, OLDTREES, NEWTREE, OLDTREE, YROW + BYTE X, Y + + MEMSET(EMPTY, @TREES1, FORESTSIZE) + MEMSET(EMPTY, @TREES2, FORESTSIZE) + OLDTREES = @TREES1 + NEWTREES = @TREES2 + + FOR Y = 1 TO 40 + YROW = Y * 42 + FOR X = 1 TO 40 + IF RND < 16384 + ^(OLDTREES + X + YROW) = TREE + FIN + NEXT + NEXT + WHILE ^$C000 < 128 + FOR Y = 1 TO 40 + YROW = Y * 42 + FOR X = 1 TO 40 + OLDTREE = OLDTREES + X + YROW + NEWTREE = NEWTREES + X + YROW + WHEN ^OLDTREE + IS EMPTY + IF RND < 400 + ^NEWTREE = TREE + ELSE + ^NEWTREE = EMPTY + FIN + IS TREE + IF RND < 10 OR BYFIRE(OLDTREE) + ^NEWTREE = FIRE + ELSE + ^NEWTREE = TREE + FIN + IS FIRE + ^NEWTREE = EMPTY + WEND + GRCOLOR(^NEWTREE) + GRPLOT(X - 1, Y - 1) + NEXT + NEXT + NEWTREES =, OLDTREES = OLDTREES, NEWTREES + LOOP + DROP ^$C010 +END + +PRSTR(@HELLOMSG) +WHILE ^$C000 < 128 + RNDNUM = RNDNUM + 1 +LOOP +RANDOMIZE(RNDNUM) +DROP ^$C010 +GRMODE +HOME +GOTOXY(10,22) +PRSTR(@EXITMSG) +FORESTFIRE +TEXTMODE +HOME +PRSTR(@GOODBYE) +DONE + diff --git a/plasma2/fire.s b/plasma2/fire.s new file mode 100755 index 0000000..e88722b --- /dev/null +++ b/plasma2/fire.s @@ -0,0 +1,1375 @@ + .INCLUDE "plstub.s" +; 1: CONST FALSE = 0 + ; FALSE = 0 +; 2: CONST TRUE = NOT FALSE + ; TRUE = -1 +; 3: CONST SHOWLORES = $C056 + ; SHOWLORES = 49238 +; 4: CONST KEYBOARD = $C000 + ; KEYBOARD = 49152 +; 5: CONST KEYSTROBE = $C010 + ; KEYSTROBE = 49168 +; 6: CONST EMPTY = 0 + ; EMPTY = 0 +; 7: CONST TREE = 4 + ; TREE = 4 +; 8: CONST FIRE = 13 + ; FIRE = 13 +; 9: CONST FORESTSIZE = 42*42 + ; FORESTSIZE = 1764 +; 10: BYTE HELLOMSG[] = "PRESS ANY KEY TO BEGIN..." +D0000: ; HELLOMSG + DB $19 + DB $50,$52,$45,$53,$53,$20,$41,$4E + DB $59,$20,$4B,$45,$59,$20,$54,$4F + DB $20,$42,$45,$47,$49,$4E,$2E,$2E + DB $2E +; 11: BYTE EXITMSG[] = "PRESS ANY KEY TO EXIT." +D0026: ; EXITMSG + DB $16 + DB $50,$52,$45,$53,$53,$20,$41,$4E + DB $59,$20,$4B,$45,$59,$20,$54,$4F + DB $20,$45,$58,$49,$54,$2E +; 12: BYTE GOODBYE[] = "THAT'S ALL FOLKS!" +D0049: ; GOODBYE + DB $11 + DB $54,$48,$41,$54,$27,$53,$20,$41 + DB $4C,$4C,$20,$46,$4F,$4C,$4B,$53 + DB $21 +; 13: BYTE TREES1[FORESTSIZE] +D0067: DS 1764 ; TREES1 +; 14: BYTE TREES2[FORESTSIZE] +D1831: DS 1764 ; TREES2 +; 15: WORD RNDNUM +D3595: DS 2 ; RNDNUM +; 16: ; +; 17: ; Defines for ASM routines +; 18: ; +; 19: ASM EQUATES +C0000: ; EQUATES() +; 20: SRC EQU $F0 + SRC EQU $F0 +; 21: SRCL EQU SRC + SRCL EQU SRC +; 22: SRCH EQU SRC+1 + SRCH EQU SRC+1 +; 23: DST EQU SRC+2 + DST EQU SRC+2 +; 24: DSTL EQU DST + DSTL EQU DST +; 25: DSTH EQU DST+1 + DSTH EQU DST+1 +; 26: ESP EQU DST+2 + ESP EQU DST+2 +; 27: END + RTS +; 28: ; +; 29: ; CALL 6502 ROUTINE +; 30: ; ROMCALL(AREG, XREG, YREG, STATUS, ADDR) +; 31: ; +; 32: ASM ROMCALL +C0002: ; ROMCALL() +; 33: TMP EQU $06 +TMP EQU $06 +; 34: +; 35: PHP + PHP +; 36: LDA ESTKL,X + LDA ESTKL,X +; 37: STA TMP + STA TMP +; 38: LDA ESTKH,X + LDA ESTKH,X +; 39: STA TMP+1 + STA TMP+1 +; 40: INX + INX +; 41: LDA ESTKL,X + LDA ESTKL,X +; 42: PHA + PHA +; 43: INX + INX +; 44: LDA ESTKL,X + LDA ESTKL,X +; 45: TAY + TAY +; 46: INX + INX +; 47: LDA ESTKL+1,X + LDA ESTKL+1,X +; 48: PHA + PHA +; 49: LDA ESTKL,X + LDA ESTKL,X +; 50: INX + INX +; 51: STX TMP+2 + STX TMP+2 +; 52: TAX + TAX +; 53: PLA + PLA +; 54: BIT ROMIN + BIT ROMIN +; 55: PLP + PLP +; 56: JSR JMPTMP + JSR JMPTMP +; 57: PHP + PHP +; 58: BIT LCBNK2 + BIT LCBNK2 +; 59: STA REGVALS+0 + STA REGVALS+0 +; 60: STX REGVALS+1 + STX REGVALS+1 +; 61: STY REGVALS+2 + STY REGVALS+2 +; 62: PLA + PLA +; 63: STA REGVALS+3 + STA REGVALS+3 +; 64: LDX TMP+2 + LDX TMP+2 +; 65: LDA #REGVALS + LDY #>REGVALS +; 67: STA ESTKL,X + STA ESTKL,X +; 68: STY ESTKH,X + STY ESTKH,X +; 69: PLP + PLP +; 70: RTS + RTS +; 71: JMPTMP: JMP (TMP) +JMPTMP: JMP (TMP) +; 72: REGVALS: DS 4 +REGVALS: DS 4 +; 73: END + RTS +; 74: ; +; 75: ; GRCOLOR(COLOR) +; 76: ; +; 77: ASM GRCOLOR +C0004: ; GRCOLOR() +; 78: LDA ESTKL,X + LDA ESTKL,X +; 79: INX + INX +; 80: STX TMP+2 + STX TMP+2 +; 81: BIT $C081 + BIT $C081 +; 82: JSR $F864 + JSR $F864 +; 83: BIT $C080 + BIT $C080 +; 84: LDX TMP+2 + LDX TMP+2 +; 85: END + RTS +; 86: ; +; 87: ; GRPLOT(X, Y) +; 88: ; +; 89: ASM GRPLOT +C0006: ; GRPLOT() +; 90: LDA ESTKL,X + LDA ESTKL,X +; 91: INX + INX +; 92: LDY ESTKL,X + LDY ESTKL,X +; 93: INX + INX +; 94: STX TMP+2 + STX TMP+2 +; 95: BIT $C081 + BIT $C081 +; 96: JSR $F800 + JSR $F800 +; 97: BIT $C080 + BIT $C080 +; 98: LDX TMP+2 + LDX TMP+2 +; 99: END + RTS +; 100: ; +; 101: ; SET MEMORY TO VALUE +; 102: ; MEMSET(VALUE, ADDR, SIZE) +; 103: ; +; 104: ASM MEMSET +C0008: ; MEMSET() +; 105: LDY #$00 + LDY #$00 +; 106: LDA ESTKL+1,X + LDA ESTKL+1,X +; 107: STA DSTL + STA DSTL +; 108: LDA ESTKH+1,X + LDA ESTKH+1,X +; 109: STA DSTH + STA DSTH +; 110: INC ESTKL,X + INC ESTKL,X +; 111: INC ESTKH,X + INC ESTKH,X +; 112: SETMEM: DEC ESTKL,X +SETMEM: DEC ESTKL,X +; 113: BNE :+ + BNE :+ +; 114: DEC ESTKH,X + DEC ESTKH,X +; 115: BEQ MEMEXIT + BEQ MEMEXIT +; 116: : LDA ESTKL+2,X +: LDA ESTKL+2,X +; 117: STA (DST),Y + STA (DST),Y +; 118: INY + INY +; 119: BNE :+ + BNE :+ +; 120: INC DSTH + INC DSTH +; 121: : DEC ESTKL,X +: DEC ESTKL,X +; 122: BNE :+ + BNE :+ +; 123: DEC ESTKH,X + DEC ESTKH,X +; 124: BEQ MEMEXIT + BEQ MEMEXIT +; 125: : LDA ESTKH+2,X +: LDA ESTKH+2,X +; 126: STA (DST),Y + STA (DST),Y +; 127: INY + INY +; 128: BNE SETMEM + BNE SETMEM +; 129: INC DSTH + INC DSTH +; 130: BNE SETMEM + BNE SETMEM +; 131: MEMEXIT: INX +MEMEXIT: INX +; 132: INX + INX +; 133: INX + INX +; 134: END + RTS +; 135: ; +; 136: ; PRINT STRING +; 137: ; PRSTR(STR) +; 138: ; +; 139: ASM PRSTR +C0010: ; PRSTR() +; 140: LDY #$00 + LDY #$00 +; 141: LDA ESTKL,X + LDA ESTKL,X +; 142: STA SRCL + STA SRCL +; 143: LDA ESTKH,X + LDA ESTKH,X +; 144: STA SRCH + STA SRCH +; 145: BIT ROMIN + BIT ROMIN +; 146: LDA (SRC),Y + LDA (SRC),Y +; 147: STA ESTKL,X + STA ESTKL,X +; 148: BEQ :+ + BEQ :+ +; 149: _PRS1: INY +_PRS1: INY +; 150: LDA (SRC),Y + LDA (SRC),Y +; 151: ORA #$80 + ORA #$80 +; 152: JSR $FDED + JSR $FDED +; 153: TYA + TYA +; 154: CMP ESTKL,X + CMP ESTKL,X +; 155: BNE _PRS1 + BNE _PRS1 +; 156: : INX +: INX +; 157: BIT LCBNK2 + BIT LCBNK2 +; 158: END + RTS +; 159: DEF TEXTMODE +C0012: ; TEXTMODE() +; 160: DROP ROMCALL(0, 0, 0, 0, $FB39) + JSR _INTERP + DB $00 ; ZERO + DB $00 ; ZERO + DB $00 ; ZERO + DB $00 ; ZERO + DB $2C,$39,$FB ; CW 64313 + DB $54,C0002 ; CALL C0002 + DB $30 ; DROP +; 161: END + DB $5C ; RET +; 162: +; 163: DEF HOME +C0014: ; HOME() +; 164: DROP ROMCALL(0, 0, 0, 0, $FC58) + JSR _INTERP + DB $00 ; ZERO + DB $00 ; ZERO + DB $00 ; ZERO + DB $00 ; ZERO + DB $2C,$58,$FC ; CW 64600 + DB $54,C0002 ; CALL C0002 + DB $30 ; DROP +; 165: END + DB $5C ; RET +; 166: +; 167: DEF GOTOXY(X, Y) +C0016: ; GOTOXY() + ; X = 2 + ; Y = 4 +; 168: ^($24) = X + JSR _INTERP + DB $58,$06,$02 ; ENTER 6,2 + DB $2A,$24 ; CB 36 + DB $66,$02 ; LLW 2 + DB $70 ; SB +; 169: DROP ROMCALL(Y, 0, 0, 0, $FB5B) + DB $66,$04 ; LLW 4 + DB $00 ; ZERO + DB $00 ; ZERO + DB $00 ; ZERO + DB $2C,$5B,$FB ; CW 64347 + DB $54,C0002 ; CALL C0002 + DB $30 ; DROP +; 170: END + DB $5A ; LEAVE +; 171: +; 172: DEF GRMODE +C0018: ; GRMODE() +; 173: DROP ROMCALL(0, 0, 0, 0, $FB40) + JSR _INTERP + DB $00 ; ZERO + DB $00 ; ZERO + DB $00 ; ZERO + DB $00 ; ZERO + DB $2C,$40,$FB ; CW 64320 + DB $54,C0002 ; CALL C0002 + DB $30 ; DROP +; 174: DROP ^SHOWLORES + DB $2C,$56,$C0 ; CW 49238 + DB $60 ; LB + DB $30 ; DROP +; 175: END + DB $5C ; RET +; 176: +; 177: DEF RANDOMIZE(SEED) +C0020: ; RANDOMIZE() + ; SEED = 2 +; 178: RNDNUM = (SEED << 8) ? (SEED >> 8 & $FF) + SEED + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $66,$02 ; LLW 2 + DB $2A,$08 ; CB 8 + DB $1A ; SHL + DB $66,$02 ; LLW 2 + DB $2A,$08 ; CB 8 + DB $1C ; SHR + DB $2A,$FF ; CB 255 + DB $14 ; BAND + DB $66,$02 ; LLW 2 + DB $02 ; ADD + DB $16 ; IOR + DB $7A,D3595 ; SAW D3595 +; 179: END + DB $5A ; LEAVE +; 180: +; 181: DEFOPT RND +C0022: ; RND() +; 182: RNDNUM = (RNDNUM << 8) + RNDNUM + 12345 + DEX + LDA D3595 + STA ESTKL,X + LDA D3595+1 + STA ESTKH,X + DEX + LDA #$08 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SHL + DEX + LDA D3595 + STA ESTKL,X + LDA D3595+1 + STA ESTKH,X + JSR ADD + DEX + LDA #$39 + STA ESTKL,X + LDA #$30 + STA ESTKH,X + JSR ADD + LDA ESTKL,X + STA D3595 + LDA ESTKH,X + STA D3595+1 +; 183: RETURN RNDNUM & $7FFF + LDA D3595 + STA ESTKL,X + LDA D3595+1 + STA ESTKH,X + DEX + LDA #$FF + STA ESTKL,X + LDA #$7F + STA ESTKH,X + JSR BAND + RTS +; 184: END +; 185: +; 186: DEFOPT BYFIRE(TREEPTR) +C0024: ; BYFIRE() + ; TREEPTR = 2 +; 187: IF ^(TREEPTR - 43) == FIRE + LDY #4 + LDA #1 + JSR ENTER + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$2B + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SUB + JSR LB + DEX + LDA #$0D + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0026 +: +; 188: RETURN TRUE + DEX + LDA #$FF + STA ESTKL,X + STA ESTKH,X + JMP LEAVE +; 189: ELSIF ^(TREEPTR - 42) == FIRE + JMP C0027 +C0026: + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$2A + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SUB + JSR LB + DEX + LDA #$0D + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0028 +: +; 190: RETURN TRUE + DEX + LDA #$FF + STA ESTKL,X + STA ESTKH,X + JMP LEAVE +; 191: ELSIF ^(TREEPTR - 41) == FIRE + JMP C0027 +C0028: + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$29 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SUB + JSR LB + DEX + LDA #$0D + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0029 +: +; 192: RETURN TRUE + DEX + LDA #$FF + STA ESTKL,X + STA ESTKH,X + JMP LEAVE +; 193: ELSIF ^(TREEPTR - 1) == FIRE + JMP C0027 +C0029: + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SUB + JSR LB + DEX + LDA #$0D + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0030 +: +; 194: RETURN TRUE + DEX + LDA #$FF + STA ESTKL,X + STA ESTKH,X + JMP LEAVE +; 195: ELSIF ^(TREEPTR + 1) == FIRE + JMP C0027 +C0030: + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDA #$0D + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0031 +: +; 196: RETURN TRUE + DEX + LDA #$FF + STA ESTKL,X + STA ESTKH,X + JMP LEAVE +; 197: ELSIF ^(TREEPTR + 41) == FIRE + JMP C0027 +C0031: + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$29 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDA #$0D + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0032 +: +; 198: RETURN TRUE + DEX + LDA #$FF + STA ESTKL,X + STA ESTKH,X + JMP LEAVE +; 199: ELSIF ^(TREEPTR + 42) == FIRE + JMP C0027 +C0032: + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$2A + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDA #$0D + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0033 +: +; 200: RETURN TRUE + DEX + LDA #$FF + STA ESTKL,X + STA ESTKH,X + JMP LEAVE +; 201: ELSIF ^(TREEPTR + 43) == FIRE + JMP C0027 +C0033: + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$2B + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDA #$0D + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0034 +: +; 202: RETURN TRUE + DEX + LDA #$FF + STA ESTKL,X + STA ESTKH,X + JMP LEAVE +; 203: FIN +C0034: +C0027: +; 204: RETURN FALSE + DEX + LDY #$00 + STY ESTKL,X + STY ESTKH,X + JMP LEAVE +; 205: END +; 206: DEFOPT FORESTFIRE +C0035: ; FORESTFIRE() +; 207: WORD NEWTREES, OLDTREES, NEWTREE, OLDTREE, YROW + ; NEWTREES = 2 + ; OLDTREES = 4 + ; NEWTREE = 6 + ; OLDTREE = 8 + ; YROW = 10 +; 208: BYTE X, Y + ; X = 12 + ; Y = 13 +; 209: +; 210: MEMSET(EMPTY, @TREES1, FORESTSIZE) + LDY #14 + LDA #0 + JSR ENTER + DEX + STY ESTKL,X + STY ESTKH,X + DEX + LDA #D0067 + STA ESTKH,X + DEX + LDA #$E4 + STA ESTKL,X + LDA #$06 + STA ESTKH,X + JSR C0008 +; 211: MEMSET(EMPTY, @TREES2, FORESTSIZE) + DEX + LDY #$00 + STY ESTKL,X + STY ESTKH,X + DEX + LDA #D1831 + STA ESTKH,X + DEX + LDA #$E4 + STA ESTKL,X + LDA #$06 + STA ESTKH,X + JSR C0008 +; 212: OLDTREES = @TREES1 + DEX + LDA #D0067 + STA ESTKH,X + LDY #$04 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 213: NEWTREES = @TREES2 + LDA #D1831 + STA ESTKH,X + LDY #$02 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 214: +; 215: FOR Y = 1 TO 40 + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X +C0038: + LDY #$0D + LDA ESTKL,X + STA (FRMP),Y + DEX + LDA #$28 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + LDA ESTKH-1,X + SBC ESTKH,X + BPL :+ + JMP C0037 +: + INC ESTKL,X + BNE :+ + INC ESTKH,X +: +; 216: YROW = Y * 42 + DEX + LDY #$0D + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA #$2A + STA ESTKL,X + STY ESTKH,X + JSR MUL + LDY #$0A + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 217: FOR X = 1 TO 40 + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X +C0040: + LDY #$0C + LDA ESTKL,X + STA (FRMP),Y + DEX + LDA #$28 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + LDA ESTKH-1,X + SBC ESTKH,X + BPL :+ + JMP C0039 +: + INC ESTKL,X + BNE :+ + INC ESTKH,X +: +; 218: IF RND < 16384 + JSR C0022 + DEX + LDY #$00 + STY ESTKL,X + LDA #$40 + STA ESTKH,X + JSR ISLT + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0041 +: +; 219: ^(OLDTREES + X + YROW) = TREE + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$0C + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + DEX + LDY #$0A + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JSR ADD + DEX + LDA #$04 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SB +; 220: FIN +C0041: +C0042: +; 221: NEXT + JMP C0040 +C0039: +; 222: NEXT + INX + JMP C0038 +C0037: +; 223: WHILE ^$C000 < 128 + INX +C0043: + DEX + LDY #$00 + STY ESTKL,X + LDA #$C0 + STA ESTKH,X + JSR LB + DEX + LDA #$80 + STA ESTKL,X + STY ESTKH,X + JSR ISLT + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0044 +: +; 224: FOR Y = 1 TO 40 + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X +C0046: + LDY #$0D + LDA ESTKL,X + STA (FRMP),Y + DEX + LDA #$28 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + LDA ESTKH-1,X + SBC ESTKH,X + BPL :+ + JMP C0045 +: + INC ESTKL,X + BNE :+ + INC ESTKH,X +: +; 225: YROW = Y * 42 + DEX + LDY #$0D + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA #$2A + STA ESTKL,X + STY ESTKH,X + JSR MUL + LDY #$0A + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 226: FOR X = 1 TO 40 + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X +C0048: + LDY #$0C + LDA ESTKL,X + STA (FRMP),Y + DEX + LDA #$28 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + LDA ESTKH-1,X + SBC ESTKH,X + BPL :+ + JMP C0047 +: + INC ESTKL,X + BNE :+ + INC ESTKH,X +: +; 227: OLDTREE = OLDTREES + X + YROW + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$0C + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + DEX + LDY #$0A + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JSR ADD + LDY #$08 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 228: NEWTREE = NEWTREES + X + YROW + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$0C + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + DEX + LDY #$0A + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JSR ADD + LDY #$06 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 229: WHEN ^OLDTREE + LDY #$08 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR LB +; 230: IS EMPTY + DEX + STY ESTKL,X + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0050 +: +; 231: IF RND < 400 + JSR C0022 + DEX + LDA #$90 + STA ESTKL,X + LDA #$01 + STA ESTKH,X + LDY #$00 + JSR ISLT + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0051 +: +; 232: ^NEWTREE = TREE + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$04 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SB +; 233: ELSE + JMP C0052 +C0051: +; 234: ^NEWTREE = EMPTY + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$00 + STY ESTKL,X + STY ESTKH,X + JSR SB +; 235: FIN +C0052: +; 236: IS TREE + JMP C0049 +C0050: + DEX + LDA #$04 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0053 +: +; 237: IF RND < 10 OR BYFIRE(OLDTREE) + JSR C0022 + DEX + LDA #$0A + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ISLT + DEX + LDY #$08 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JSR C0024 + JSR LOR + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0054 +: +; 238: ^NEWTREE = FIRE + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$0D + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SB +; 239: ELSE + JMP C0055 +C0054: +; 240: ^NEWTREE = TREE + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$04 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SB +; 241: FIN +C0055: +; 242: IS FIRE + JMP C0049 +C0053: + DEX + LDA #$0D + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0056 +: +; 243: ^NEWTREE = EMPTY + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$00 + STY ESTKL,X + STY ESTKH,X + JSR SB +; 244: WEND + JMP C0049 +C0056: +C0049: +; 245: GRCOLOR(^NEWTREE) + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR LB + JSR C0004 +; 246: GRPLOT(X - 1, Y - 1) + DEX + LDY #$0C + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR SUB + DEX + LDY #$0D + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR SUB + JSR C0006 +; 247: NEXT + JMP C0048 +C0047: +; 248: NEXT + INX + JMP C0046 +C0045: +; 249: NEWTREES =, OLDTREES = OLDTREES, NEWTREES + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$04 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y + INX + LDY #$02 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 250: LOOP + INX + JMP C0043 +C0044: +; 251: DROP ^$C010 + DEX + LDA #$10 + STA ESTKL,X + LDA #$C0 + STA ESTKH,X + LDY #$00 + JSR LB +; 252: END + INX + JMP LEAVE +; 253: +; 254: PRSTR(@HELLOMSG) +START: ; JSR INTERP + DB $26,D0000 ; LA D0000 + DB $54,C0010 ; CALL C0010 +; 255: WHILE ^$C000 < 128 +C0058: + DB $2C,$00,$C0 ; CW 49152 + DB $60 ; LB + DB $2A,$80 ; CB 128 + DB $46 ; ISLT + DB $4C,C0059 ; SKPFLS C0059 +; 256: RNDNUM = RNDNUM + 1 + DB $6A,D3595 ; LAW D3595 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $7A,D3595 ; SAW D3595 +; 257: LOOP + DB $50,C0058 ; SKIP C0058 +C0059: +; 258: RANDOMIZE(RNDNUM) + DB $6A,D3595 ; LAW D3595 + DB $54,C0020 ; CALL C0020 +; 259: DROP ^$C010 + DB $2C,$10,$C0 ; CW 49168 + DB $60 ; LB + DB $30 ; DROP +; 260: GRMODE + DB $54,C0018 ; CALL C0018 +; 261: HOME + DB $54,C0014 ; CALL C0014 +; 262: GOTOXY(10,22) + DB $2A,$0A ; CB 10 + DB $2A,$16 ; CB 22 + DB $54,C0016 ; CALL C0016 +; 263: PRSTR(@EXITMSG) + DB $26,D0026 ; LA D0026 + DB $54,C0010 ; CALL C0010 +; 264: FORESTFIRE + DB $54,C0035 ; CALL C0035 +; 265: TEXTMODE + DB $54,C0012 ; CALL C0012 +; 266: HOME + DB $54,C0014 ; CALL C0014 +; 267: PRSTR(@GOODBYE) + DB $26,D0049 ; LA D0049 + DB $54,C0010 ; CALL C0010 +; 268: DONE + DB $5C ; RET diff --git a/plasma2/fire.sys b/plasma2/fire.sys new file mode 100755 index 0000000..ec761a7 Binary files /dev/null and b/plasma2/fire.sys differ diff --git a/plasma2/interp6502.s b/plasma2/interp6502.s new file mode 100755 index 0000000..1e9a60c --- /dev/null +++ b/plasma2/interp6502.s @@ -0,0 +1,1023 @@ +.DEFINE EQU = +.DEFINE DB .BYTE +.DEFINE DW .WORD +.DEFINE DS .RES + +;********************************************************** +;* +;* VM ZERO PAGE LOCATIONS +;* +;********************************************************** +ESTKSZ EQU $20 +ESTK EQU $C0 +ESTKL EQU ESTK +ESTKH EQU ESTK+ESTKSZ/2 +VMZP EQU ESTK+ESTKSZ +FRMP EQU VMZP+$00 +FRMPL EQU FRMP +FRMPH EQU FRMP+1 +PC EQU VMZP+$02 +PCL EQU PC +PCH EQU PC+1 +TICK EQU VMZP+$04 +ESP EQU VMZP+$05 + +TMP EQU VMZP+$0A +TMPL EQU TMP +TMPH EQU TMP+1 +TMPX EQU TMP+2 +NPARMS EQU TMPL +FRMSZ EQU TMPH +DVSIGN EQU TMPX +JSROP EQU VMZP+$0D + + JMP PLASMA + DB $EE,$EE + DB 65,00 + DS 64 +;* +;* INIT AND ENTER INTO PLASMA BYTECODE INTERPRETER +;* +PLASMA: CLD + LDY #$20 +: LDA PAGE3,Y + STA $03D0,Y + DEY + BPL :- + LDA #$00 + LDY #$BF + STA FRMPL + STY FRMPH + LDX #$FE ; LEAVE $1FF AVAIL FOR RDSTR() + TXS + LDX #ESTKSZ/2 + STX ESP + LDA #$6C + STA JSROP + LDA #>OPTBL + STA JSROP+2 + LDA #>START + STA PCL + LDA # +#include "tokens.h" + +char *statement, *scanpos, *tokenstr; +t_token scantoken, prevtoken; +int tokenlen; +long constval; +int lineno = 0; +t_token keywords[] = { + IF_TOKEN, 'I', 'F', + ELSE_TOKEN, 'E', 'L', 'S', 'E', + ELSEIF_TOKEN, 'E', 'L', 'S', 'I', 'F', + FIN_TOKEN, 'F', 'I', 'N', + WHILE_TOKEN, 'W', 'H', 'I', 'L', 'E', + LOOP_TOKEN, 'L', 'O', 'O', 'P', + CASE_TOKEN, 'W', 'H', 'E', 'N', + OF_TOKEN, 'I', 'S', + DEFAULT_TOKEN, 'O', 'T', 'H', 'E', 'R', 'W', 'I', 'S', 'E', + ENDCASE_TOKEN, 'W', 'E', 'N', 'D', + FOR_TOKEN, 'F', 'O', 'R', + TO_TOKEN, 'T', 'O', + DOWNTO_TOKEN, 'D', 'O', 'W', 'N', 'T', 'O', + STEP_TOKEN, 'S', 'T', 'E', 'P', + NEXT_TOKEN, 'N', 'E', 'X', 'T', + REPEAT_TOKEN, 'R', 'E', 'P', 'E', 'A', 'T', + UNTIL_TOKEN, 'U', 'N', 'T', 'I', 'L', + BREAK_TOKEN, 'B', 'R', 'E', 'A', 'K', + ASM_TOKEN, 'A', 'S', 'M', + IFUNC_TOKEN, 'D', 'E', 'F', + NFUNC_TOKEN, 'D', 'E', 'F', 'O', 'P', 'T', + DROP_TOKEN, 'D', 'R', 'O', 'P', + RETURN_TOKEN, 'R', 'E', 'T', 'U', 'R', 'N', + END_TOKEN, 'E', 'N', 'D', + START_TOKEN, 'S', 'T', 'A', 'R', 'T', + DONE_TOKEN, 'D', 'O', 'N', 'E', + LOGIC_NOT_TOKEN, 'N', 'O', 'T', + LOGIC_AND_TOKEN, 'A', 'N', 'D', + LOGIC_OR_TOKEN, 'O', 'R', + BYTE_TOKEN, 'B', 'Y', 'T', 'E', + WORD_TOKEN, 'W', 'O', 'R', 'D', + CONST_TOKEN, 'C', 'O', 'N', 'S', 'T', + FUNC_TOKEN, 'F', 'U', 'N', 'C', + EOL_TOKEN + }; + +void parse_error(char *errormsg) +{ + char *error_carrot = statement; + + fprintf(stderr, "\n%4d: %s\n ", lineno, statement); + for (error_carrot = statement; error_carrot != tokenstr; error_carrot++) + putc(*error_carrot == '\t' ? '\t' : ' ', stderr); + fprintf(stderr, "^\nError: %s\n", errormsg); +} +t_token scan(void) +{ + prevtoken = scantoken; + /* + * Skip whitespace. + */ + while (*scanpos && (*scanpos == ' ' || *scanpos == '\t')) scanpos++; + tokenstr = scanpos; + /* + * Scan for token based on first character. + */ + if (*scanpos == '\0' || *scanpos == '\n' ||*scanpos == ';') + scantoken = EOL_TOKEN; + else if ((scanpos[0] >= 'a' && scanpos[0] <= 'z') + || (scanpos[0] >= 'A' && scanpos[0] <= 'Z') + || (scanpos[0] == '_')) + { + /* + * ID, either variable name or reserved word. + */ + int keypos = 0, matchpos = 0; + + do + { + scanpos++; + } while ((*scanpos >= 'a' && *scanpos <= 'z') + || (*scanpos >= 'A' && *scanpos <= 'Z') + || (*scanpos == '_') + || (*scanpos >= '0' && *scanpos <= '9')); + scantoken = ID_TOKEN; + tokenlen = scanpos - tokenstr; + /* + * Search for matching keyword. + */ + while (keywords[keypos] != EOL_TOKEN) + { + while (keywords[keypos + 1 + matchpos] == toupper(tokenstr[matchpos])) + matchpos++; + if (IS_TOKEN(keywords[keypos + 1 + matchpos]) && (matchpos == tokenlen)) + { + /* + * A match. + */ + scantoken = keywords[keypos]; + break; + } + else + { + /* + * Find next keyword. + */ + keypos += matchpos + 1; + matchpos = 0; + while (!IS_TOKEN(keywords[keypos])) keypos++; + } + } + } + else if (scanpos[0] >= '0' && scanpos[0] <= '9') + { + /* + * Number constant. + */ + for (constval = 0; *scanpos >= '0' && *scanpos <= '9'; scanpos++) + constval = constval * 10 + *scanpos - '0'; + scantoken = INT_TOKEN; + } + else if (scanpos[0] == '$') + { + /* + * Hexadecimal constant. + */ + constval = 0; + while (scanpos++) + { + if (*scanpos >= '0' && *scanpos <= '9') + constval = constval * 16 + *scanpos - '0'; + else if (*scanpos >= 'A' && *scanpos <= 'F') + constval = constval * 16 + *scanpos - 'A' + 10; + else if (*scanpos >= 'a' && *scanpos <= 'f') + constval = constval * 16 + *scanpos - 'a' + 10; + else + break; + } + scantoken = INT_TOKEN; + } + else if (scanpos[0] == '\'') + { + /* + * Character constant. + */ + scantoken = CHAR_TOKEN; + if (scanpos[1] != '\\') + { + constval = scanpos[1]; + if (scanpos[2] != '\'') + { + + parse_error("Bad character constant"); + return (-1); + } + scanpos += 3; + } + else + { + switch (scanpos[2]) + { + case 'n': + constval = '\n'; + break; + case 'r': + constval = '\r'; + break; + case 't': + constval = '\t'; + break; + case '\'': + constval = '\''; + case '\\': + constval = '\\'; + case '0': + constval = '\0'; + break; + default: + parse_error("Bad character constant"); + return (-1); + } + if (scanpos[3] != '\'') + { + + parse_error("Bad character constant"); + return (-1); + } + scanpos += 4; + } + } + else if (scanpos[0] == '\"') + { + /* + * String constant. + */ + scantoken = STRING_TOKEN; + constval = (long)++scanpos; + while (*scanpos && *scanpos != '\"') + scanpos++; + if (!*scanpos++) + { + parse_error("Unterminated string"); + return (-1); + } + } + else switch (scanpos[0]) + { + /* + * Potential two and three character tokens. + */ + case '>': + if (scanpos[1] == '>') + { + scantoken = SHR_TOKEN; + scanpos += 2; + } + else if (scanpos[1] == '=') + { + scantoken = GE_TOKEN; + scanpos += 2; + } + else + { + scantoken = GT_TOKEN; + scanpos++; + } + break; + case '<': + if (scanpos[1] == '<') + { + scantoken = SHL_TOKEN; + scanpos += 2; + } + else if (scanpos[1] == '=') + { + scantoken = LE_TOKEN; + scanpos += 2; + } + else if (scanpos[1] == '>') + { + scantoken = NE_TOKEN; + scanpos += 2; + } + else + { + scantoken = LT_TOKEN; + scanpos++; + } + break; + case '=': + if (scanpos[1] == '=') + { + scantoken = EQ_TOKEN; + scanpos += 2; + } + else if (scanpos[1] == ',') + { + scantoken = SETLIST_TOKEN; + scanpos += 2; + } + else + { + scantoken = SET_TOKEN; + scanpos++; + } + break; + case '+': + if (scanpos[1] == '+') + { + scantoken = INC_TOKEN; + scanpos += 2; + } + else + { + scantoken = ADD_TOKEN; + scanpos++; + } + break; + case '-': + if (scanpos[1] == '-') + { + scantoken = DEC_TOKEN; + scanpos += 2; + } + else + { + scantoken = SUB_TOKEN; + scanpos++; + } + break; + default: + /* + * Simple single character tokens. + */ + scantoken = TOKEN(*scanpos++); + } + tokenlen = scanpos - tokenstr; + return (scantoken); +} +void scan_rewind(char *backptr) +{ + scanpos = backptr; +} +char inputline[128]; +int next_line(void) +{ + gets(inputline); + lineno++; + statement = inputline; + scanpos = inputline; + scantoken = EOL_TOKEN; + scan(); + printf("; %4d: %s\n", lineno, inputline); + return (1); +} diff --git a/plasma2/lex.h b/plasma2/lex.h new file mode 100755 index 0000000..4726b57 --- /dev/null +++ b/plasma2/lex.h @@ -0,0 +1,9 @@ +extern char *statement, *scanpos, *tokenstr; +extern t_token scantoken, prevtoken; +extern int tokenlen; +extern long constval; +extern char inputline[]; +void parse_error(char *errormsg); +int next_line(void); +void scan_rewind(char *backptr); +t_token scan(void); diff --git a/plasma2/lex.o b/plasma2/lex.o new file mode 100755 index 0000000..f20da2c Binary files /dev/null and b/plasma2/lex.o differ diff --git a/plasma2/loadcmd.s b/plasma2/loadcmd.s new file mode 100755 index 0000000..f5afaef --- /dev/null +++ b/plasma2/loadcmd.s @@ -0,0 +1,92 @@ +.PC02 +.DEFINE EQU = +.DEFINE DB .BYTE +.DEFINE DW .WORD +.DEFINE DS .RES +;* +;* LANGUAGE CARD CONTROL +;* +LCBNK2 EQU $C080 +ROMIN EQU $C081 +;********************************************************** +;* +;* VM ZERO PAGE LOCATIONS +;* +;********************************************************** +ESTKSZ EQU $20 +ESTK EQU $C0 +ESTKL EQU ESTK +ESTKH EQU ESTK+ESTKSZ/2 +FRMP EQU ESTK+ESTKSZ +FRMPL EQU FRMP +FRMPH EQU FRMP+1 +TMP EQU $F0 +TMPL EQU TMP +TMPH EQU TMP+1 +SRC EQU TMP +SRCL EQU SRC +SRCH EQU SRC+1 +DST EQU SRC+2 +DSTL EQU DST +DSTH EQU DST+1 +ESP EQU DST+2 +;* +;* PAGE 3 ENTRYPOINTS TO INTERNAL ROUTINES +;* +_INTERP EQU $03D0 +LEAVE EQU $03DC +ENTER EQU $03E2 +;* +;* CLEAR COMMAND LINE LENGTH BYTE IF CALLED FROM 'BYE' +;* + LDY #$00 + LDX #$FE ; LEAVE ROOM FOR COMMAND LINE LENGTH BYTE + TXS + BVS :+ + STY $01FF ; CLEAR AUTORUN COMMAND WHEN CALLED FROM 'BYE' +;* +;* MOVE REST OF CMD FROM LANGUAGE CARD +;* +: STY $06 + STY $08 + LDA #$D2 + STA $07 + LDA #$11 + STA $09 + BIT LCBNK2 +MVVM: LDA ($06),Y + STA ($08),Y + INY + BNE MVVM + INC $07 + INC $09 + LDA $07 + CMP #$E0 + BNE MVVM +;* +;* DEACTIVATE 80 COL CARDS +;* + BIT ROMIN + LDY #4 +: LDA DISABLE80,Y + JSR $FDED + DEY + BPL :- + BIT $C054 ; SET TEXT MODE + BIT $C051 + BIT $C058 + JSR $FC58 ; HOME + +;* +;* JUMP TO INTERPRETER +;* + BIT LCBNK2 + LDX #$00 + LDA #$BF + STX FRMPL + STA FRMPH + LDY #>START + LDA #> 8, VAL, 0, 0, $F941) +END +DEF ADDSYM(TYPE, ADDR, SYMSTR) + (LOMEM).0 = TYPE + (LOMEM):1 = ADDR + (LOMEM).3 = ^SYMSTR + MEMCPY(SYMSTR + 1, LOMEM + 4, ^SYMSTR) + LOMEM = LOMEM + 4 + ^SYMSTR +END +DEF INITPLASMA + BYTE PARAMS[2] + + CROUT + PRSTR(@PLASMASTR) + CROUT + ^$BFD8 = 0 ; CLOSE ALL OPEN FILES + PARAMS.0 = 1 + PARAMS.1 = 0 + SYSCALL($CC, @PARAMS) + MEMSET($0000, $BF58, 24) ; RESET SYS BITMAP + ^$BF58 = $C0 + ^$BF6F = $01 + ; + ; SET INIT MEMORY BOUNDARIES + ; + HIMEM = $BF00 + LOMEM = $0800 + MODICT = LOMEM + ; + ; INIT SYMBOL DICTIONARY + ; + ADDSYM(FUNC_TYPE, @MEMSET, @MEMSETSTR) + ADDSYM(FUNC_TYPE, @MEMCPY, @MEMCPYSTR) + ADDSYM(FUNC_TYPE, @ROMCALL, @ROMCALLSTR) + ADDSYM(FUNC_TYPE, @SYSCALL, @SYSCALLSTR) + ADDSYM(FUNC_TYPE, @COUT, @COUTSTR) + ADDSYM(FUNC_TYPE, @CIN, @CINSTR) + ADDSYM(FUNC_TYPE, @PRSTR, @PRSTRSTR) + ADDSYM(FUNC_TYPE, @RDSTR, @RDSTRSTR) + ADDSYM(0, 0, @NULLSTR) ; THIS MARKS END OF MODULE DICTIONARY +END +DEF ALLOC(SIZE) + WORD ADDR + + ADDR = LOMEM + LOMEM = LOMEM + SIZE + RETURN ADDR +END +DEF RELEASE(ADDR) + LOMEM = ADDR +END +; +; BASIC FILE I/O +; +DEF GETFILEINFO(PATH, INFOPTR) + BYTE PARAMS[18] + + PARAMS.0 = 10 + PARAMS:1 = PATH + PERR = SYSCALL($C4, @PARAMS) + IF NOT PERR + MEMCPY(@PARAMS.3, INFOPTR, 15) + FIN + RETURN PERR +END +DEF OPEN(PATH, BUFF) + BYTE PARAMS[6] + + PARAMS.0 = 3 + PARAMS:1 = PATH + PARAMS:3 = BUFF + PARAMS.5 = 0 + PERR = SYSCALL($C8, @PARAMS) + RETURN PARAMS.5 +END +DEF CLOSE(REFNUM) + BYTE PARAMS[2] + + PARAMS.0 = 1 + PARAMS.1 = REFNUM + PERR = SYSCALL($CC, @PARAMS) + RETURN PERR +END +DEF READ(REFNUM, BUFF, LEN) + BYTE PARAMS[8] + + PARAMS.0 = 4 + PARAMS.1 = REFNUM + PARAMS:2 = BUFF + PARAMS:4 = LEN + PARAMS:6 = 0 + PERR = SYSCALL($CA, @PARAMS) + RETURN PARAMS:6 +END +; +; CODE GENERATION +; +; ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR : 00 02 04 06 08 0A 0C 0E +DEF GEN_ZERO + ^LOMEM = $00 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_ADD + ^LOMEM = $02 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_SUB + ^LOMEM = $04 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_MUL + ^LOMEM = $06 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_DIV + ^LOMEM = $08 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_MOD + ^LOMEM = $0A + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_INCR + ^LOMEM = $0C + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_DECR + ^LOMEM = $0E + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +; NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW : 10 12 14 16 18 1A 1C 1E +DEF GEN_NEG + ^LOMEM = $10 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_COMP + ^LOMEM = $12 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_BAND + ^LOMEM = $14 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_IOR + ^LOMEM = $16 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_XOR + ^LOMEM = $18 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_SHL + ^LOMEM = $1A + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_SHR + ^LOMEM = $1C + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_IDXW + ^LOMEM = $1E + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +; NOT,LOR,LAND,LA,LLA,CB,CW,SWAP : 20 22 24 26 28 2A 2C 2E +DEF GEN_NOT + ^LOMEM = $20 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_LOR + ^LOMEM = $22 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_LAND + ^LOMEM = $24 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_LA + ^LOMEM = $26 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_LLA + ^LOMEM = $28 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_CB + (LOMEM).0 = $2A + (LOMEM).1 = (PCPTR).1 + LOMEM = LOMEM + 2 + PCPTR = PCPTR + 2 +END +DEF GEN_CW + (LOMEM).0 = $2C + (LOMEM):1 = (PCPTR):1 + LOMEM = LOMEM + 3 + PCPTR = PCPTR + 3 +END +DEF GEN_SWAP + ^LOMEM = $2E + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +; DROP,DUP,PUSH,PULL,BRLT,BRGT,BREQ,BRNE : 30 32 34 36 38 3A 3C 3E +DEF GEN_DROP + ^LOMEM = $30 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_DUP + ^LOMEM = $32 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_PUSH + ^LOMEM = $34 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_PULL + ^LOMEM = $36 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_BRLT + ^LOMEM = $38 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_BRGT + ^LOMEM = $3A + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_BREQ + ^LOMEM = $3C + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_BRNE + ^LOMEM = $3E + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +; ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU : 40 42 44 46 48 4A 4C 4E +DEF GEN_ISEQ + ^LOMEM = $40 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_ISNE + ^LOMEM = $42 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_ISGT + ^LOMEM = $44 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_ISLT + ^LOMEM = $46 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_ISGE + ^LOMEM = $48 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_ISLE + ^LOMEM = $4A + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF BRFLS + ^LOMEM = $4C + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF BRTRU + ^LOMEM = $4E + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +; JUMP,IJMP,CALL,ICAL,ENTER,LEAVE,RET,XCALL : 50 52 54 56 58 5A 5C 5E +DEF GEN_JUMP + ^LOMEM = $50 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_IJMP + ^LOMEM = $52 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_CALL + ^LOMEM = $54 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_ICAL + ^LOMEM = $56 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_ENTER + ^LOMEM = $58 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_LEAVE + ^LOMEM = $5A + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_RET + ^LOMEM = $5C + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_XCALL + ^LOMEM = $5E + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +; LB,LW,LLB,LLW,LAB,LAW,DLB,DLW : 60 62 64 66 68 6A 6C 6E +DEF GEN_LB + ^LOMEM = $60 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_LW + ^LOMEM = $62 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_LLB + (LOMEM).0 = $64 + (LOMEM).1 = (PCPTR).1 + LOMEM = LOMEM + 2 + PCPTR = PCPTR + 2 +END +DEF GEN_LLW + (LOMEM).0 = $66 + (LOMEM).1 = (PCPTR).1 + LOMEM = LOMEM + 2 + PCPTR = PCPTR + 2 +END +DEF GEN_LAB + ^LOMEM = $68 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_LAW + ^LOMEM = $6A + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_DLB + (LOMEM).0 = $6C + (LOMEM).1 = (PCPTR).1 + LOMEM = LOMEM + 2 + PCPTR = PCPTR + 2 +END +DEF GEN_DLW + (LOMEM).0 = $6E + (LOMEM).1 = (PCPTR).1 + LOMEM = LOMEM + 2 + PCPTR = PCPTR + 2 +END +; SB,SW,SLB,SLW,SAB,SAW,DAB,DAW : 70 72 74 76 78 7A 7C 7E +DEF GEN_SB + ^LOMEM = $70 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_SW + ^LOMEM = $72 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_SLB + (LOMEM).0 = $74 + (LOMEM).1 = (PCPTR).1 + LOMEM = LOMEM + 2 + PCPTR = PCPTR + 2 +END +DEF GEN_SLW + (LOMEM).0 = $76 + (LOMEM).1 = (PCPTR).1 + LOMEM = LOMEM + 2 + PCPTR = PCPTR + 2 +END +DEF GEN_SAB + ^LOMEM = $78 + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_SAW + ^LOMEM = $7A + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_DAB + ^LOMEM = $7C + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_DAW + ^LOMEM = $7E + LOMEM = LOMEM + 1 + PCPTR = PCPTR + 1 +END +DEF GEN_OP + *(GEN_OPTBL + ^PCPTR)() +END +DEF GEN_DEF(NPARAM, FRAMESZ) +END +DEF GEN_END(NPARAM, FRAMESZ) +END +DEF GENCODE(PCODEPTR, PCODELEN, RLD, ES) +END +; +; REL MODULE FIXUPS +; +DEF DUMPRLD(RLD) + COUT('$') + PRBYTE(^RLD) + COUT(':') + COUT(' ') + COUT('$') + PRWORD(*(RLD + 1)) + COUT(' ') + COUT('$') + PRBYTE(^(RLD + 3)) + CROUT + RETURN RLD + 4 +END +DEF DUMPESD(ESD) + WHILE ^ESD & $80 + COUT(^ESD) + ESD = ESD + 1 + LOOP + COUT(^ESD) + COUT(':') + COUT(' ') + COUT('$') + PRBYTE(^(ESD + 1)) + COUT(' ') + COUT('$') + PRWORD(^(ESD + 2)) + CROUT + RETURN ESD + 4 +END +DEF MATCHSTR(STR1, STR2) + BYTE I + IF ^STR1 == ^STR2 + FOR I = ^STR1 DOWNTO 1 + IF (STR1).[I] <> (STR2).[I] + RETURN FALSE + FIN + NEXT + RETURN TRUE + FIN + RETURN FALSE +END +DEF SEARCHDICT(SYMSTR) + WORD DICTPTR + + DICTPTR = MODICT + ; + ; SEARCH MODULE DICTIONARY LOOKING FOR MATCH + ; + WHILE DICTPTR + IF ^DICTPTR +; CROUT +; PRSTR(DICTPTR + 3) + IF MATCHSTR(DICTPTR + 3, SYMSTR) +; COUT('$') +; PRWORD(*(DICTPTR + 1)) + RETURN *(DICTPTR + 1) + FIN + DICTPTR = DICTPTR + 4 + ^(DICTPTR + 3) ; NEXT ENTRY + ELSE + DICTPTR = *(DICTPTR + 1) ; NEXT MODULE SYM TABLE + FIN + LOOP +END +DEF DUMPDICT + WORD DICTPTR + + DICTPTR = MODICT + ; + ; SEARCH MODULE DICTIONARY LOOKING FOR MATCH + ; + WHILE DICTPTR + IF ^DICTPTR + CROUT + PRSTR(DICTPTR + 3) + COUT('$') + PRWORD(*(DICTPTR + 1)) + CROUT + DICTPTR = DICTPTR + 4 + ^(DICTPTR + 3) ; NEXT ENTRY + ELSE + DICTPTR = *(DICTPTR + 1) ; NEXT MODULE SYM TABLE + FIN + LOOP +END +DEF TOUPPER(C) + IF C >= 'a' + IF C <= 'z' + RETURN C - $20 + FIN + FIN + RETURN C +END +DEF MATCHEXTRN(INDEX, ESD) + BYTE SYMSTR[$81], I + WORD SYMPTR + + ; + ; FIND MATCHING ESD INDEX + ; + WHILE ^ESD +; DUMPESD(ESD) + SYMPTR = ESD + I = 1 + WHILE ^ESD & $80 + SYMSTR[I] = TOUPPER(^ESD & $7F) + I = I + 1 + ESD = ESD + 1 + LOOP + SYMSTR[I] = TOUPPER(^ESD & $7F) + SYMSTR = I +; CROUT + IF ^(ESD + 1) & $10 +; PRSTR(@MATCHEXTRNSTR) +; PRSTR(@SYMSTR) + IF ^(ESD + 2) == INDEX + RETURN SEARCHDICT(@SYMSTR) + FIN + FIN + ESD = ESD + 4 + LOOP + RETURN 0 +END +DEF FIXUP(SEGPTR, RLD, OFST, ESD) + WORD FIXVAL, FIXADDR, EXTRNVAL + + WHILE ^RLD +; DUMPRLD(RLD) + FIXADDR = SEGPTR + *(RLD + 1) + IF ^RLD & $80 + ; + ; 16 BIT FIXUP + ; +; PRSTR(@FIX16STR) +; PRWORD(FIXADDR) +; CROUT + FIXVAL = *FIXADDR + IF ^RLD & $10 + ; + ; EXTERNAL SYMBOL + ; + EXTRNVAL = MATCHEXTRN(^(RLD + 3), ESD) + IF EXTRNVAL + FIXVAL = FIXVAL + EXTRNVAL + ELSE + RETURN -1 + FIN + ELSE + FIXVAL = FIXVAL + OFST + FIN + IF ^RLD & $20 ; REVERSE HI AND LO BYTES + FIXVAL = ((FIXVAL >> 8) & $FF) ? (FIXVAL << 8) + FIN + *FIXADDR = FIXVAL + ELSE + ; + ; 8 BIT FIXUP + ; +; PRSTR(@FIX8STR) +; PRWORD(FIXADDR) +; CROUT + IF ^RLD & $10 + ; + ; EXTERNAL SYMBOL + ; + FIXVAL = MATCHEXTRN(^(RLD + 3), ESD) + IF NOT EXTRNVAL + RETURN -1 + FIN + ELSE + IF ^RLD & $40 + FIXVAL = ^FIXADDR << 8 ? ^(RLD + 3) + FIXVAL = FIXVAL + OFST + ELSE + FIXVAL = ^(RLD + 3) << 8 ? ^FIXADDR + FIXVAL = FIXVAL + OFST + FIN + FIN + IF ^RLD & $40 + ^FIXADDR = FIXVAL >> 8 + ELSE + ^FIXADDR = FIXVAL + FIN + FIN + RLD = RLD + 4 + LOOP +END +DEF LOADMOD(MODSTR) + BYTE REFNUM, I, INFO[15], SYMSTR[81] + WORD RELOFST, MODPTR, MODSYMTBL, MODSYMSZ, LEN, DATALEN, RLD, ESD + WORD PCODESEG, PCODEPTR, PCODELEN, CODEPTR, CODELEN + + GETFILEINFO(MODSTR, @INFO) + IF INFO.1 <> $FE ; REL FILE TYPE + RETURN @BADMOD + FIN + RELOFST = INFO:2 +; PRSTR(@ASMADR) +; PRWORD(RELOFST) +; CROUT + ; + ; READ REL FILE + ; + REFNUM = OPEN(MODSTR, IOBUFFER) + LEN = READ(REFNUM, LOMEM, 32768) + CLOSE(REFNUM) +; PRSTR(@LOADADR) +; PRWORD(LOMEM) +; CROUT + ; + ; GET POINTERS TO IMPORTANT SECTIONS + ; + IF (LOMEM):4 <> $BEE2 + RETURN BADMOD + FIN + DATALEN = *LOMEM + MODPTR = LOMEM + 2 + LOMEM = LOMEM + LEN + ENTRY = MODPTR + 6 + PCODEPTR = MODPTR + (MODPTR):0 + RELOFST = MODPTR - (MODPTR):4 + RLD = MODPTR + DATALEN + ESD = RLD + WHILE ^ESD ; SKIP OVER RLD + ESD = ESD + 4 + LOOP + ESD = ESD + 1 +; PRSTR(@RELOFSTSTR) +; PRWORD(RELOFST) +; CROUT + ; + ; EXPAND BYTECODE + ; + PCODELEN = RLD - PCODEPTR + IF CODELEN + CODEPTR = LOMEM + GENCODE(PCODEPTR, PCODELEN, RLD, ESD) + CODELEN = LOMEM - CODEPTR + FIN + ; + ; RUN THROUGH DATA FIXUP TABLE + ; + IF FIXUP(MODPTR, RLD, RELOFST, ESD) < 0 + RETURN @BADMOD + FIN + ; + ; CREATE SYMBOL TABLE FOR EXPORTS + ; + WHILE ^ESD +; DUMPESD(ESD) + I = 1 + WHILE ^ESD & $80 + SYMSTR[I] = TOUPPER(^ESD & $7F) + I = I + 1 + ESD = ESD + 1 + LOOP + SYMSTR[I] = TOUPPER(^ESD & $7F) + SYMSTR = I + IF ^(ESD + 1) & $08 ; ENTRY SYMBOL + ADDSYM(FUNC_TYPE, *(ESD + 2), @SYMSTR) + FIN + ESD = ESD + 4 + LOOP + ADDSYM(0, MODICT, @NULLSTR) ; LINK TO PREVIOUS MODULE DICTIONARY + MODSYMTBL = ESD + ; + ; MOVE SYM TABLE TO END OF DATA SEGMENT + ; + MODSYMSZ = LOMEM - MODSYMTBL + MEMCPY(MODSYMTBL, RLD, MODSYMSZ) + ; + ; UPDATE POINTERS + ; + MODICT = RLD + LOMEM = RLD + MODSYMSZ +; DUMPDICT + RETURN ENTRY +END + +INITPLASMA +(LOADMOD(RDSTR($BA)))() +PRSTR(@PRESSANYKEY) +WHILE ^$C000 < 128 +LOOP +^$C010 +DONE diff --git a/plasma2/loadvm.s b/plasma2/loadvm.s new file mode 100755 index 0000000..776de98 --- /dev/null +++ b/plasma2/loadvm.s @@ -0,0 +1,117 @@ +.PC02 +.DEFINE EQU = +.DEFINE DB .BYTE +.DEFINE DW .WORD +.DEFINE DS .RES +;* +;* LANGUAGE CARD CONTROL +;* +LCBNK2 EQU $C080 +ROMIN EQU $C081 +;* +;* PRODOS +;* +PRODOS EQU $BF00 +;* +;* LOAD VMCORE FILE +;* +;LOADVM: + LDA #$00 + INC ; ONLY WORKS ON 65C02 + CMP #$01 + BEQ LDVMC02 +LDVM02: LDA #VMCORE + STA $07 + BNE :+ +LDVMC02: LDA #VMCOREC + STA $07 +;* +;* MOVE VM INTO LANGUAGE CARD +;* +: LDA #$00 + STA $08 + LDA #$D0 + STA $09 + LDY #$00 + BIT $C083 ; SELECT AND WE LC BANK 2 + BIT $C083 +MVVM: LDA ($06),Y ; COPY VM+CMD INTO LANGUAGE CARD + STA ($08),Y + INY + BNE MVVM + INC $07 + INC $09 + LDA $09 + CMP #$E0 + BNE MVVM + LDX #$FE + TXS + LDX #$00 + STX $01FF +;* +;* LOOK FOR STARTUP FILE +;* + JSR PRODOS ; OPEN AUTORUN + DB $C8 + DW OPENPARMS + BCC :+ + JMP EXIT +: LDA REFNUM + STA NLPARMS+1 + JSR PRODOS + DB $C9 + DW NLPARMS + BCC :+ + JMP EXIT +: LDA REFNUM + STA READPARMS+1 + JSR PRODOS + DB $CA + DW READPARMS + BCC :+ + JMP EXIT +: LDX READPARMS+6 + STX $01FF +EXIT: JSR PRODOS + DB $CC + DW CLOSEPARMS + LDY #$00 + STY $06 + LDA #$D1 + STA $07 +LDVM: LDA ($06),Y ; LOAD FIRST PAGE OF CMD INTO PLACE + STA $1000,Y + INY + BNE LDVM + LDA #$7F + ADC #$01 ; SET V FLAG + JMP $1007 ; CALL CMD +;EXIT: JSR PRODOS +; DB $65 +; DW EXITPARMS +;EXITPARMS: DB 4 +; DB 0 +AUTORUN: DB 7,"AUTORUN" +OPENPARMS: DB 3 + DW AUTORUN + DW $0800 +REFNUM: DB 0 +NLPARMS: DB 3 + DB 0 + DB $7F + DB $0D +READPARMS: DB 4 + DB 0 + DW $0200 + DW $0080 + DW 0 +CLOSEPARMS: DB 1 + DB 0 +VMCORE: + .INCLUDE "vmcore.byte" +VMCOREC: + .INCLUDE "vmcorec.byte" diff --git a/plasma2/makefile b/plasma2/makefile new file mode 100755 index 0000000..ff9295a --- /dev/null +++ b/plasma2/makefile @@ -0,0 +1,127 @@ +.SUFFIXES = +AFLAGS = -o $@ +LFLAGS = -C default.cfg +PLCOMP = plc +BYTEDUMP = bytedump +OBJS = parse.o lex.o codegen.o +PLASMASYS = plasma.sys +PLEDPLA = pled.pla +PLEDSYS = pled.sys +PLEXPLA = plex.pla +PLEXSYS = plex.sys +PLASMPLA = plas.pla +PLASMSYS = plas.sys +RODPLA = rod.pla +RODSYS = rod.sys +FIREPLA = fire.pla +FIRESYS = fire.sys +VMLDR = loadvm.s +CMDPLA = cmd.pla +CMDLDR = loadcmd.s +CMDBYT = cmd.byte +PLIDEPLA = plide.pla +PLIDESYS = plide.sys +PLINKPLA = plink.pla +PLINKSYS = plink.sys +VMCORE = vmcore.s +VMCOREBIN = vmcore.bin +VMCORECBIN = vmcorec.bin +LOADER = loader.pla +# +# Image filetypes for Virtual ][ +# +PLATYPE = .\$$ED +BINTYPE = .BIN +SYSTYPE = .SYS +TXTTYPE = .TXT +# +# Image filetypes for CiderPress +# +#PLATYPE = \#ed0000 +#BINTYPE = \#060000 +#SYSTYPE = \#ff0000 +#TXTTYPE = \#040000 + +all: $(RODSYS) $(FIRESYS) $(PLEDSYS) $(PLASMSYS) $(PLEXSYS) $(PLIDESYS) $(PLINKSYS) $(PLCOMP) $(BYTEDUMP) $(VMCOREBIN) $(VMCORECBIN) $(PLASMASYS) + +$(PLCOMP): $(OBJS) + cc $(OBJS) -o $(PLCOMP) + +$(BYTEDUMP): bytedump.c + cc bytedump.c -o $(BYTEDUMP) + +$(RODSYS): $(PLCOMP) $(RODPLA) + ./$(PLCOMP) < $(RODPLA) > rod.s + ca65 rod.s -o tmp.o + ld65 $(LFLAGS) tmp.o -o $(RODSYS) + rm tmp.o + cp $(RODSYS) rod\#ff0000 + +$(FIRESYS): $(PLCOMP) $(FIREPLA) + ./$(PLCOMP) < $(FIREPLA) > fire.s + ca65 fire.s -o tmp.o + ld65 $(LFLAGS) tmp.o -o $(FIRESYS) + rm tmp.o + cp $(FIRESYS) fire\#ff0000 + +$(PLEDSYS): $(PLCOMP) $(PLEDPLA) + ./$(PLCOMP) < $(PLEDPLA) > pled.s + ca65 pled.s -o tmp.o + ld65 $(LFLAGS) tmp.o -o $(PLEDSYS) + rm tmp.o + cp $(PLEDSYS) pled\#ff0000 + +$(PLASMSYS): $(PLCOMP) $(PLASMPLA) + ./$(PLCOMP) < $(PLASMPLA) > plas.s + ca65 plas.s -o tmp.o + ld65 -C plide.cfg tmp.o -o $(PLASMSYS) + rm tmp.o + cp $(PLASMSYS) plas\#ff0000 + +$(PLEXSYS): $(PLCOMP) $(PLEXPLA) + ./$(PLCOMP) < $(PLEXPLA) > plex.s + ca65 plex.s -o tmp.o + ld65 -C plide.cfg tmp.o -o $(PLEXSYS) + rm tmp.o + cp $(PLEXSYS) plex\#ff0000 + +$(CMDBYT): $(PLCOMP) $(CMDLDR) $(CMDPLA) $(BYTEDUMP) + ./$(PLCOMP) $$ < $(CMDPLA) > cmd.s + ca65 $(CMDLDR) -o tmp.o + ld65 -C cmdloader.cfg tmp.o -o cmd.bin + ./$(BYTEDUMP) cmd.bin > $(CMDBYT) + rm tmp.o + +$(PLIDESYS): $(PLIDEPLA) $(PLCOMP) + ./$(PLCOMP) < $(PLIDEPLA) > plide.s + ca65 plide.s -o tmp.o + ld65 -C plide.cfg tmp.o -o $(PLIDESYS) + rm tmp.o + cp $(PLIDESYS) plide\#ff0000 + +$(PLINKSYS): $(PLINKPLA) $(PLCOMP) + ./$(PLCOMP) < $(PLINKPLA) > plink.s + ca65 plink.s -o tmp.o + ld65 $(LFLAGS) tmp.o -o $(PLINKSYS) + rm tmp.o + cp $(PLINKSYS) plink\#ff0000 + +$(VMCOREBIN): $(PLCOMP) $(VMCORE) $(CMDBYT) $(BYTEDUMP) + ca65 $(VMCORE) -D IS65C02=0 -o tmp.o + ld65 $(LFLAGS) tmp.o -o $(VMCOREBIN) + rm tmp.o + +$(VMCORECBIN): $(PLCOMP) $(VMCORE) $(CMDBYTE) $(BYTEDUMP) + ca65 $(VMCORE) -D IS65C02=1 -o tmp.o + ld65 $(LFLAGS) tmp.o -o $(VMCORECBIN) + rm tmp.o + +$(PLASMASYS): $(PLCOMP) $(VMLDR) $(VMCOREBIN) $(VMCORECBIN) + ./$(BYTEDUMP) $(VMCOREBIN) > vmcore.byte + ./$(BYTEDUMP) $(VMCORECBIN) > vmcorec.byte + ca65 $(VMLDR) -o tmp.o + ld65 $(LFLAGS) tmp.o -o $(PLASMASYS) + rm tmp.o + cp $(PLASMASYS) plasma.system#ff0000 + + diff --git a/plasma2/makesys.pla b/plasma2/makesys.pla new file mode 100755 index 0000000..1f11592 --- /dev/null +++ b/plasma2/makesys.pla @@ -0,0 +1,213 @@ +BYTE INFOBUFF[20] +BYTE PERR +WORD FILESTR = $2006 +; +; Defines for ASM routines +; +ASM EQUATES + TMP EQU $F0 + TMPL EQU TMP + TMPH EQU TMP+1 + SRC EQU TMP + SRCL EQU SRC + SRCH EQU SRC+1 + DST EQU SRC+2 + DSTL EQU DST + DSTH EQU DST+1 + ESP EQU DST+2 +JMPTMP: JMP (TMP) +END +; +; CALL 6502 ROUTINE +; ROMCALL(AREG, XREG, YREG, STATUS, ADDR) +; +ASM ROMCALL + PHP + LDA ESTKL,X + STA TMPL + LDA ESTKH,X + STA TMPH + INX + LDA ESTKL,X + PHA + INX + LDA ESTKL,X + TAY + INX + LDA ESTKL+1,X + PHA + LDA ESTKL,X + INX + STX ESP + TAX + PLA + BIT ROMIN + PLP + JSR JMPTMP + PHP + BIT LCBNK2 + STA REGVALS+0 + STX REGVALS+1 + STY REGVALS+2 + PLA + STA REGVALS+3 + LDX ESP + LDA #REGVALS + STA ESTKL,X + STY ESTKH,X + PLP + RTS +REGVALS: DS 4 +END +; +; +; CALL PRODOS +; SYSCALL(CMD, PARAMS) +; +ASM SYSCALL + LDA ESTKL,X + LDY ESTKH,X + STA PARAMS + STY PARAMS+1 + INX + LDA ESTKL,X + STA CMD + STX ESP + BIT ROMIN + JSR $BF00 +CMD: DB 00 +PARAMS: DW 0000 + BIT LCBNK2 + LDX ESP + STA ESTKL,X + LDY #$00 + STY ESTKH,X +END +; +; COPY MEMORY +; MEMCPY(SRCADDR, DSTADDR, SIZE) +; +ASM MEMCPY + LDY #$00 + LDA ESTKL,X + BNE :+ + LDA ESTKH,X + BEQ MEMEXIT +: LDA ESTKL+1,X + STA DSTL + LDA ESTKH+1,X + STA DSTH + LDA ESTKL+2,X + STA SRCL + LDA ESTKH+2,X + STA SRCH + CMP DSTH + BCC REVCPY + BNE FORCPY + LDA SRCL + CMP DSTL + BCS FORCPY +REVCPY: ; REVERSE DIRECTION COPY +; CLC + LDA ESTKL,X + ADC DSTL + STA DSTL + LDA ESTKH,X + ADC DSTH + STA DSTH + CLC + LDA ESTKL,X + ADC SRCL + STA SRCL + LDA ESTKH,X + ADC SRCH + STA SRCH + INC ESTKH,X +REVCPYLP: + LDA DSTL + BNE :+ + DEC DSTH +: DEC DSTL + LDA SRCL + BNE :+ + DEC SRCH +: DEC SRCL + LDA (SRC),Y + STA (DST),Y + DEC ESTKL,X + BNE REVCPYLP + DEC ESTKH,X + BNE REVCPYLP + BEQ MEMEXIT +FORCPY: INC ESTKH,X +FORCPYLP: + LDA (SRC),Y + STA (DST),Y + INC DSTL + BNE :+ + INC DSTH +: INC SRCL + BNE :+ + INC SRCH +: DEC ESTKL,X + BNE FORCPYLP + DEC ESTKH,X + BNE FORCPYLP + BEQ MEMEXIT +END +; +; READ STRING +; STR = RDSTR(PROMPTCHAR) +; +ASM RDSTR + LDA ESTKL,X + STA $33 + STX ESP + BIT ROMIN + JSR $FD6A + BIT LCBNK2 + STX $01FF +: LDA $01FF,X + AND #$7F + STA $01FF,X + DEX + BPL :- + LDX ESP + LDA #$FF + STA ESTKL,X + LDA #$01 + STA ESTKH,X +END + +DEF GETFILEINFO(PATH, INFOPTR) + BYTE PARAMS[18] + + PARAMS.0 = 10 + PARAMS:1 = PATH + PERR = SYSCALL($C4, @PARAMS) + IF NOT PERR + MEMCPY(@PARAMS.3, INFOPTR, 15) + FIN + RETURN PERR +END + +DEF SETFILEINFO(PATH, INFOPTR) + BYTE PARAMS[14] + + PARAMS.0 = 7 + PARAMS:1 = PATH + MEMCPY(INFOPTR, @PARAMS.3, 11) + PERR = SYSCALL($C3, @PARAMS) + RETURN PERR +END + +IF ^FILESTR == 0 + FILESTR = RDSTR($BA) +FIN +IF GETFILEINFO(FILESTR, @INFOBUFF) == 0 + INFOBUFF.1 = $FF + SETFILEINFO(FILESTR, @INFOBUFF) +FIN +DONE + diff --git a/plasma2/parse.c b/plasma2/parse.c new file mode 100755 index 0000000..5042d2a --- /dev/null +++ b/plasma2/parse.c @@ -0,0 +1,1465 @@ +#include +#include "tokens.h" +#include "lex.h" +#include "codegen.h" + +int infunc = 0, retfunc_tag = 0, break_tag = 0, stack_loop = 0; +t_token prevstmnt; + +t_token binary_ops_table[] = { + /* Highest precedence */ + MUL_TOKEN, DIV_TOKEN, DIVMOD_TOKEN, + ADD_TOKEN, SUB_TOKEN, + SHR_TOKEN, SHL_TOKEN, + AND_TOKEN, + EOR_TOKEN, + OR_TOKEN, + GT_TOKEN, GE_TOKEN, LT_TOKEN, LE_TOKEN, + EQ_TOKEN, NE_TOKEN, + LOGIC_AND_TOKEN, + LOGIC_OR_TOKEN, + COMMA_TOKEN + /* Lowest precedence */ + }; +t_token binary_ops_precedence[] = { + /* Highest precedence */ + 1, 1, 1, + 2, 2, + 3, 3, + 4, + 5, + 6, + 7, 7, 7, 7, + 8, 8, + 9, + 10, + 11 + /* Lowest precedence */ + }; + +t_token opstack[16]; +int precstack[16]; +int opsptr = -1; +void push_op(t_token op, int prec) +{ + if (++opsptr == 16) + { + parse_error("Stack overflow\n"); + return; + } + opstack[opsptr] = op; + precstack[opsptr] = prec; +} +t_token pop_op(void) +{ + if (opsptr < 0) + { + parse_error("Stack underflow\n"); + return (0); + } + return opstack[opsptr--]; +} +t_token tos_op(void) +{ + return opsptr < 0 ? 0 : opstack[opsptr]; +} +int tos_op_prec(int tos) +{ + return opsptr <= tos ? 100 : precstack[opsptr]; +} +int consts = 0; +char idconst_name[1024][17]; +int idconst_value[1024]; +int globals = 0; +int globalsize = 0; +char idglobal_name[1024][17]; +int idglobal_type[1024]; +int idglobal_tag[1024]; +int locals = 0; +int localsize = 0; +char idlocal_name[128][17]; +int idlocal_type[128]; +int idlocal_offset[128]; +int id_match(char *name, int len, char *id) +{ + if (len == id[0]) + { + if (len > 16) len = 16; + while (len--) + { + if (name[len] != id[1 + len]) + return (0); + } + return (1); + } + return (0); +} +int idlocal_lookup(char *name, int len) +{ + int i; + for (i = 0; i < locals; i++) + if (id_match(name, len, &(idlocal_name[i][0]))) + return (i); + return (-1); +} +int idglobal_lookup(char *name, int len) +{ + int i; + for (i = 0; i < globals; i++) + if (id_match(name, len, &(idglobal_name[i][0]))) + return (i); + return (-1); +} +int idconst_lookup(char *name, int len) +{ + int i; + for (i = 0; i < consts; i++) + if (id_match(name, len, &(idconst_name[i][0]))) + return (i); + return (-1); +} +int idlocal_add(char *name, int len, int type, int size) +{ + if (localsize > 255) + { + printf("Local variable size overflow\n"); + return (0); + } + char c = name[len]; + name[len] = '\0'; + emit_idlocal(name, localsize); + name[len] = c; + idlocal_name[locals][0] = len; + if (len > 16) len = 16; + while (len--) + idlocal_name[locals][1 + len] = name[len]; + idlocal_type[locals] = type; + idlocal_offset[locals] = localsize; + localsize += size; + locals++; + return (1); +} +int idglobal_add(char *name, int len, int type, int size) +{ + if (globals > 1024) + { + printf("Global variable count overflow\n"); + return (0); + } + char c = name[len]; + name[len] = '\0'; + emit_idglobal(globalsize, size, name); + name[len] = c; + idglobal_name[globals][0] = len; + if (len > 16) len = 16; + while (len--) + idglobal_name[globals][1 + len] = name[len]; + idglobal_type[globals] = type; + idglobal_tag[globals] = globalsize; + globalsize += size; + globals++; + return (1); +} +void idglobal_size(int type, int size, int constsize) +{ + if (size > constsize) + globalsize += emit_data(0, 0, 0, size - constsize); + else + globalsize += constsize; +} +int idfunc_add(char *name, int len, int tag) +{ + if (globals > 1024) + { + printf("Global variable count overflow\n"); + return (0); + } + idglobal_name[globals][0] = len; + if (len > 16) len = 16; + while (len--) + idglobal_name[globals][1 + len] = name[len]; + idglobal_type[globals] = FUNC_TYPE; + idglobal_tag[globals] = tag; + globals++; + return (1); +} +int idconst_add(char *name, int len, int value) +{ + if (consts > 1024) + { + printf("Constant count overflow\n"); + return (0); + } + char c = name[len]; + name[len] = '\0'; + emit_idconst(name, value); + name[len] = c; + idconst_name[consts][0] = len; + if (len > 16) len = 16; + while (len--) + idconst_name[consts][1 + len] = name[len]; + idconst_value[consts] = value; + consts++; + return (1); +} +int id_addr(char *name, int len) +{ + int i; + if ((i = idlocal_lookup(name, len)) >= 0) + return (idlocal_offset[i]); + if ((i = idglobal_lookup(name, len)) >= 0) + return (idglobal_tag[i]); + parse_error("Undeclared identifier"); + return (-1); +} +int id_const(char *name, int len) +{ + int i; + if ((i = idconst_lookup(name, len)) >= 0) + return (idconst_value[i]); + parse_error("Undeclared constant"); + return (0); +} +int id_type(char *name, int len) +{ + int i; + if ((i = idconst_lookup(name, len)) >= 0) + return (CONST_TYPE); + if ((i = idlocal_lookup(name, len)) >= 0) + return (idlocal_type[i] | LOCAL_TYPE); + if ((i = idglobal_lookup(name, len)) >= 0) + return (idglobal_type[i]); + parse_error("Undeclared identifier"); + return (0); +} +void idlocal_reset(void) +{ + locals = localsize = 0; +} +int tag_new(void) +{ + static int codetag = 0; + return (codetag++); +} +int parse_expr(void); +int parse_term(void) +{ + /* + * Parse terminal tokens. + */ + switch (scan()) + { + case CHAR_TOKEN: + case INT_TOKEN: + case FLOAT_TOKEN: + case ID_TOKEN: + case STRING_TOKEN: + break; + case OPEN_PAREN_TOKEN: + if (!parse_expr()) + { + parse_error("Bad expression in parenthesis"); + return (0); + } + if (scantoken != CLOSE_PAREN_TOKEN) + { + parse_error("Missing closing parenthesis"); + return (0); + } + break; + default: + /* + * Non-terminal token. + */ + return (0); + } + return (1); +} +int parse_constval(long *value, int *size) +{ + int mod = 0, type = 0; + *value = 0; + while (!parse_term()) + { + switch (scantoken) + { + case ADD_TOKEN: + /* + * Just ignore unary plus, it is a no-op. + */ + break; + case SUB_TOKEN: // Really NEG_TOKEN + mod |= 1; + break; + case COMP_TOKEN: + mod |= 2; + break; + case LOGIC_NOT_TOKEN: + mod |= 4; + break; + case AT_TOKEN: + mod |= 8; + break; + default: + return (0); + } + } + /* + * Determine which terminal type. + */ + if (scantoken == STRING_TOKEN) + { + *value = constval; + *size = tokenlen - 1; + type = STRING_TYPE; + if (mod) + { + parse_error("Invalid string modifiers"); + return (0); + } + } + else if (scantoken == CHAR_TOKEN) + { + *value = constval; + *size = 1; + type = BYTE_TYPE; + } + else if (scantoken == INT_TOKEN) + { + *value = constval; + *size = 2; + type = WORD_TYPE; + } + else if (scantoken == ID_TOKEN) + { + type = id_type(tokenstr, tokenlen); + if (type & CONST_TYPE) + *value = id_const(tokenstr, tokenlen); + else if ((type & VAR_TYPE) && (mod & 8)) + { + type = TAG_TYPE; + *value = id_addr(tokenstr, tokenlen); + } + else if (type & FUNC_TYPE) + { + type = TAG_TYPE; + *value = id_addr(tokenstr, tokenlen) | 0x8000; + } + else + { + parse_error("Invalid constant"); + return (0); + } + } + else + { + parse_error("Invalid constant"); + return (0); + } + if (mod & 1) + *value = -*value; + if (mod & 2) + *value = ~*value; + if (mod & 4) + *value = *value ? 0 : -1; + return (type); +} +int parse_value(int rvalue) +{ + int cparams; + int deref = rvalue; + int optos = opsptr; + int type = 0, value = 0, emit_value = 0; + /* + * Parse pre operand operators. + */ + while (!parse_term()) + { + switch (scantoken) + { + case ADD_TOKEN: + /* + * Just ignore unary plus, it is a no-op. + */ + break; + case BPTR_TOKEN: + if (deref) + push_op(scantoken, 0); + else + { + type |= BPTR_TYPE; + deref++; + } + break; + case WPTR_TOKEN: + if (deref) + push_op(scantoken, 0); + else + { + type |= WPTR_TYPE; + deref++; + } + break; + case AT_TOKEN: + deref--; + break; + case SUB_TOKEN: // Really NEG_TOKEN + case COMP_TOKEN: + case LOGIC_NOT_TOKEN: + push_op(scantoken, 0); + break; + default: + return (0); + } + } + /* + * Determine which terminal type. + */ + if (scantoken == INT_TOKEN || scantoken == CHAR_TOKEN) + { + value = constval; + type |= CONST_TYPE; + } + else if (scantoken == ID_TOKEN) + { + if ((type |= id_type(tokenstr, tokenlen)) & CONST_TYPE) + value = id_const(tokenstr, tokenlen); + else if (type & VAR_TYPE) + value = id_addr(tokenstr, tokenlen); + else if (type & FUNC_TYPE) + value = id_addr(tokenstr, tokenlen); + else + { + printf("Bad ID type\n"); + return (0); + } + } + else if (scantoken == CLOSE_PAREN_TOKEN) + { +// type |= WORD_TYPE; + emit_value = 1; + } + else + return (0); + if (type & CONST_TYPE) + { + /* + * Quick optimizations + */ + while ((optos < opsptr) + && ((tos_op() == NEG_TOKEN) || (tos_op() == COMP_TOKEN) || (tos_op() == LOGIC_NOT_TOKEN))) + { + switch (pop_op()) + { + case NEG_TOKEN: + value = -value; + break; + case COMP_TOKEN: + value = ~value; + break; + case LOGIC_NOT_TOKEN: + value = value ? 0 : -1; + break; + } + } + } + /* + * Parse post operand operators. + */ + scan(); + while (scantoken == OPEN_PAREN_TOKEN + || scantoken == OPEN_BRACKET_TOKEN + || scantoken == DOT_TOKEN + || scantoken == COLON_TOKEN) + { + /* + * Parse post operand operators. + */ + if (scantoken == OPEN_BRACKET_TOKEN) + { + /* + * Array + */ + if (!emit_value) + { + if (type & ADDR_TYPE) + { + if (type & LOCAL_TYPE) + emit_localaddr(value); + else + emit_globaladdr(value, type); + } + else if (type & CONST_TYPE) + { + emit_const(value); + } + emit_value = 1; + } + if (type & PTR_TYPE) + emit_lw(); + if (!parse_expr()) + { + parse_error("Bad expression"); + return (0); + } + if (scantoken != CLOSE_BRACKET_TOKEN) + { + parse_error("Missing closing bracket"); + return (0); + } + if (type & WORD_TYPE) + { + //type |= WPTR_TYPE; + type = WPTR_TYPE; + emit_indexword(); + } + else + { + //type |= BPTR_TYPE; + type = BPTR_TYPE; + emit_indexbyte(); + } + //type &= ~(ADDR_TYPE | CONST_TYPE); + scan(); + } + else if (scantoken == DOT_TOKEN || scantoken == COLON_TOKEN) + { + /* + * Structure member offset or array of arrays + */ + int elem_size; + int elem_type = (scantoken == DOT_TOKEN) ? BPTR_TYPE : WPTR_TYPE; + long elem_offset = 0; + if (parse_constval(&elem_offset, &elem_size)) + { + /* + * Constant member offset + */ + if (!emit_value) + { + if (type & VAR_TYPE) + { + if (type & LOCAL_TYPE) + emit_localaddr(value + elem_offset); + else + emit_globaladdrofst(value, elem_offset, type); + } + else if (type & CONST_TYPE) + { + value += elem_offset; + emit_const(value); + } + else // FUNC_TYPE + { + emit_globaladdr(value, type); + emit_const(elem_offset); + emit_op(ADD_TOKEN); + } + emit_value = 1; + } + else + { + if (elem_offset != 0) + { + emit_const(elem_offset); + emit_op(ADD_TOKEN); + } + } + scan(); + } + else if (scantoken == OPEN_BRACKET_TOKEN) + { + /* + * Array of arrays + */ + if (!emit_value) + { + if (type & ADDR_TYPE) + { + if (type & LOCAL_TYPE) + emit_localaddr(value); + else + emit_globaladdr(value, type); + } + else if (type & CONST_TYPE) + { + emit_const(value); + } + emit_value = 1; + } + do + { + if (emit_value++ > 1) + { + emit_indexword(); + emit_lw(); + } + if (!parse_expr()) + { + parse_error("Bad expression"); + return (0); + } + if (scantoken != CLOSE_BRACKET_TOKEN) + { + parse_error("Missing closing bracket"); + return (0); + } + } while (scan() == OPEN_BRACKET_TOKEN); + if (elem_type & WPTR_TYPE) + emit_indexword(); + else + emit_indexbyte(); + } + else + { + parse_error("Invalid member offset"); + return (0); + } + type = elem_type; //(type & ~(ADDR_TYPE | CONST_TYPE)) | elem_type; + } + else if (scantoken == OPEN_PAREN_TOKEN) + { + /* + * Function call + */ + if (!emit_value && (type & VAR_TYPE)) + { + if (type & LOCAL_TYPE) + emit_localaddr(value); + else + emit_globaladdr(value, type); + } + if (type & (VAR_TYPE | PTR_TYPE)) + emit_lw(); + if (!(type & (FUNC_TYPE | CONST_TYPE))) + emit_push(); + parse_expr(); + if (scantoken != CLOSE_PAREN_TOKEN) + { + parse_error("Missing closing parenthesis"); + return (0); + } + if (type & (FUNC_TYPE | CONST_TYPE)) + emit_call(value); + else + { + emit_pull(); + emit_ical(); + } + emit_value = 1; + type = WORD_TYPE; //(type & ~(FUNC_TYPE | CONST_TYPE)) | WORD_TYPE; + scan(); + } + } + if (emit_value) + { + if (rvalue && deref && (type & PTR_TYPE)) + (type & BPTR_TYPE) ? emit_lb() : emit_lw(); + } + else + { + if (type & CONST_TYPE) + emit_const(value); + else if (deref) + { + if (type & FUNC_TYPE) + emit_call(value); + else if (type & VAR_TYPE) + { + if (type & LOCAL_TYPE) + (type & BYTE_TYPE) ? emit_llb(value) : emit_llw(value); + else + (type & BYTE_TYPE) ? emit_lab(value) : emit_law(value); + } + else if (type & PTR_TYPE) + (type & BPTR_TYPE) ? emit_lb() : emit_lw(); + } + else + { + if (type & LOCAL_TYPE) + emit_localaddr(value); + else + emit_globaladdr(value, type); + } + } + while (optos < opsptr) + { + if (!emit_unaryop(pop_op())) + { + parse_error(": Invalid unary operation"); + return (0); + } + } + return (type ? type : WORD_TYPE); +} +int parse_constexpr(long *value, int *size) +{ + long val1, val2; + int type, size1, size2 = 0; + + if (!(type = parse_constval(&val1, &size1))) + return (0); + if (scan() == ADD_TOKEN) + { + if (!parse_constval(&val2, &size2)) + return (0); + *value = val1 + val2; + } + else if (scantoken == SUB_TOKEN) + { + if (!parse_constval(&val2, &size2)) + return (0); + *value = val1 - val2; + } + else if (scantoken == MUL_TOKEN) + { + if (!parse_constval(&val2, &size2)) + return (0); + *value = val1 * val2; + } + else if (scantoken == DIV_TOKEN) + { + if (!parse_constval(&val2, &size2)) + return (0); + *value = val1 / val2; + } + else if (scantoken == AND_TOKEN) + { + if (!parse_constval(&val2, &size2)) + return (0); + *value = val1 & val2; + } + else if (scantoken == OR_TOKEN) + { + if (!parse_constval(&val2, &size2)) + return (0); + *value = val1 | val2; + } + else if (scantoken == EOR_TOKEN) + { + if (!parse_constval(&val2, &size2)) + return (0); + *value = val1 ^ val2; + } + else + *value = val1; + *size = size1 > size2 ? size1 : size2; + return (type); +} +int parse_expr() +{ + int prevmatch; + int matchop = 0; + int optos = opsptr; + int i; + int prevtype, type = 0; + do + { + /* + * Parse sequence of double operand operations. + */ + prevmatch = matchop; + matchop = 0; + if (parse_value(1)) + { + matchop = 1; + for (i = 0; i < sizeof(binary_ops_table); i++) + if (scantoken == binary_ops_table[i]) + { + matchop = 2; + if (binary_ops_precedence[i] >= tos_op_prec(optos)) + if (!emit_op(pop_op())) + { + parse_error(": Invalid binary operation"); + return (0); + } + push_op(scantoken, binary_ops_precedence[i]); + break; + } + } + } while (matchop == 2); + if (matchop == 0 && prevmatch == 2) + { + parse_error("Missing operand"); + return (0); + } + while (optos < opsptr) + if (!emit_op(pop_op())) + { + parse_error(": Invalid binary operation"); + return (0); + } + return (matchop || prevmatch); +} +int parse_setlist(int addr, int type) +{ + int nexttype, nextaddr; + char *idptr; + + if (!(type & VAR_TYPE)) + emit_push(); + if (scan() == ID_TOKEN) + { + nexttype = id_type(tokenstr, tokenlen); + nextaddr = id_addr(tokenstr, tokenlen); + } + else + { + nexttype = 0; + nextaddr = 0; + } + idptr = tokenstr; + scan(); + if (nexttype & VAR_TYPE && scantoken == SET_TOKEN) + { + parse_expr(); + if (type & LOCAL_TYPE) + (type & BYTE_TYPE) ? emit_slb(nextaddr) : emit_slw(nextaddr); + else + (type & BYTE_TYPE) ? emit_sab(nextaddr) : emit_saw(nextaddr); + } + else if (nexttype & VAR_TYPE && scantoken == SETLIST_TOKEN) + { + parse_setlist(nextaddr, nexttype); + } + else + { + tokenstr = idptr; + scan_rewind(tokenstr); + if ((nexttype = parse_value(0)) != 0) + { + if (scantoken == SET_TOKEN) + { + emit_push(); + parse_expr(); + emit_pull(); + emit_swap(); + (nexttype & (BYTE_TYPE | BPTR_TYPE)) ? emit_sb() : emit_sw(); + } + else if (scantoken == SETLIST_TOKEN) + parse_setlist(0, nexttype); + } + else + { + parse_error("Syntax error"); + return (0); + } + } + if (type & VAR_TYPE) + { + if (type & LOCAL_TYPE) + (type & BYTE_TYPE) ? emit_slb(addr) : emit_slw(addr); + else + (type & BYTE_TYPE) ? emit_sab(addr) : emit_saw(addr); + } + else + { + emit_pull(); + emit_swap(); + (type & (BYTE_TYPE | BPTR_TYPE)) ? emit_sb() : emit_sw(); + } + return (1); +} +int parse_stmnt(void) +{ + int tag_prevbrk, tag_else, tag_endif, tag_while, tag_wend, tag_repeat, tag_for, tag_choice, type, addr, step; + char *idptr; + + /* + * Optimizationf for last function LEAVE + */ + if (scantoken != END_TOKEN && scantoken != DONE_TOKEN) + prevstmnt = scantoken; + + switch (scantoken) + { + case IF_TOKEN: + parse_expr(); + tag_else = tag_new(); + tag_endif = tag_new(); + emit_skpfls(tag_else); + scan(); + do { + while (parse_stmnt()) next_line(); + if (scantoken != ELSEIF_TOKEN) + break; + emit_skip(tag_endif); + emit_codetag(tag_else); + if (!parse_expr()) + { + parse_error("Bad expression"); + return (0); + } + tag_else = tag_new(); + emit_skpfls(tag_else); + } while (1); + if (scantoken == ELSE_TOKEN) + { + emit_skip(tag_endif); + emit_codetag(tag_else); + scan(); + while (parse_stmnt()) next_line(); + emit_codetag(tag_endif); + } + else + { + emit_codetag(tag_else); + emit_codetag(tag_endif); + } + if (scantoken != FIN_TOKEN) + { + parse_error("Missing IF/FIN"); + return (0); + } + break; + case WHILE_TOKEN: + tag_while = tag_new(); + tag_wend = tag_new(); + tag_prevbrk = break_tag; + break_tag = tag_wend; + emit_codetag(tag_while); + parse_expr(); + emit_skpfls(tag_wend); + while (parse_stmnt()) next_line(); + if (scantoken != LOOP_TOKEN) + { + parse_error("Missing WHILE/END"); + return (0); + } + emit_skip(tag_while); + emit_codetag(tag_wend); + break_tag = tag_prevbrk; + break; + case REPEAT_TOKEN: + tag_prevbrk = break_tag; + break_tag = tag_new(); + tag_repeat = tag_new(); + emit_codetag(tag_repeat); + scan(); + while (parse_stmnt()) next_line(); + if (scantoken != UNTIL_TOKEN) + { + parse_error("Missing REPEAT/UNTIL"); + return (0); + } + parse_expr(); + emit_skpfls(tag_repeat); + emit_codetag(break_tag); + break_tag = tag_prevbrk; + break; + case FOR_TOKEN: + stack_loop++; + tag_prevbrk = break_tag; + break_tag = tag_new(); + tag_for = tag_new(); + if (scan() != ID_TOKEN) + { + parse_error("Missing FOR variable"); + return (0); + } + type = id_type(tokenstr, tokenlen); + addr = id_addr(tokenstr, tokenlen); + if (scan() != SET_TOKEN) + { + parse_error("Missing FOR ="); + return (0); + } + parse_expr(); + emit_codetag(tag_for); + if (type & LOCAL_TYPE) + type & BYTE_TYPE ? emit_dlb(addr) : emit_dlw(addr); + else + type & BYTE_TYPE ? emit_dab(addr) : emit_daw(addr); + step = 1; + if (scantoken == TO_TOKEN) + { + parse_expr(); + } + else if (scantoken == DOWNTO_TOKEN) + { + step = -1; + parse_expr(); + } + step > 0 ? emit_skpgt(break_tag) : emit_skplt(break_tag); + if (scantoken == STEP_TOKEN) + { + parse_expr(); + emit_op(step > 0 ? ADD_TOKEN : SUB_TOKEN); + } + else + emit_unaryop(step > 0 ? INC_TOKEN : DEC_TOKEN); + while (parse_stmnt()) next_line(); + if (scantoken != NEXT_TOKEN) + { + parse_error("Missing FOR/NEXT "); + return (0); + } + emit_skip(tag_for); + emit_codetag(break_tag); + emit_drop(); + break_tag = tag_prevbrk; + stack_loop--; + break; + case CASE_TOKEN: + stack_loop++; + tag_prevbrk = break_tag; + break_tag = tag_new(); + tag_choice = tag_new(); + parse_expr(); + next_line(); + while (scantoken != ENDCASE_TOKEN) + { + if (scantoken == OF_TOKEN) + { + if (!parse_expr()) + { + parse_error("Bad CASE OF expression"); + return (0); + } + emit_skpne(tag_choice); + while (parse_stmnt()) next_line(); + emit_skip(break_tag); + emit_codetag(tag_choice); + tag_choice = tag_new(); + } + else if (scantoken == DEFAULT_TOKEN) + { + scan(); + while (parse_stmnt()) next_line(); + if (scantoken != ENDCASE_TOKEN) + { + parse_error("Bad CASE DEFAULT clause"); + return (0); + } + } + else + { + parse_error("Bad CASE clause"); + return (0); + } + } + emit_codetag(break_tag); + emit_drop(); + break_tag = tag_prevbrk; + stack_loop--; + break; + case BREAK_TOKEN: + if (break_tag) + emit_skip(break_tag); + else + { + parse_error("BREAK without loop"); + return (0); + } + break; + case RETURN_TOKEN: + if (infunc) + { + int i; + for (i = 0; i < stack_loop; i++) + emit_drop(); + parse_expr(); + emit_leave(localsize); + } + else + { + parse_error("RETURN outside of function"); + return (0); + } + break; + case DROP_TOKEN: + parse_expr(); + emit_drop(); + break; + case EOL_TOKEN: + case COMMENT_TOKEN: + return (1); + case ELSE_TOKEN: + case ELSEIF_TOKEN: + case FIN_TOKEN: + case LOOP_TOKEN: + case UNTIL_TOKEN: + case NEXT_TOKEN: + case OF_TOKEN: + case DEFAULT_TOKEN: + case ENDCASE_TOKEN: + case END_TOKEN: + case DONE_TOKEN: + case IFUNC_TOKEN: + case NFUNC_TOKEN: + return (0); + case ID_TOKEN: + idptr = tokenstr; + type = id_type(tokenstr, tokenlen); + if (type & (VAR_TYPE | FUNC_TYPE)) + { + addr = id_addr(tokenstr, tokenlen); + if (scan() == SET_TOKEN) + { + if (type & VAR_TYPE) + { + parse_expr(); + if (type & LOCAL_TYPE) + (type & BYTE_TYPE) ? emit_slb(addr) : emit_slw(addr); + else + (type & BYTE_TYPE) ? emit_sab(addr) : emit_saw(addr); + break; + } + } + else if (type & VAR_TYPE && scantoken == SETLIST_TOKEN) + { + parse_setlist(addr, type); + break; + } + else if ((scantoken == EOL_TOKEN) && (type & FUNC_TYPE)) + { + emit_call(addr); + break; + } + } + tokenstr = idptr; + default: + scan_rewind(tokenstr); + if ((type = parse_value(0)) != 0) + { + if (scantoken == SET_TOKEN) + { + parse_expr(); + if (type & LOCAL_TYPE) + (type & (BYTE_TYPE | BPTR_TYPE)) ? emit_sb() : emit_sw(); + else + (type & (BYTE_TYPE | BPTR_TYPE)) ? emit_sb() : emit_sw(); + } + else if (scantoken == SETLIST_TOKEN) + { + parse_setlist(0, type); + } + else + { + if (type & BPTR_TYPE) + emit_lb(); + else if (type & WPTR_TYPE) + emit_lw(); + } + } + else + { + parse_error("Syntax error"); + return (0); + } + } + if (scan() != EOL_TOKEN && scantoken != COMMENT_TOKEN) + { + parse_error("Extraneous characters"); + return (0); + } + return (1); +} +int parse_var(int type) +{ + char *idstr; + long constval; + int consttype, constsize, arraysize, idlen = 0; + long size = 1; + + if (scan() == ID_TOKEN) + { + idstr = tokenstr; + idlen = tokenlen; + if (scan() == OPEN_BRACKET_TOKEN) + { + size = 0; + parse_constexpr(&size, &constsize); + if (scantoken != CLOSE_BRACKET_TOKEN) + { + parse_error("Missing closing bracket"); + return (0); + } + scan(); + } + } + if (type == WORD_TYPE) + size *= 2; + if (scantoken == SET_TOKEN) + { + if (infunc) + { + parse_error("Cannot initiallize local variables"); + return (0); + } + if (idlen) + idglobal_add(idstr, idlen, type, 0); + if ((consttype = parse_constexpr(&constval, &constsize))) + { + /* + * Variable initialization. + */ + arraysize = emit_data(type, consttype, constval, constsize); + while (scantoken == COMMA_TOKEN) + { + if ((consttype = parse_constexpr(&constval, &constsize))) + arraysize += emit_data(type, consttype, constval, constsize); + else + { + parse_error("Bad array declaration"); + return (0); + } + } + idglobal_size(PTR_TYPE, size, arraysize); + } + else + { + parse_error("Bad variable initializer"); + return (0); + } + } + else if (idlen) + { + infunc ? idlocal_add(idstr, idlen, type, size) + : idglobal_add(idstr, idlen, type, size); + } + return (1); +} +int parse_vars(void) +{ + long value; + int type, idlen, size; + char *idstr; + + switch (scantoken) + { + case CONST_TOKEN: + if (scan() != ID_TOKEN) + { + parse_error("Missing variable"); + return (0); + } + idstr = tokenstr; + idlen = tokenlen; + if (scan() != SET_TOKEN) + { + parse_error("Bad LValue"); + return (0); + } + if (!parse_constexpr(&value, &size)) + { + parse_error("Bad constant"); + return (0); + } + idconst_add(idstr, idlen, value); + break; + case BYTE_TOKEN: + case WORD_TOKEN: + type = (scantoken == BYTE_TOKEN) ? BYTE_TYPE : WORD_TYPE; + if (!parse_var(type)) + return (0); + while (scantoken == COMMA_TOKEN) + { + if (!parse_var(type)) + return (0); + } + break; + case FUNC_TOKEN: + if (scan() == ID_TOKEN) + { + idstr = tokenstr; + idlen = tokenlen; + idfunc_add(tokenstr, tokenlen, tag_new()); + while (scan() == COMMA_TOKEN) + { + if (scan() == ID_TOKEN) + { + idstr = tokenstr; + idlen = tokenlen; + idfunc_add(tokenstr, tokenlen, tag_new()); + } + else + { + parse_error("Bad function pre-declaration"); + return (0); + } + } + } + else + { + parse_error("Bad function pre-declaration"); + return (0); + } + case EOL_TOKEN: + case COMMENT_TOKEN: + return (1); + default: + return (0); + } + return (1); +} +int parse_func(void) +{ + char c; + int func_tag, defopt, cfnparms; + optimization(0); + switch (scantoken) + { + case IFUNC_TOKEN: + case NFUNC_TOKEN: + defopt = scantoken - IFUNC_TOKEN; + if (scan() != ID_TOKEN) + { + parse_error("Missing function name"); + return (0); + } + cfnparms = 0; + infunc = 1; + if (idglobal_lookup(tokenstr, tokenlen) >= 0) + func_tag = id_addr(tokenstr, tokenlen); + else + { + func_tag = tag_new(); + idfunc_add(tokenstr, tokenlen, func_tag); + } + c = tokenstr[tokenlen]; + tokenstr[tokenlen] = '\0'; + emit_idfunc(func_tag, tokenstr); + tokenstr[tokenlen] = c; + retfunc_tag = tag_new(); + idlocal_reset(); + localsize = 2; + if (scan() == OPEN_PAREN_TOKEN) + { + do + { + if (scan() == ID_TOKEN) + { + cfnparms++; + idlocal_add(tokenstr, tokenlen, WORD_TYPE, 2); + scan(); + } + } while (scantoken == COMMA_TOKEN); + if (scantoken != CLOSE_PAREN_TOKEN) + { + parse_error("Bad function parameter list"); + return (0); + } + scan(); + } + while (parse_vars()) next_line(); + emit_def(defopt); + emit_enter(localsize, cfnparms); + prevstmnt = 0; + while (parse_stmnt()) next_line(); + infunc = 0; + if (scantoken != END_TOKEN) + { + parse_error("Syntax error"); + return (0); + } + if (scan() != EOL_TOKEN && scantoken != COMMENT_TOKEN) + { + parse_error("Extraneous characters"); + return (0); + } + if (prevstmnt != RETURN_TOKEN) + emit_leave(localsize); + return (1); + case ASM_TOKEN: + if (scan() != ID_TOKEN) + { + parse_error("Missing function name"); + return (0); + } + cfnparms = 0; + infunc = 1; + if (idglobal_lookup(tokenstr, tokenlen) >= 0) + func_tag = id_addr(tokenstr, tokenlen); + else + { + func_tag = tag_new(); + idfunc_add(tokenstr, tokenlen, func_tag); + } + c = tokenstr[tokenlen]; + tokenstr[tokenlen] = '\0'; + emit_idfunc(func_tag, tokenstr); + tokenstr[tokenlen] = c; + retfunc_tag = tag_new(); + idlocal_reset(); + localsize = 2; + if (scan() == OPEN_PAREN_TOKEN) + { + do + { + if (scan() == ID_TOKEN) + { + cfnparms++; + idlocal_add(tokenstr, tokenlen, WORD_TYPE, 2); + scan(); + } + } while (scantoken == COMMA_TOKEN); + if (scantoken != CLOSE_PAREN_TOKEN) + { + parse_error("Bad function parameter list"); + return (0); + } + scan(); + } + while (parse_vars()) next_line(); + emit_def(1); + emit_enter(localsize, cfnparms); + prevstmnt = 0; + do + { + if (scantoken == EOL_TOKEN) + next_line(); + else if (scantoken != END_TOKEN) + { + emit_asm(inputline); + next_line(); + } + } while (scantoken != END_TOKEN); + emit_leave(localsize); + infunc = 0; + return (1); + case EOL_TOKEN: + case COMMENT_TOKEN: + return (1); + } + return (0); +} +int parse_module(void) +{ + if (next_line()) + { + while (parse_vars()) next_line(); + while (parse_func()) next_line(); + if (scantoken != DONE_TOKEN && scantoken != EOF_TOKEN) + { + optimization(0); + emit_start(); + prevstmnt = 0; + while (parse_stmnt()) next_line(); + if (scantoken != DONE_TOKEN) + parse_error("Missing DONE statement"); + emit_ret(); + } + return (1); + } + return (0); +} +int main(int argc, char **argv) +{ + int optc = 1; + if (argc > optc && argv[optc][0] == '-') + { + emit_flags(EDASM); + optc++; + } + if (argc > optc && argv[optc][0] == '$') + optc++; + else + emit_header(); + if (parse_module()) + { + fprintf(stderr, "Compilation complete.\n"); + emit_trailer(); + } + return (0); +} diff --git a/plasma2/parse.o b/plasma2/parse.o new file mode 100755 index 0000000..ed52156 Binary files /dev/null and b/plasma2/parse.o differ diff --git a/plasma2/plas.pla b/plasma2/plas.pla new file mode 100755 index 0000000..3af959c --- /dev/null +++ b/plasma2/plas.pla @@ -0,0 +1,2731 @@ +; +; Global constants +; +const FALSE = 0 +const TRUE = !FALSE +; +; Data and code buffer variables +; +const iobuffer = $0800 +const compbuff = $6000 +const compbuffsz = $4000 +const func_dict = $5000 +const fixup_tbl = $4000 +const argbuff = $2006 +const inbuff = $0200 +const instr = $01FF +byte ioref +word filename +; +; REL file tables +; +word datalen, codelen +word fixup = fixup_tbl +word numfuncs = 1 +; +; Symbol table variables +; +const idglobal_tblsz = $0800 +const idlocal_tblsz = $0200 +const idglobal_tbl = $1000 +const idlocal_tbl = $1800 +const ctag_max = 768 +const ctag_value = $1A00 +const ctag_flags = $0D00 +const idval = 0 +const idtype = 2 +const idname = 3 +const idrecsz = 4 +word globals = 0 +word datasize = 0 +word lastglobal +byte locals = 0 +word framesize = 0 +word lastlocal +const resolved = 1 +const is_ctag = $8000 +const mask_ctag = $7FFF +word codetag = -1 +; +; Symbol types +; +const EXTERN_SYM = $10 +const EXPORT_SYM = $08 +; +; Compiler pointers +; +word codeptr +word entrypoint = 0 +byte lastop = $FF +byte perr +; +; String variables +; +byte version[] = "PLASMA ][ COMPILER VERSION 0.8 " +byte badfile[] = "FILE NOT FOUND" +; +; Tokens +; +const ID_TKN = $D6 ; V +const CHR_TKN = $C3 ; C +const INT_TKN = $C9 ; I +const STR_TKN = $D3 ; S +const EOL_TKN = $02 +const EOF_TKN = $01 +const ERR_TKN = $00 +; +; Binary operand operators +; +const SET_TKN = $BD ; = +const SETLIST_TKN = $B9 ; =, +const ADD_TKN = $AB ; + +const SUB_TKN = $AD ; - +const MUL_TKN = $AA ; * +const DIV_TKN = $AF ; / +const MOD_TKN = $A5 ; % +const OR_TKN = $BF ; ? +const EOR_TKN = $DE ; ^ +const AND_TKN = $A6 ; & +const SHR_TKN = $D2 ; R +const SHL_TKN = $CC ; L +const GT_TKN = $BE ; > +const GE_TKN = $C8 ; H +const LT_TKN = $BC ; < +const LE_TKN = $C2 ; B +const NE_TKN = $D5 ; U +const EQ_TKN = $C5 ; E +const LOGIC_AND_TKN = $CE ; N +const LOGIC_OR_TKN = $CF ; O +; +; Unary operand operators +; +const AT_TKN = $C0 ; @ +const DOT_TKN = $AE ; . +const COLON_TKN = $BA ; : +const NEG_TKN = $AD ; - +const COMP_TKN = $A3 ; # +const LOGIC_NOT_TKN = $A1 ; ! +const BPTR_TKN = $DE ; ^ +const WPTR_TKN = $AA ; * +const INC_TKN = $C1 ; A +const DEC_TKN = $C4 ; D +; +; Enclosure tokens +; +const OPEN_PAREN_TKN = $A8 ; ( +const CLOSE_PAREN_TKN = $A9 ; ) +const OPEN_BRACKET_TKN = $DB ; [ +const CLOSE_BRACKET_TKN = $DD ; ] +; +; Misc. tokens +; +const COMMA_TKN = $AC ; , +const COMMENT_TKN = $BB ; ; +; +; Keyword tokens +; +const CONST_TKN = $80 +const BYTE_TKN = $81 +const WORD_TKN = $82 +const IF_TKN = $83 +const ELSEIF_TKN = $84 +const ELSE_TKN = $85 +const FIN_TKN = $86 +const END_TKN = $87 +const WHILE_TKN = $88 +const LOOP_TKN = $89 +const CASE_TKN = $8A +const OF_TKN = $8B +const DEFAULT_TKN = $8C +const ENDCASE_TKN = $8D +const FOR_TKN = $8E +const TO_TKN = $8F +const DOWNTO_TKN = $90 +const STEP_TKN = $91 +const NEXT_TKN = $92 +const REPEAT_TKN = $93 +const UNTIL_TKN = $94 +const DEF_TKN = $95 +const OPT_TKN = $96 +const DROP_TKN = $97 +const DONE_TKN = $98 +const RETURN_TKN = $99 +const BREAK_TKN = $9A +const EVAL_TKN = $9D +const FUNC_TKN = $9E +const EXTERN_TKN = $9F +const ENTRY_TKN = $A0 +const IMPORT_TKN = $A1 +const INCLUDE_TKN = $A2 +; +; Types +; +const CONST_TYPE = $01 +const BYTE_TYPE = $02 +const WORD_TYPE = $04 +const VAR_TYPE = $06 ; (WORD_TYPE | BYTE_TYPE) +const FUNC_TYPE = $08 +const FUNC_CONST_TYPE = $09 +const ADDR_TYPE = $0E ; (VAR_TYPE | FUNC_TYPE) +const LOCAL_TYPE = $10 +const BPTR_TYPE = $20 +const WPTR_TYPE = $40 +const PTR_TYPE = $60 ; (BPTR_TYPE | WPTR_TYPE) +const XBYTE_TYPE = $22 ; (BPTR_TYPE | BYTE_TYPE) +const XWORD_TYPE = $44 ; (WPTR_TYPE | WORD_TYPE) +const STR_TYPE = $80 +; +; Keywords +; +byte keywrds[] +byte = "IF", IF_TKN +byte = "TO", TO_TKN +byte = "IS", OF_TKN +byte = "OR", LOGIC_OR_TKN +byte = "FOR", FOR_TKN +byte = "FIN", FIN_TKN +byte = "DEF", DEF_TKN +byte = "END", END_TKN +byte = "AND", LOGIC_AND_TKN +byte = "NOT", LOGIC_NOT_TKN +byte = "BYTE", BYTE_TKN +byte = "WORD", WORD_TKN +byte = "DROP", DROP_TKN +byte = "ELSE", ELSE_TKN +byte = "NEXT", NEXT_TKN +byte = "WHEN", CASE_TKN +byte = "LOOP", LOOP_TKN +byte = "FUNC", FUNC_TKN +byte = "STEP", STEP_TKN +byte = "DONE", DONE_TKN +byte = "WEND", ENDCASE_TKN +byte = "ENTRY", ENTRY_TKN +byte = "CONST", CONST_TKN +byte = "ELSIF", ELSEIF_TKN +byte = "WHILE", WHILE_TKN +byte = "UNTIL", UNTIL_TKN +byte = "BREAK", BREAK_TKN +byte = "OTHER", DEFAULT_TKN +byte = "DOWNTO", DOWNTO_TKN +byte = "REPEAT", REPEAT_TKN +byte = "RETURN", RETURN_TKN +byte = "EXTERN", EXTERN_TKN +byte = "IMPORT", IMPORT_TKN +byte = "INCLUDE", INCLUDE_TKN +byte = $FF +; +; Mathematical ops +; +const bops_tblsz = 18 ; minus 1 +byte bops_tbl[] ; Highest precedence +byte = MUL_TKN, DIV_TKN, MOD_TKN +byte = ADD_TKN, SUB_TKN +byte = SHR_TKN, SHL_TKN +byte = AND_TKN +byte = EOR_TKN +byte = OR_TKN +byte = GT_TKN, GE_TKN, LT_TKN, LE_TKN +byte = EQ_TKN, NE_TKN +byte = LOGIC_AND_TKN +byte = LOGIC_OR_TKN +byte = COMMA_TKN + ; Lowest precedence +byte bops_prec[] ; Highest precedence +byte = 1, 1, 1 +byte = 2, 2 +byte = 3, 3 +byte = 4 +byte = 5 +byte = 6 +byte = 7, 7, 7, 7 +byte = 8, 8 +byte = 9 +byte = 10 +byte = 11 + ; Lowest precedence +byte opstack[16] +byte precstack[16] +word opsp = -1 +; +; Scanner variables +; +byte token, tknlen +word scanptr, tknptr +word constval +word lineno = 0 +; +; Compiler output messages +; +byte dup_id[] = "DUPLICATE IDENTIFIER" +byte undecl_id[] = "UNDECLARED IDENTIFIER" +byte bad_cnst[] = "BAD CONSTANT" +byte bad_offset[] = "BAD STRUCT OFFSET" +byte bad_decl[] = "BAD DECLARATION" +byte bad_op[] = "BAD OPERATION" +byte bad_stmnt[] = "BAD STATMENT" +byte bad_expr[] = "BAD EXPRESSION" +byte bad_syntax[] = "BAD SYNTAX" +byte estk_overflw[] = "EVAL STACK OVERFLOW" +byte estk_underflw[] = "EVAL STACK UNDERFLOW" +byte local_overflw[] = "LOCAL FRAME OVERFLOW" +byte global_sym_overflw[] = "GLOBAL SYMBOL TABLE OVERFLOW" +byte local_sym_overflw[] = "LOCAL SYMBOL TABLE OVERFLOW" +byte ctag_full[] = "CODE LABEL OVERFLOW" +byte no_close_paren[] = "MISSING CLOSING PAREN" +byte no_close_bracket[] = "MISSING CLOSING BRACKET" +byte missing_op[] = "MISSING OPERAND" +byte no_fin[] = "MISSING FIN" +byte no_loop[] = "MISSING LOOP" +byte no_until[] = "MISSING UNTIL" +byte no_done[] = "MISSING DONE" +byte no_local_init[] = "NO INITIALIZED LOCALS" +; +; Runtime functions +; +byte runtime0[] = "romcall" +byte RUNTIME0[] = "ROMCALL" +byte runtime1[] = "syscall" +byte RUNTIME1[] = "SYSCALL" +byte runtime2[] = "memset" +byte RUNTIME2[] = "MEMSET" +byte runtime3[] = "memcpy" +byte RUNTIME3[] = "MEMCPY" +byte runtime4[] = "cout" +byte RUNTIME4[] = "COUT" +byte runtime5[] = "cin" +byte RUNTIME5[] = "CIN" +byte runtime6[] = "prstr" +byte RUNTIME6[] = "PRSTR" +byte runtime7[] = "rdstr" +byte RUNTIME7[] = "RDSTR" +; +; Parser variables +; +byte infunc = 0 +byte stack_loop = 0 +byte prevstmnt = 0 +word retfunc_tag = 0 +word break_tag = 0 +func parse_expr_01, parse_module_01 +; +; Defines for ASM routines +; +asm equates + TMP EQU $F0 + TMPL EQU TMP + TMPH EQU TMP+1 + SRC EQU TMP + SRCL EQU SRC + SRCH EQU SRC+1 + DST EQU SRC+2 + DSTL EQU DST + DSTH EQU DST+1 + ESP EQU DST+2 + SAVEESP EQU ESP+1 + SAVESP EQU SAVEESP+1 + SAVEFP EQU SAVESP+1 + SAVETMR EQU SAVEFP+2 + SAVEINT EQU SAVETMR+2 + TMRVEC EQU $03E8 + INTVEC EQU $03EA +JMPTMP: JMP (TMP) +end +; +; CALL 6502 ROUTINE +; ROMCALL(AREG, XREG, YREG, STATUS, ADDR) +; +asm romcall + PHP + LDA ESTKL,X + STA TMPL + LDA ESTKH,X + STA TMPH + INX + LDA ESTKL,X + PHA + INX + LDA ESTKL,X + TAY + INX + LDA ESTKL+1,X + PHA + LDA ESTKL,X + INX + STX ESP + TAX + PLA + BIT ROMIN + PLP + JSR JMPTMP + PHP + BIT LCBNK2 + STA REGVALS+0 + STX REGVALS+1 + STY REGVALS+2 + PLA + STA REGVALS+3 + LDX ESP + LDA #REGVALS + STA ESTKL,X + STY ESTKH,X + PLP + RTS +REGVALS: DS 4 +end +; +; CALL PRODOS +; SYSCALL(CMD, PARAMS) +; +asm syscall + LDA ESTKL,X + LDY ESTKH,X + STA PARAMS + STY PARAMS+1 + INX + LDA ESTKL,X + STA CMD + STX ESP + BIT ROMIN + JSR $BF00 +CMD: DB 00 +PARAMS: DW 0000 + BIT LCBNK2 + LDX ESP + STA ESTKL,X + LDY #$00 + STY ESTKH,X +end +; +; SET MEMORY TO VALUE +; MEMSET(VALUE, ADDR, SIZE) +; +asm memset + LDY #$00 + LDA ESTKL+1,X + STA DSTL + LDA ESTKH+1,X + STA DSTH + INC ESTKL,X + INC ESTKH,X +SETMEM: DEC ESTKL,X + BNE :+ + DEC ESTKH,X + BEQ MEMEXIT +: LDA ESTKL+2,X + STA (DST),Y + INY + BNE :+ + INC DSTH +: DEC ESTKL,X + BNE :+ + DEC ESTKH,X + BEQ MEMEXIT +: LDA ESTKH+2,X + STA (DST),Y + INY + BNE SETMEM + INC DSTH + BNE SETMEM +MEMEXIT: INX + INX + INX +end +; +; COPY MEMORY +; MEMCPY(SRCADDR, DSTADDR, SIZE) +; +asm memcpy + LDY #$00 + LDA ESTKL,X + BNE :+ + LDA ESTKH,X + BEQ MEMEXIT +: LDA ESTKL+1,X + STA DSTL + LDA ESTKH+1,X + STA DSTH + LDA ESTKL+2,X + STA SRCL + LDA ESTKH+2,X + STA SRCH + CMP DSTH + BCC REVCPY + BNE FORCPY + LDA SRCL + CMP DSTL + BCS FORCPY +REVCPY: ; REVERSE DIRECTION COPY +; CLC + LDA ESTKL,X + ADC DSTL + STA DSTL + LDA ESTKH,X + ADC DSTH + STA DSTH + CLC + LDA ESTKL,X + ADC SRCL + STA SRCL + LDA ESTKH,X + ADC SRCH + STA SRCH + INC ESTKH,X +REVCPYLP: + LDA DSTL + BNE :+ + DEC DSTH +: DEC DSTL + LDA SRCL + BNE :+ + DEC SRCH +: DEC SRCL + LDA (SRC),Y + STA (DST),Y + DEC ESTKL,X + BNE REVCPYLP + DEC ESTKH,X + BNE REVCPYLP + BEQ MEMEXIT +FORCPY: INC ESTKH,X +FORCPYLP: + LDA (SRC),Y + STA (DST),Y + INC DSTL + BNE :+ + INC DSTH +: INC SRCL + BNE :+ + INC SRCH +: DEC ESTKL,X + BNE FORCPYLP + DEC ESTKH,X + BNE FORCPYLP + BEQ MEMEXIT +end +; +; CHAR OUT +; COUT(CHAR) +; +asm cout + LDA ESTKL,X + INX + ORA #$80 + BIT ROMIN + JSR $FDED + BIT LCBNK2 +end +; +; CHAR IN +; RDKEY() +; +asm cin + BIT ROMIN + STX ESP + JSR $FD0C + LDX ESP + BIT LCBNK2 + DEX + AND #$7F + STA ESTKL,X + LDY #$00 + STY ESTKH,X +end +; +; PRINT STRING +; PRSTR(STR) +; +asm prstr + LDY #$00 + LDA ESTKL,X + STA SRCL + LDA ESTKH,X + STA SRCH + BIT ROMIN + LDA (SRC),Y + STA ESTKL,X + BEQ :+ +_PRS1: INY + LDA (SRC),Y + ORA #$80 + JSR $FDED + TYA + CMP ESTKL,X + BNE _PRS1 +: INX + BIT LCBNK2 +end +; +; READ STRING +; STR = RDSTR(PROMPTCHAR) +; +asm rdstr + LDA ESTKL,X + STA $33 + STX ESP + BIT ROMIN + JSR $FD6A + BIT LCBNK2 + STX $01FF +: LDA $01FF,X + AND #$7F + STA $01FF,X + DEX + BPL :- + LDX ESP + LDA #$FF + STA ESTKL,X + LDA #$01 + STA ESTKH,X +end +;def toupper_11(c) +; if c >= 'a' +; if c <= 'z' +; return c - $20 +; fin +; fin +; return c +;end +asm toupper_11 + LDA ESTKL,X + CMP #'a' + BCC :+ + CMP #'z'+1 + BCS :+ + SEC + SBC #$20 + STA ESTKL,X +: +end +; +; EXIT +; +asm exit + JSR $BF00 + DB $65 + DW EXITTBL +EXITTBL: + DB 4 + DB 0 +end +; +; ProDOS routines +; +def getpfx_11(path) + byte params[3] + + ^path = 0 + params.0 = 1 + params:1 = path + perr = syscall($C7, @params) + return path +end +def setpfx_11(path) + byte params[3] + + params.0 = 1 + params:1 = path + perr = syscall($C6, @params) + return path +end +def open_21(path, buff) + byte params[6] + + params.0 = 3 + params:1 = path + params:3 = buff + params.5 = 0 + perr = syscall($C8, @params) + return params.5 +end +def close_11(refnum) + byte params[2] + + params.0 = 1 + params.1 = refnum + perr = syscall($CC, @params) + return perr +end +def read_31(refnum, buff, len) + byte params[8] + + params.0 = 4 + params.1 = refnum + params:2 = buff + params:4 = len + params:6 = 0 + perr = syscall($CA, @params) + return params:6 +end +def write_31(refnum, buff, len) + byte params[8] + + params.0 = 4 + params.1 = refnum + params:2 = buff + params:4 = len + params:6 = 0 + perr = syscall($CB, @params) + return params:6 +end +def create_41(path, access, type, aux) + byte params[12] + + params.0 = 7 + params:1 = path + params.3 = access + params.4 = type + params:5 = aux + params.7 = $1 + params:8 = 0 + params:10 = 0 + perr = syscall($C0, @params) + return perr +end +def destroy_11(path) + byte params[12] + + params.0 = 1 + params:1 = path + perr = syscall($C1, @params) + return perr +end +def newline_31(refnum, emask, nlchar) + byte params[4] + + params.0 = 3 + params.1 = refnum + params.2 = emask + params.3 = nlchar + perr = syscall($C9, @params) + return perr +end +def crout + cout($0D) +end +def prbyte_10(h) + cout('$') + drop romcall(h, 0, 0, 0, $FDDA) +end +def prword_10(h) + cout('$') + drop romcall(h >> 8, h, 0, 0, $F941) +end +def print_10(i) + byte numstr[7] + byte place, sign + + place = 6 + if i < 0 + sign = 1 + i = -i + else + sign = 0 + fin + while i >= 10 + i =, numstr[place] = i % 10 + '0' + place = place - 1 + loop + numstr[place] = i + '0' + place = place - 1 + if sign + numstr[place] = '-' + place = place - 1 + fin + numstr[place] = 6 - place + prstr(@numstr[place]) +end +def nametostr_30(namestr, len, strptr) + ^strptr = len + memcpy(namestr, strptr + 1, len) +end + +;===================================== +; +; PLASMA Compiler +; +;===================================== + +; +; Error handler +; +def parse_err_11(err) + word i + + drop close_11(0) + crout() + print_10(lineno) + cout(':') + prstr(err) + crout() + prstr(instr) + crout() + for i = inbuff to tknptr - 1 + cout(' ') + next + cout('^') + cin() + exit() + return ERR_TKN +end +; +; Fixup table and function directory +; +def fixupword_add10(addr) +end +def fixupbyte_add10(addr) +end +def func_add(offset, len, flags) +end +; +; Emit bytecode +; +def ctag_new_01 + if codetag >= ctag_max + return parse_err_11(@ctag_full) + fin + codetag = codetag + 1 + ctag_value:[codetag] = 0 + ctag_flags.[codetag] = 0 + return codetag ? is_ctag +end +defopt ctag_resolve_21(tag, addr) + word updtptr, nextptr + + tag = tag & mask_ctag + if ctag_flags.[tag] & resolved + return parse_err_11(@dup_id) + fin + updtptr = ctag_value:[tag] + while updtptr + ; + ; Update list of addresses needing resolution + ; + nextptr = *updtptr + *updtptr = addr + updtptr = nextptr + loop + ctag_value:[tag] = addr + ctag_flags.[tag] = ctag_flags.[tag] ? resolved + return 0 +end +defopt emit_byte_10(bval) + ^codeptr = bval + codeptr = codeptr + 1 +end +defopt emit_word_10(wval) + *codeptr = wval + codeptr = codeptr + 2 +end +def emit_fill_10(size) + memset(0, codeptr, size) + codeptr = codeptr + size +end +def emit_codetag_10(tag) + drop ctag_resolve_21(tag, codeptr) +end +defopt emit_op_10(op) + lastop = op + ^codeptr = op + codeptr = codeptr + 1 +end +def emit_tag_10(tag) + word updtptr + + if tag & is_ctag + tag = tag & mask_ctag + updtptr = ctag_value:[tag] + if !(ctag_flags.[tag] & resolved) + ; + ; Add to list of tags needing resolution + ; + ctag_value:[tag] = codeptr + fin + emit_word_10(updtptr) + else + emit_word_10(tag + compbuff) + fin +end +def emit_iddata_30(value, size, namestr) + emit_fill_10(size) +end +def emit_data_41(vartype, consttype, constval, constsize) + byte i + word size, chrptr + + if consttype == 0 + size = constsize + emit_fill_10(constsize) + elsif consttype == STR_TYPE + size = constsize + chrptr = constval + constsize = constsize - 1 + emit_byte_10(constsize) + while constsize > 0 + emit_byte_10(^chrptr) + chrptr = chrptr + 1 + constsize = constsize - 1 + loop + else + if vartype == WORD_TYPE + size = 2 + emit_word_10(constval) + else + size = 1 + emit_byte_10(constval) + fin + fin + return size +end +def emit_const_10(cval) + if cval == 0 + emit_op_10($00) + elsif cval > 0 and cval < 256 + emit_op_10($2A) + emit_byte_10(cval) + else + emit_op_10($2C) + emit_word_10(cval) + fin +end +def emit_lb + emit_op_10($60) +end +def emit_lw + emit_op_10($62) +end +def emit_llb_10(index) + emit_op_10($64) + emit_byte_10(index) +end +def emit_llw_10(index) + emit_op_10($66) + emit_byte_10(index) +end +def emit_lab_10(tag) + emit_op_10($68) + emit_tag_10(tag) +end +def emit_law_10(tag) + emit_op_10($6A) + emit_tag_10(tag) +end +def emit_sb + emit_op_10($70) +end +def emit_sw + emit_op_10($72) +end +def emit_slb_10(index) + emit_op_10($74) + emit_byte_10(index) +end +def emit_slw_10(index) + emit_op_10($76) + emit_byte_10(index) +end +def emit_dlb_10(index) + emit_op_10($6C) + emit_byte_10(index) +end +def emit_dlw_10(index) + emit_op_10($6E) + emit_byte_10(index) +end +def emit_sab_10(tag) + emit_op_10($78) + emit_tag_10(tag) +end +def emit_saw_10(tag) + emit_op_10($7A) + emit_tag_10(tag) +end +def emit_dab_10(tag) + emit_op_10($7C) + emit_tag_10(tag) +end +def emit_daw_10(tag) + emit_op_10($7E) + emit_tag_10(tag) +end +def emit_call_10(tag) + emit_op_10($54) + emit_tag_10(tag) +end +def emit_ical + emit_op_10($56) +end +def emit_push + emit_op_10($34) +end +def emit_pull + ; + ; Skip if last op was push + ; + if lastop == $34 + codeptr = codeptr - 1 + lastop = $FF + else + emit_op_10($36) + fin +end +def emit_localaddr_10(index) + emit_op_10($28) + emit_byte_10(index) +end +def emit_globaladdr_10(tag) + emit_op_10($26) + emit_tag_10(tag) +end +def emit_indexbyte + emit_op_10($02) +end +def emit_indexword + emit_op_10($1E) +end +defopt emit_unaryop_11(op) + when op + is NEG_TKN + emit_op_10($10) + is COMP_TKN + emit_op_10($12) + is LOGIC_NOT_TKN + emit_op_10($20) + is INC_TKN + emit_op_10($0C) + is DEC_TKN + emit_op_10($0E) + is BPTR_TKN + emit_op_10($60) + is WPTR_TKN + emit_op_10($62) + otherwise + return FALSE + wend + return TRUE +end +defopt emit_binaryop_11(op) + when op + is MUL_TKN + ; + ; Replace MUL 2 with SHL 1 + ; + if lastop == $2A and ^(codeptr - 1) == 2 ; CB 2 + codeptr = codeptr - 1 + emit_byte_10(1) ; CB 1 + emit_op_10($1A) ; SHL + else + emit_op_10($06) + fin + is DIV_TKN + ; + ; Replace DIV 2 with SHR 1 + ; + if lastop == $2A and ^(codeptr - 1) == 2 ; CB 2 + codeptr = codeptr - 1 + emit_byte_10(1) ; CB 1 + emit_op_10($1C) ; SHR + else + emit_op_10($08) + fin + is MOD_TKN + emit_op_10($0A) + is ADD_TKN + ; + ; Replace ADD 1 with INCR + ; + if lastop == $2A and ^(codeptr - 1) == 1 ; CB 1 + codeptr = codeptr - 2 + emit_op_10($0C) ; INC_OP + else + emit_op_10($02) + fin + is SUB_TKN + ; + ; Replace SUB 1 with DECR + ; + if lastop == $2A and ^(codeptr - 1) == 1 ; CB 1 + codeptr = codeptr - 2 + emit_op_10($0E) ; DEC_OP + else + emit_op_10($04) + fin + is SHL_TKN + emit_op_10($1A) + is SHR_TKN + emit_op_10($1C) + is AND_TKN + emit_op_10($14) + is OR_TKN + emit_op_10($16) + is EOR_TKN + emit_op_10($18) + is EQ_TKN + emit_op_10($40) + is NE_TKN + emit_op_10($42) + is GE_TKN + emit_op_10($48) + is LT_TKN + emit_op_10($46) + is GT_TKN + emit_op_10($44) + is LE_TKN + emit_op_10($4A) + is LOGIC_OR_TKN + emit_op_10($22) + is LOGIC_AND_TKN + emit_op_10($24) + is COMMA_TKN + ; Do nothing except move to next stanza in expression + otherwise + return FALSE + wend + return TRUE +end +def emit_brtru_10(tag) + emit_op_10($4E) + emit_tag_10(tag) +end +def emit_brfls_10(tag) + emit_op_10($4C) + emit_tag_10(tag) +end +def emit_brgt_10(tag) + emit_op_10($3A) + emit_tag_10(tag) +end +def emit_brlt_10(tag) + emit_op_10($38) + emit_tag_10(tag) +end +def emit_brne_10(tag) + emit_op_10($3E) + emit_tag_10(tag) +end +def emit_jump_10(tag) + emit_op_10($50) + emit_tag_10(tag) +end +def emit_drop + emit_op_10($30) +end +def emit_swap + emit_op_10($2E) +end +def emit_leave_10(framesize) + if framesize > 2 + emit_op_10($5A) + else + emit_op_10($5C) + fin +end +def emit_enter_20(framesize, cparams) + emit_byte_10($20) + emit_byte_10($D0) + emit_byte_10($03) + if framesize > 2 + emit_op_10($58) + emit_byte_10(framesize) + emit_byte_10(cparams) + fin +end +def emit_start + ; + ; Save address + ; + entrypoint = codeptr + emit_byte_10(emit_start.[0]) + emit_byte_10(emit_start.[1]) + emit_byte_10(emit_start.[2]) +end +; +; Lexical anaylzer +; +;def isalpha_11(c) +; if c >= 'A' and c <= 'Z' +; return TRUE +; elsif c >= 'a' and c <= 'z' +; return TRUE +; elsif c == '_' +; return TRUE +; fin +; return FALSE +;end +asm isalpha_11 + LDY #$00 + LDA ESTKL,X + CMP #'A' + BCC ISALRET + CMP #'Z'+1 + BCS :+ + DEY + BNE ISALRET +: CMP #'a' + BCC ISALRET + CMP #'z'+1 + BCS :+ + DEY + BNE ISALRET +: CMP #'_' + BNE ISALRET + DEY +ISALRET: + STY ESTKL,X + STY ESTKH,X + RTS +end +;def isnum_11(c) +; if c >= '0' and c <= '9' +; return TRUE +; fin +; return FALSE +;end +asm isnum_11 + LDY #$00 + LDA ESTKL,X + CMP #'0' + BCC :+ + CMP #'9'+1 + BCS :+ + DEY +: STY ESTKL,X + STY ESTKH,X + RTS +end +;def isalphanum_11(c) +; if c >= 'A' and c <= 'Z' +; return TRUE +; elsif c >= '0' and c <= '9' +; return TRUE +; elsif c >= 'a' and c <= 'z' +; return TRUE +; elsif c == '_' +; return TRUE +; fin +; return FALSE +;end +asm isalphanum_11 + LDY #$00 + LDA ESTKL,X + CMP #'0' + BCC ISANRET + CMP #'9'+1 + BCS :+ + DEY + BNE ISANRET +: CMP #'A' + BCC ISANRET + CMP #'Z'+1 + BCS :+ + DEY + BNE ISANRET +: CMP #'a' + BCC :+ + CMP #'z'+1 + BCS ISANRET + DEY + BNE ISANRET +: CMP #'_' + BNE ISANRET + DEY +ISANRET: + STY ESTKL,X + STY ESTKH,X + RTS +end +defopt keymatch_21(chrptr, len) + byte i, keypos + + keypos = 0 + while keywrds[keypos] < len + keypos = keypos + keywrds[keypos] + 2 + loop + while keywrds[keypos] == len + for i = 1 to len + if toupper_11((chrptr).[i - 1]) <> keywrds[keypos + i] + break + fin + next + if i > len + return keywrds[keypos + keywrds[keypos] + 1] + fin + keypos = keypos + keywrds[keypos] + 2 + loop + return ID_TKN +end +defopt scan_01 + ; + ; Scan for token based on first character + ; + while ^scanptr and ^scanptr <= ' ' + scanptr = scanptr + 1 + loop + tknptr = scanptr + if !^scanptr or ^scanptr == ';' + if token <> EOF_TKN + token = EOL_TKN + fin + elsif isalpha_11(^scanptr) + ; + ; ID, either variable name or reserved word + ; + repeat + scanptr = scanptr + 1 + until !isalphanum_11(^scanptr) + tknlen = scanptr - tknptr; + token = keymatch_21(tknptr, tknlen) + elsif isnum_11(^scanptr) + ; + ; Number constant + ; + token = INT_TKN + constval = 0 + repeat + constval = constval * 10 + ^scanptr - '0' + scanptr = scanptr + 1 + until !isnum_11(^scanptr) + elsif ^scanptr == '$' + ; + ; Hexadecimal constant + ; + token = INT_TKN; + constval = 0 + repeat + scanptr = scanptr + 1 + if ^scanptr >= '0' and ^scanptr <= '9' + constval = (constval << 4) + ^scanptr - '0' + elsif ^scanptr >= 'A' and ^scanptr <= 'F' + constval = (constval << 4) + ^scanptr - '7'; 'A'-10 + elsif ^scanptr >= 'a' and ^scanptr <= 'f' + constval = (constval << 4) + ^scanptr - 'W'; 'a'-10 + else + break; + fin + until !^scanptr + elsif ^scanptr == $27 ; ' + ; + ; Character constant + ; + token = CHR_TKN + if ^(scanptr + 1) <> $5C ; \ + constval = ^(scanptr + 1) + if ^(scanptr + 2) <> $27 ; ' + return parse_err_11(@bad_cnst) + fin + scanptr = scanptr + 3 + else + when ^(scanptr + 2) + is 'n' + constval = $0D + is 'r' + constval = $0A + is 't' + constval = $09 + otherwise + constval = ^(scanptr + 2) + wend + if ^(scanptr + 3) <> $27 ; ' + return parse_err_11(@bad_cnst) + fin + scanptr = scanptr + 4 + fin + elsif ^scanptr == '"' + ; + ; String constant + ; + token = STR_TKN + scanptr = scanptr + 1 + constval = scanptr + while ^scanptr and ^scanptr <> '"' + scanptr = scanptr + 1 + loop + if !^scanptr + return parse_err_11(@bad_cnst) + fin + scanptr = scanptr + 1 + else + ; + ; Potential two and three character tokens + ; + when ^scanptr + is '>' + if ^(scanptr + 1) == '>' + token = SHR_TKN + scanptr = scanptr + 2 + elsif ^(scanptr + 1) == '=' + token = GE_TKN + scanptr = scanptr + 2 + else + token = GT_TKN + scanptr = scanptr + 1 + fin + is '<' + if ^(scanptr + 1) == '<' + token = SHL_TKN + scanptr = scanptr + 2 + elsif ^(scanptr + 1) == '=' + token = LE_TKN + scanptr = scanptr + 2 + elsif ^(scanptr + 1) == '>' + token = NE_TKN + scanptr = scanptr + 2 + else + token = LT_TKN + scanptr = scanptr + 1 + fin + is '=' + if ^(scanptr + 1) == '=' + token = EQ_TKN + scanptr = scanptr + 2; + elsif ^(scanptr + 1) == ',' + token = SETLIST_TKN + scanptr = scanptr + 2; + else + token = SET_TKN; + scanptr = scanptr + 1 + fin + otherwise + ; + ; Simple single character tokens + ; + token = ^scanptr ? $80 + scanptr = scanptr + 1 + wend + fin + tknlen = scanptr - tknptr + return token +end +def rewind_10(ptr) + scanptr = ptr +end +; +; Get next line of input +; +def nextln_01 + byte i, chr + + scanptr = inbuff + ^instr = read_31(ioref, inbuff, $7F) + inbuff[^instr] = $00 + if ^instr + lineno = lineno + 1 + if !(lineno & $0F) + cout('.') + fin +; cout('>') +; prstr(instr) +; crout + drop scan_01() + else + ^instr = 0 + ^inbuff = $00 + token = DONE_TKN + fin + return ^instr +end +; +; Alebraic op to stack op +; +def push_op_21(op, prec) + opsp = opsp + 1 + if opsp == 16 + return parse_err_11(@estk_overflw) + fin + opstack[opsp] = op + precstack[opsp] = prec + return 0 +end +def pop_op_01 + if opsp < 0 + return parse_err_11(@estk_underflw) + fin + opsp = opsp - 1 + return opstack[opsp + 1] +end +def tos_op_01 + if opsp < 0 + return 0 + fin + return opstack[opsp] +end +def tos_op_prec_11(tos) + if opsp <= tos + return 100 + fin + return precstack[opsp] +end +; +; Symbol table +; +defopt idmatch_41(nameptr, len, idptr, idcnt) + byte i + + while idcnt + if len == (idptr).idname + for i = 1 to len + if (nameptr).[i - 1] <> (idptr).idname.[i] + break + fin + next + if i > len + return idptr + fin + fin + idptr = idptr + (idptr).idname + idrecsz + idcnt = idcnt - 1 + loop + return 0 +end +;def dumpsym_20(idptr, idcnt) +; while idcnt +; prword_10((idptr):idval) +; cout(' ') +; prbyte_10((idptr).idtype) +; cout(' ') +; prstr(@(idptr).idname) +; cout('=') +; if (idptr).idtype & ADDR_TYPE +; if (idptr):idval & is_ctag +; prword_10(ctag_value:[(idptr):idval & mask_ctag]) +; else +; prword_10((idptr):idval + compbuff) +; fin +; else +; prword_10((idptr):idval) +; fin +; crout() +; idptr = idptr + (idptr).idname + idrecsz +; idcnt = idcnt - 1 +; loop +;end +def id_lookup_21(nameptr, len) + word idptr + + idptr = idmatch_41(nameptr, len, idlocal_tbl, locals) + if idptr + return idptr + fin + idptr = idmatch_41(nameptr, len, idglobal_tbl, globals) + if idptr + return idptr + fin + return parse_err_11(@undecl_id) +end +def idglobal_lookup_21(nameptr, len) + return idmatch_41(nameptr, len, idglobal_tbl, globals) +end +def idlocal_add_41(namestr, len, type, size) + if idmatch_41(namestr, len, @idlocal_tbl, locals) + return parse_err_11(@dup_id) + fin + (lastlocal):idval = framesize + (lastlocal).idtype = type ? LOCAL_TYPE + nametostr_30(namestr, len, lastlocal + idname) + locals = locals + 1 + lastlocal = lastlocal + idrecsz + len + if lastlocal > idlocal_tbl + idlocal_tblsz + prstr(@local_sym_overflw) + exit + fin + framesize = framesize + size + if framesize > 255 + prstr(@local_overflw) + return FALSE + fin + return TRUE +end +def iddata_add_41(namestr, len, type, size) + if idmatch_41(namestr, len, idglobal_tbl, globals) + return parse_err_11(@dup_id) + fin + (lastglobal):idval = datasize + (lastglobal).idtype = type + nametostr_30(namestr, len, lastglobal + idname) + emit_iddata_30(datasize, size, lastglobal + idname) + globals = globals + 1 + lastglobal = lastglobal + idrecsz + len + if lastglobal > idglobal_tbl + idglobal_tblsz + prstr(@global_sym_overflw) + exit + fin + datasize = datasize + size + return TRUE +end +def iddata_size_30(type, varsize, initsize) + if varsize > initsize + datasize = datasize + emit_data_41(0, 0, 0, varsize - initsize) + else + datasize = datasize + initsize + fin +; if datasize <> codeptr - compbuff +; prstr(@emiterr) +; keyin_01() +; fin +end +def idglobal_add_41(namestr, len, type, value) + if idmatch_41(namestr, len, idglobal_tbl, globals) + return parse_err_11(@dup_id) + fin + (lastglobal):idval = value + (lastglobal).idtype = type + nametostr_30(namestr, len, lastglobal + idname) + globals = globals + 1 + lastglobal = lastglobal + idrecsz + len + if lastglobal > idglobal_tbl + idglobal_tblsz + prstr(@global_sym_overflw) + exit + fin + return TRUE +end +def idfunc_add_31(namestr, len, tag) + return idglobal_add_41(namestr, len, FUNC_TYPE, tag) +end +def idconst_add_31(namestr, len, value) + return idglobal_add_41(namestr, len, CONST_TYPE, value) +end +def idglobal_init + word ctag + + lineno = 0 + codeptr = compbuff + lastop = $FF + entrypoint = 0 + datasize = 0 + globals = 0 + lastglobal = idglobal_tbl + codetag = -1 + ctag = ctag_new_01() + drop idfunc_add_31(@runtime0 + 1, runtime0, ctag) + drop idfunc_add_31(@RUNTIME0 + 1, RUNTIME0, ctag) + drop ctag_resolve_21(ctag, @romcall) + ctag = ctag_new_01() + drop idfunc_add_31(@runtime1 + 1, runtime1, ctag) + drop idfunc_add_31(@RUNTIME1 + 1, RUNTIME1, ctag) + drop ctag_resolve_21(ctag, @syscall) + ctag = ctag_new_01() + drop idfunc_add_31(@runtime2 + 1, runtime2, ctag) + drop idfunc_add_31(@RUNTIME2 + 1, RUNTIME2, ctag) + drop ctag_resolve_21(ctag, @memset) + ctag = ctag_new_01() + drop idfunc_add_31(@runtime3 + 1, runtime3, ctag) + drop idfunc_add_31(@RUNTIME3 + 1, RUNTIME3, ctag) + drop ctag_resolve_21(ctag, @memcpy) + ctag = ctag_new_01() + drop idfunc_add_31(@runtime4 + 1, runtime4, ctag) + drop idfunc_add_31(@RUNTIME4 + 1, RUNTIME4, ctag) + drop ctag_resolve_21(ctag, @cout) + ctag = ctag_new_01() + drop idfunc_add_31(@runtime5 + 1, runtime5, ctag) + drop idfunc_add_31(@RUNTIME5 + 1, RUNTIME5, ctag) + drop ctag_resolve_21(ctag, @cin) + ctag = ctag_new_01() + drop idfunc_add_31(@runtime6 + 1, runtime6, ctag) + drop idfunc_add_31(@RUNTIME6 + 1, RUNTIME6, ctag) + drop ctag_resolve_21(ctag, @prstr) + ctag = ctag_new_01() + drop idfunc_add_31(@runtime7 + 1, runtime7, ctag) + drop idfunc_add_31(@RUNTIME7 + 1, RUNTIME7, ctag) + drop ctag_resolve_21(ctag, @rdstr) +end +def idlocal_init + locals = 0 + framesize = 2 + lastlocal = idlocal_tbl +end +; +; Parser +; +def parse_term_01 + when scan_01() + is ID_TKN + return TRUE + is INT_TKN + return TRUE + is CHR_TKN + return TRUE + is STR_TKN + return TRUE + is OPEN_PAREN_TKN + if !parse_expr_01() + return FALSE + fin + if token <> CLOSE_PAREN_TKN + return parse_err_11(@no_close_paren) + fin + return TRUE + wend + return FALSE +end +def parse_constval_21(valptr, sizeptr) + byte mod, type + word idptr + + mod = 0 + type = 0 + *valptr = 0 + while !parse_term_01() + when token + is SUB_TKN + mod = mod ? 1 + is COMP_TKN + mod = mod ? 2 + is LOGIC_NOT_TKN + mod = mod ? 4 + is AT_TKN + mod = mod ? 8 + otherwise + return 0 + wend + loop + when token + is STR_TKN + *valptr = constval + ^sizeptr = tknlen - 1 + type = STR_TYPE + if mod + return parse_err_11(@bad_op) + fin + is CHR_TKN + *valptr = constval + ^sizeptr = 1 + type = BYTE_TYPE + is INT_TKN + *valptr = constval + ^sizeptr = 2 + type = WORD_TYPE + is ID_TKN + ^sizeptr = 2 + idptr = id_lookup_21(tknptr, tknlen) + if !idptr + return parse_err_11(@bad_cnst) + fin + type = (idptr).idtype + *valptr = (idptr):idval + if type & VAR_TYPE and !(mod & 8) + return parse_err_11(@bad_cnst) + fin + otherwise + return parse_err_11(@bad_cnst) + wend + if mod & 1 + *valptr = -*valptr + fin + if mod & 2 + *valptr = #*valptr + fin + if mod & 4 + *valptr = !*valptr + fin + return type +end +def ispostop_01 + when token + is OPEN_PAREN_TKN + return TRUE + is OPEN_BRACKET_TKN + return TRUE + is DOT_TKN + return TRUE + is COLON_TKN + return TRUE + wend + return FALSE +end +def parse_value_11(rvalue) + byte cparams, deref, type, emit_val + word optos, idptr, value + byte elem_type, elem_size + word elem_offset + + deref = rvalue + optos = opsp + type = 0 + emit_val = 0 + value = 0 + + ; + ; Parse pre-ops + ; + while !parse_term_01() + when token + is ADD_TKN + is BPTR_TKN + if deref + drop push_op_21(token, 0) + else + type = type ? BPTR_TYPE + deref = deref + 1 + fin + is WPTR_TKN + if deref + drop push_op_21(token, 0) + else + type = type ? WPTR_TYPE + deref = deref + 1 + fin + is AT_TKN + deref = deref - 1 + is SUB_TKN + drop push_op_21(token, 0) + is COMP_TKN + drop push_op_21(token, 0) + is LOGIC_NOT_TKN + drop push_op_21(token, 0) + otherwise + return 0 + wend + loop + ; + ; Determine terminal type + ; + when token + is INT_TKN + type = type ? CONST_TYPE + value = constval + is CHR_TKN + type = type ? CONST_TYPE + value = constval + is ID_TKN + idptr = id_lookup_21(tknptr, tknlen) + if !idptr + return 0 + fin + if !(idptr).idtype + return 0 + fin + type = type ? (idptr).idtype + value = (idptr):idval + is CLOSE_PAREN_TKN + type = type ? WORD_TYPE + emit_val = 1 + otherwise + return 0 + wend + ; + ; Constant optimizations + ; + if type & CONST_TYPE + cparams = TRUE + while optos < opsp and cparams + when tos_op_01() + is NEG_TKN + drop pop_op_01() + value = -value + is COMP_TKN + drop pop_op_01() + value = #value + is LOGIC_NOT_TKN + drop pop_op_01() + value = !value + otherwise + cparams = FALSE + wend + loop + fin + ; + ; Parse post-ops + ; + drop scan_01() + while ispostop_01() + if token == OPEN_BRACKET_TKN + ; + ; Array + ; + if !emit_val + if type & ADDR_TYPE + if type & LOCAL_TYPE + emit_localaddr_10(value) + else + emit_globaladdr_10(value) + fin + elsif type & CONST_TYPE + emit_const_10(value) + fin + emit_val = 1 + fin ; !emit_val + if type & PTR_TYPE + emit_lw() + fin + if !parse_expr_01() + return 0 + fin + if token <> CLOSE_BRACKET_TKN + return parse_err_11(@no_close_bracket) + fin + if type & WORD_TYPE + type = WPTR_TYPE + emit_indexword() + else + type = BPTR_TYPE + emit_indexbyte() + fin + drop scan_01() + elsif token == DOT_TKN or token == COLON_TKN + ; + ; Dot and Colon + ; + if token == DOT_TKN + elem_type = BPTR_TYPE + else + elem_type = WPTR_TYPE + fin + if parse_constval_21(@elem_offset, @elem_size) + ; + ; Constant structure offset + ; + if !emit_val + if type & VAR_TYPE + if type & LOCAL_TYPE + emit_localaddr_10(value + elem_offset) + else + ; emit_globaladdr_10(value + elem_offset) + emit_globaladdr_10(value) + emit_const_10(elem_offset) + drop emit_binaryop_11(ADD_TKN) + fin + elsif type & CONST_TYPE + value = value + elem_offset + emit_const_10(value) + else ; FUNC_TYPE + emit_globaladdr_10(value) + emit_const_10(elem_offset) + drop emit_binaryop_11(ADD_TKN) + fin + emit_val = 1 + else + if elem_offset <> 0 + emit_const_10(elem_offset) + drop emit_binaryop_11(ADD_TKN) + fin + fin ; !emit_val + drop scan_01() + elsif token == OPEN_BRACKET_TKN + ; + ; Array of arrays + ; + if !emit_val + if type & ADDR_TYPE + if type & LOCAL_TYPE + emit_localaddr_10(value) + else + emit_globaladdr_10(value) + fin + elsif type & CONST_TYPE + emit_const_10(value) + fin + emit_val = 1 + fin ; !emit_val + repeat + if emit_val > 1 + emit_indexword() + emit_lw() + fin + emit_val = emit_val + 1 + if !parse_expr_01() + return parse_err_11(@bad_expr) + fin + if token <> CLOSE_BRACKET_TKN + return parse_err_11(@no_close_bracket) + fin + until scan_01() <> OPEN_BRACKET_TKN + if elem_type & WPTR_TYPE + emit_indexword() + else + emit_indexbyte() + fin + else + return parse_err_11(@bad_offset) + fin + type = elem_type + elsif token == OPEN_PAREN_TKN + ; + ; Function call + ; + if !emit_val and type & VAR_TYPE + if type & LOCAL_TYPE + emit_localaddr_10(value) + else + emit_globaladdr_10(value) + fin + fin + if !(type & FUNC_CONST_TYPE) + emit_push() + fin + drop parse_expr_01() + if token <> CLOSE_PAREN_TKN + return parse_err_11(@no_close_paren) + fin + if type & FUNC_CONST_TYPE + emit_call_10(value) + else + emit_pull() + emit_ical() + fin + emit_val = 1 + type = WORD_TYPE + drop scan_01() + fin + loop + if emit_val + if rvalue + if deref and type & PTR_TYPE + if type & BPTR_TYPE + emit_lb() + else + emit_lw() + fin + fin + fin + else ; emit_val + if type & CONST_TYPE + emit_const_10(value) + elsif deref + if type & FUNC_TYPE + emit_call_10(value) + elsif type & VAR_TYPE + if type & LOCAL_TYPE + if type & BYTE_TYPE + emit_llb_10(value) + else + emit_llw_10(value) + fin + else + if type & BYTE_TYPE + emit_lab_10(value) + else + emit_law_10(value) + fin + fin + elsif type & PTR_TYPE + if type & BPTR_TYPE + emit_lb() + else + emit_lw() + fin + fin + else + if type & LOCAL_TYPE + emit_localaddr_10(value) + else + emit_globaladdr_10(value) + fin + fin + fin ; emit_val + while optos < opsp + if !emit_unaryop_11(pop_op_01()) + return parse_err_11(@bad_op) + fin + loop + return type +end +def parse_constexpr_21(valptr, sizeptr) + byte type, size1, size2 + word val1, val2 + + type = parse_constval_21(@val1, @size1) + if !type + return 0 + fin + size2 = 0 + when scan_01() + is ADD_TKN + type = parse_constval_21(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 + val2 + is SUB_TKN + type = parse_constval_21(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 - val2 + is MUL_TKN + type = parse_constval_21(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 * val2 + is DIV_TKN + type = parse_constval_21(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 + val2 + is MOD_TKN + type = parse_constval_21(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 % val2 + drop + is AND_TKN + type = parse_constval_21(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 & val2 + is OR_TKN + type = parse_constval_21(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 ? val2 + is EOR_TKN + type = parse_constval_21(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 ^ val2 + otherwise + *valptr = val1 + wend + if size1 > size2 + ^sizeptr = size1 + else + ^sizeptr = size2 + fin + return type +end +def parse_expr_01 + byte prevmatch, matchop, i + word optos + + matchop = 0 + optos = opsp + repeat + prevmatch = matchop + matchop = 0 + if parse_value_11(1) + matchop = 1 + for i = 0 to bops_tblsz + if token == bops_tbl[i] + matchop = 2 + if bops_prec[i] >= tos_op_prec_11(optos) + if !emit_binaryop_11(pop_op_01()) + return parse_err_11(@bad_op) + fin + fin + drop push_op_21(token, bops_prec[i]) + break + fin + next + fin + until matchop <> 2 + if matchop == 0 and prevmatch == 2 + return parse_err_11(@missing_op) + fin + while optos < opsp + if !emit_binaryop_11(pop_op_01()) + return parse_err_11(@bad_op) + fin + loop + return matchop or prevmatch +end +def parse_setlist_21(addr, type) + word nexttype, nextaddr, idptr, saveptr + + if !(type & VAR_TYPE) + emit_push() + fin + nexttype = 0 + nextaddr = 0 + if scan_01() == ID_TKN + idptr = id_lookup_21(tknptr, tknlen) + if !idptr + return FALSE + fin + nexttype = (idptr).idtype + if type & VAR_TYPE + nextaddr = (idptr):idval + fin + fin + saveptr = tknptr + drop scan_01() + if nexttype & VAR_TYPE and token == SET_TKN + drop parse_expr_01() + if type & LOCAL_TYPE + if type & BYTE_TYPE + emit_slb_10(nextaddr) + else + emit_slw_10(nextaddr) + fin + else + if type & BYTE_TYPE + emit_sab_10(nextaddr) + else + emit_saw_10(nextaddr) + fin + fin + elsif nexttype & VAR_TYPE and token == SETLIST_TKN + if !parse_setlist_21(nextaddr, nexttype) + return FALSE + fin + else + tknptr = saveptr + rewind_10(tknptr) + nexttype = parse_value_11(0) + if nexttype <> 0 + if token == SET_TKN + emit_push() + drop parse_expr_01() + emit_pull() + emit_swap() + if nexttype & (BYTE_TYPE ? BPTR_TYPE) + emit_sb() + else + emit_sw() + fin + fin + elsif token == SETLIST_TKN + if !parse_setlist_21(0, nexttype) + return FALSE + fin + else + return parse_err_11(@bad_syntax) + fin + fin + if type & VAR_TYPE + if type & LOCAL_TYPE + if type & BYTE_TYPE + emit_slb_10(addr) + else + emit_slw_10(addr) + fin + else + if type & BYTE_TYPE + emit_sab_10(addr) + else + emit_saw_10(addr) + fin + fin + else + emit_pull() + emit_swap() + if type & (BYTE_TYPE ? BPTR_TYPE) + emit_sb() + else + emit_sw() + fin + fin + return TRUE +end +def parse_stmnt_01 + byte type, i + word tag_prevbrk, tag_else, tag_endif, tag_while, tag_wend + word tag_repeat, tag_for, tag_choice, idptr, saveptr, addr, stepdir + + if token <> END_TKN and token <> DONE_TKN + prevstmnt = token + fin + when token + is IF_TKN + drop parse_expr_01() + tag_else = ctag_new_01() + tag_endif = ctag_new_01() + emit_brfls_10(tag_else) + drop scan_01() + repeat + while parse_stmnt_01() + drop nextln_01() + loop + if token <> ELSEIF_TKN + break + fin + emit_jump_10(tag_endif) + emit_codetag_10(tag_else) + if !parse_expr_01() + return 0 + fin + tag_else = ctag_new_01() + emit_brfls_10(tag_else) + until FALSE + if token == ELSE_TKN + emit_jump_10(tag_endif) + emit_codetag_10(tag_else) + drop scan_01() + while parse_stmnt_01() + drop nextln_01() + loop + emit_codetag_10(tag_endif) + else + emit_codetag_10(tag_else) + emit_codetag_10(tag_endif) + fin + if token <> FIN_TKN + return parse_err_11(@no_fin) + fin + is FOR_TKN + stack_loop = stack_loop + 1 + tag_for = ctag_new_01() + tag_prevbrk = break_tag + break_tag = ctag_new_01() + if scan_01() <> ID_TKN + return parse_err_11(@bad_stmnt) + fin + idptr = id_lookup_21(tknptr, tknlen) + if idptr + type = (idptr).idtype + addr = (idptr):idval + else + return FALSE + fin + if scan_01() <> SET_TKN + return parse_err_11(@bad_stmnt) + fin + if !parse_expr_01() + return parse_err_11(@bad_stmnt) + fin + emit_codetag_10(tag_for) + if type & LOCAL_TYPE + if type & BYTE_TYPE + emit_dlb_10(addr) + else + emit_dlw_10(addr) + fin + else + if type & BYTE_TYPE + emit_dab_10(addr) + else + emit_daw_10(addr) + fin + fin + stepdir = 1 + if token == TO_TKN + drop parse_expr_01() + elsif token == DOWNTO_TKN + drop parse_expr_01() + stepdir = -1 + fin + if stepdir > 0 + emit_brgt_10(break_tag) + else + emit_brlt_10(break_tag) + fin + if token == STEP_TKN + drop parse_expr_01() + if stepdir > 0 + drop emit_binaryop_11(ADD_TKN) + else + drop emit_binaryop_11(SUB_TKN) + fin + else + if stepdir > 0 + drop emit_unaryop_11(INC_TKN) + else + drop emit_unaryop_11(DEC_TKN) + fin + fin + while parse_stmnt_01() + drop nextln_01() + loop + if token <> NEXT_TKN + return parse_err_11(@bad_stmnt) + fin + emit_jump_10(tag_for) + emit_codetag_10(break_tag) + emit_drop() + break_tag = tag_prevbrk + stack_loop = stack_loop - 1 + is WHILE_TKN + tag_while = ctag_new_01() + tag_wend = ctag_new_01() + tag_prevbrk = break_tag + break_tag = tag_wend + emit_codetag_10(tag_while) + drop parse_expr_01() + emit_brfls_10(tag_wend) + while parse_stmnt_01() + drop nextln_01() + loop + if token <> LOOP_TKN + return parse_err_11(@no_loop) + fin + emit_jump_10(tag_while) + emit_codetag_10(tag_wend) + break_tag = tag_prevbrk + is REPEAT_TKN + tag_repeat = ctag_new_01() + tag_prevbrk = break_tag + break_tag = ctag_new_01() + emit_codetag_10(tag_repeat) + drop scan_01() + while parse_stmnt_01() + drop nextln_01() + loop + if token <> UNTIL_TKN + return parse_err_11(@no_until) + fin + drop parse_expr_01() + emit_brfls_10(tag_repeat) + emit_codetag_10(break_tag) + break_tag = tag_prevbrk + is CASE_TKN + stack_loop = stack_loop + 1 + tag_choice = ctag_new_01() + tag_prevbrk = break_tag + break_tag = ctag_new_01() + drop parse_expr_01() + drop nextln_01() + while token <> ENDCASE_TKN + when token + is OF_TKN + if !parse_expr_01() + return parse_err_11(@bad_stmnt) + fin + emit_brne_10(tag_choice) + while parse_stmnt_01() + drop nextln_01() + loop + emit_jump_10(break_tag) + emit_codetag_10(tag_choice) + tag_choice = ctag_new_01() + is DEFAULT_TKN + drop scan_01() + while parse_stmnt_01() + drop nextln_01() + loop + if token <> ENDCASE_TKN + return parse_err_11(@bad_stmnt) + fin + otherwise + return parse_err_11(@bad_stmnt) + wend + loop + emit_codetag_10(break_tag) + emit_drop() + break_tag = tag_prevbrk + stack_loop = stack_loop - 1 + is BREAK_TKN + if break_tag + emit_jump_10(break_tag) + else + return parse_err_11(@bad_stmnt) + fin + is RETURN_TKN + if infunc + for i = 1 to stack_loop + emit_drop() + next + drop parse_expr_01() + emit_leave_10(framesize) + else + return parse_err_11(@bad_stmnt) + fin + is DROP_TKN + drop parse_expr_01() + emit_drop() + is ELSE_TKN + return FALSE + is ELSEIF_TKN + return FALSE + is FIN_TKN + return FALSE + is LOOP_TKN + return FALSE + is UNTIL_TKN + return FALSE + is NEXT_TKN + return FALSE + is OF_TKN + return FALSE + is DEFAULT_TKN + return FALSE + is ENDCASE_TKN + return FALSE + is END_TKN + return FALSE + is DONE_TKN + return FALSE + is FUNC_TKN + return FALSE + is EOF_TKN + return FALSE + is EOL_TKN + return TRUE + otherwise + if token == ID_TKN + saveptr = tknptr + idptr = id_lookup_21(tknptr, tknlen) + if !idptr + return FALSE + fin + type = (idptr).idtype + if type & ADDR_TYPE + addr = (idptr):idval + if scan_01() == SET_TKN + if type & VAR_TYPE + drop parse_expr_01() + if type & LOCAL_TYPE + if type & BYTE_TYPE + emit_slb_10(addr) + else + emit_slw_10(addr) + fin + else + if type & BYTE_TYPE + emit_sab_10(addr) + else + emit_saw_10(addr) + fin + fin + return TRUE + fin + elsif token == SETLIST_TKN and type & VAR_TYPE + return parse_setlist_21(addr, type); + elsif token == EOL_TKN and type & FUNC_TYPE + emit_call_10(addr) + return TRUE + fin + fin + tknptr = saveptr + fin + rewind_10(tknptr) + type = parse_value_11(0) + if type + if token == SET_TKN + drop parse_expr_01() + if type & XBYTE_TYPE + emit_sb() + else + emit_sw() + fin + elsif token == SETLIST_TKN + return parse_setlist_21(0, type); + else + if type & BPTR_TYPE + emit_lb() + elsif type & WPTR_TYPE + emit_lw() + fin + fin + else + return parse_err_11(@bad_syntax) + fin + wend + if scan_01() <> EOL_TKN + return parse_err_11(@bad_syntax) + fin + return TRUE +end +def parse_var_11(type) + byte consttype, constsize, idlen + word idptr, constval, arraysize, size + + idlen = 0 + size = 1 + if scan_01() == ID_TKN + idptr = tknptr + idlen = tknlen + if scan_01() == OPEN_BRACKET_TKN + size = 0 + drop parse_constexpr_21(@size, @constsize) + if token <> CLOSE_BRACKET_TKN + return parse_err_11(@no_close_bracket) + fin + drop scan_01() + fin + fin + if type == WORD_TYPE + size = size * 2 + fin + if token == SET_TKN + if infunc + return parse_err_11(@no_local_init) + fin + if idlen + drop iddata_add_41(idptr, idlen, type, 0) + fin + consttype = parse_constexpr_21(@constval, @constsize) + if consttype + arraysize = emit_data_41(type, consttype, constval, constsize) + while token == COMMA_TKN + consttype = parse_constexpr_21(@constval, @constsize) + if consttype + arraysize = arraysize + emit_data_41(type, consttype, constval, constsize) + else + return parse_err_11(@bad_decl) + fin + loop + if token <> EOL_TKN + return parse_err_11(@no_close_bracket) + fin + iddata_size_30(PTR_TYPE, size, arraysize); + else + return parse_err_11(@bad_decl) + fin + elsif idlen + if infunc + drop idlocal_add_41(idptr, idlen, type, size) + else + drop iddata_add_41(idptr, idlen, type, size) + fin + fin + return TRUE +end +def parse_vars_01 + byte idlen, type, size + word value, idptr + + when token + is CONST_TKN + if scan_01() <> ID_TKN + return parse_err_11(@bad_cnst) + fin + idptr = tknptr; + idlen = tknlen + if scan_01() <> SET_TKN + return parse_err_11(@bad_cnst) + fin + if !parse_constexpr_21(@value, @size) + return parse_err_11(@bad_cnst) + fin + drop idconst_add_31(idptr, idlen, value) + is BYTE_TKN + type = BYTE_TYPE + repeat + if !parse_var_11(type) + return FALSE + fin + until token <> COMMA_TKN + is WORD_TKN + type = WORD_TYPE + repeat + if !parse_var_11(type) + return FALSE + fin + until token <> COMMA_TKN + is FUNC_TKN + repeat + if scan_01() == ID_TKN + drop idfunc_add_31(tknptr, tknlen, ctag_new_01()) + else + return parse_err_11(@bad_decl) + fin + until scan_01() <> COMMA_TKN + is EOL_TKN + return TRUE + otherwise + return FALSE + wend + return TRUE +end +def parse_func_01 + byte opt, cfnparms + word func_tag, idptr + + if token == FUNC_TKN + opt = token - FUNC_TKN + if scan_01() <> ID_TKN + return parse_err_11(@bad_decl) + fin + cfnparms = 0 + infunc = TRUE + idptr = idglobal_lookup_21(tknptr, tknlen) + if idptr + func_tag = (idptr):idval + else + func_tag = ctag_new_01() + drop idfunc_add_31(tknptr, tknlen, func_tag) + fin + emit_codetag_10(func_tag) + retfunc_tag = ctag_new_01() + idlocal_init() + if scan_01() == OPEN_PAREN_TKN + repeat + if scan_01() == ID_TKN + cfnparms = cfnparms + 1 + drop idlocal_add_41(tknptr, tknlen, WORD_TYPE, 2) + drop scan_01() + fin + until token <> COMMA_TKN + if token <> CLOSE_PAREN_TKN + return parse_err_11(@bad_decl) + fin + drop scan_01() + fin + while parse_vars_01() + drop nextln_01() + loop + emit_enter_20(framesize, cfnparms) + prevstmnt = 0 + while parse_stmnt_01() + drop nextln_01() + loop + infunc = FALSE + if token <> END_TKN + return parse_err_11(@bad_syntax) + fin + if scan_01() <> EOL_TKN + return parse_err_11(@bad_syntax) + fin + if prevstmnt <> RETURN_TKN + emit_leave_10(framesize) + fin + return TRUE + elsif token == EOL_TKN + return TRUE + fin + return FALSE +end +def parse_module_01 + entrypoint = 0 + idglobal_init() + idlocal_init() + if nextln_01() + while parse_vars_01() + drop nextln_01() + loop + while parse_func_01() + drop nextln_01() + loop + if token <> DONE_TKN + emit_start() + prevstmnt = 0 + while parse_stmnt_01() + drop nextln_01() + loop + if token <> DONE_TKN + drop parse_err_11(@no_done) + fin + fin + ; dumpsym(idglobal_tbl, globals) + ; prstr(@entrypt_str) + ; prword(entrypoint) + ; crout() + ; keyin_01() + return TRUE + fin + return FALSE +end +; +; Compile PLASMA file to REL file +; +prstr(@version) +crout() +if ^argbuff + filename = argbuff +else + filename = rdstr($BA) +fin +ioref = open_21(filename, iobuffer) +if ioref + drop newline_31(ioref, $7F, $0D) + if parse_module_01() + drop close_11(ioref) + ; + ; Save REF file + ; + + else + drop close_11(ioref) + crout() + prstr(@badfile) + cin() + fin +; crout +; dumpsym(@idglobal_tbl, globals) +; crout +fin +done diff --git a/plasma2/plas.s b/plasma2/plas.s new file mode 100755 index 0000000..bd46f8d --- /dev/null +++ b/plasma2/plas.s @@ -0,0 +1,9992 @@ + .INCLUDE "plstub.s" +; 1: ; +; 2: ; Global constants +; 3: ; +; 4: const FALSE = 0 + ; FALSE = 0 +; 5: const TRUE = !FALSE + ; TRUE = -1 +; 6: ; +; 7: ; Data and code buffer variables +; 8: ; +; 9: const iobuffer = $0800 + ; iobuffer = 2048 +; 10: const compbuff = $6000 + ; compbuff = 24576 +; 11: const compbuffsz = $4000 + ; compbuffsz = 16384 +; 12: const func_dict = $5000 + ; func_dict = 20480 +; 13: const fixup_tbl = $4000 + ; fixup_tbl = 16384 +; 14: const argbuff = $2006 + ; argbuff = 8198 +; 15: const inbuff = $0200 + ; inbuff = 512 +; 16: const instr = $01FF + ; instr = 511 +; 17: byte inref +D0000: DS 1 ; inref +; 18: ; +; 19: ; REL file tables +; 20: ; +; 21: word datalen, codelen +D0001: DS 2 ; datalen +D0003: DS 2 ; codelen +; 22: word fixup = fixup_tbl +D0005: ; fixup + DW $4000 +; 23: word numfuncs = 1 +D0007: ; numfuncs + DW $0001 +; 24: ; +; 25: ; Symbol table variables +; 26: ; +; 27: const idglobal_tblsz = $0800 + ; idglobal_tblsz = 2048 +; 28: const idlocal_tblsz = $0200 + ; idlocal_tblsz = 512 +; 29: const idglobal_tbl = $1000 + ; idglobal_tbl = 4096 +; 30: const idlocal_tbl = $1800 + ; idlocal_tbl = 6144 +; 31: const ctag_max = 768 + ; ctag_max = 768 +; 32: const ctag_value = $1A00 + ; ctag_value = 6656 +; 33: const ctag_flags = $0D00 + ; ctag_flags = 3328 +; 34: const idval = 0 + ; idval = 0 +; 35: const idtype = 2 + ; idtype = 2 +; 36: const idname = 3 + ; idname = 3 +; 37: const idrecsz = 4 + ; idrecsz = 4 +; 38: word globals = 0 +D0009: ; globals + DW $0000 +; 39: word datasize = 0 +D0011: ; datasize + DW $0000 +; 40: word lastglobal +D0013: DS 2 ; lastglobal +; 41: byte locals = 0 +D0015: ; locals + DB $00 +; 42: word framesize = 0 +D0016: ; framesize + DW $0000 +; 43: word lastlocal +D0018: DS 2 ; lastlocal +; 44: const resolved = 1 + ; resolved = 1 +; 45: const is_ctag = $8000 + ; is_ctag = 32768 +; 46: const mask_ctag = $7FFF + ; mask_ctag = 32767 +; 47: word codetag = -1 +D0020: ; codetag + DW $FFFF +; 48: ; +; 49: ; Symbol types +; 50: ; +; 51: const EXTERN_SYM = $10 + ; EXTERN_SYM = 16 +; 52: const EXPORT_SYM = $08 + ; EXPORT_SYM = 8 +; 53: ; +; 54: ; Compiler pointers +; 55: ; +; 56: word codeptr +D0022: DS 2 ; codeptr +; 57: word entrypoint = 0 +D0024: ; entrypoint + DW $0000 +; 58: byte lastop = $FF +D0026: ; lastop + DB $FF +; 59: byte perr +D0027: DS 1 ; perr +; 60: ; +; 61: ; String variables +; 62: ; +; 63: byte version[] = "PLASMA ][ COMPILER VERSION 0.8 " +D0028: ; version + DB $1F + DB $50,$4C,$41,$53,$4D,$41,$20,$5D + DB $5B,$20,$43,$4F,$4D,$50,$49,$4C + DB $45,$52,$20,$56,$45,$52,$53,$49 + DB $4F,$4E,$20,$30,$2E,$38,$20 +; 64: byte badfile[] = "FILE NOT FOUND" +D0060: ; badfile + DB $0E + DB $46,$49,$4C,$45,$20,$4E,$4F,$54 + DB $20,$46,$4F,$55,$4E,$44 +; 65: ; +; 66: ; Tokens +; 67: ; +; 68: const ID_TKN = $D6 ; V + ; ID_TKN = 214 +; 69: const CHR_TKN = $C3 ; C + ; CHR_TKN = 195 +; 70: const INT_TKN = $C9 ; I + ; INT_TKN = 201 +; 71: const STR_TKN = $D3 ; S + ; STR_TKN = 211 +; 72: const EOL_TKN = $02 + ; EOL_TKN = 2 +; 73: const EOF_TKN = $01 + ; EOF_TKN = 1 +; 74: const ERR_TKN = $00 + ; ERR_TKN = 0 +; 75: ; +; 76: ; Binary operand operators +; 77: ; +; 78: const SET_TKN = $BD ; = + ; SET_TKN = 189 +; 79: const SETLIST_TKN = $B9 ; =, + ; SETLIST_TKN = 185 +; 80: const ADD_TKN = $AB ; + + ; ADD_TKN = 171 +; 81: const SUB_TKN = $AD ; - + ; SUB_TKN = 173 +; 82: const MUL_TKN = $AA ; * + ; MUL_TKN = 170 +; 83: const DIV_TKN = $AF ; / + ; DIV_TKN = 175 +; 84: const MOD_TKN = $A5 ; % + ; MOD_TKN = 165 +; 85: const OR_TKN = $BF ; ? + ; OR_TKN = 191 +; 86: const EOR_TKN = $DE ; ^ + ; EOR_TKN = 222 +; 87: const AND_TKN = $A6 ; & + ; AND_TKN = 166 +; 88: const SHR_TKN = $D2 ; R + ; SHR_TKN = 210 +; 89: const SHL_TKN = $CC ; L + ; SHL_TKN = 204 +; 90: const GT_TKN = $BE ; > + ; GT_TKN = 190 +; 91: const GE_TKN = $C8 ; H + ; GE_TKN = 200 +; 92: const LT_TKN = $BC ; < + ; LT_TKN = 188 +; 93: const LE_TKN = $C2 ; B + ; LE_TKN = 194 +; 94: const NE_TKN = $D5 ; U + ; NE_TKN = 213 +; 95: const EQ_TKN = $C5 ; E + ; EQ_TKN = 197 +; 96: const LOGIC_AND_TKN = $CE ; N + ; LOGIC_AND_TKN = 206 +; 97: const LOGIC_OR_TKN = $CF ; O + ; LOGIC_OR_TKN = 207 +; 98: ; +; 99: ; Unary operand operators +; 100: ; +; 101: const AT_TKN = $C0 ; @ + ; AT_TKN = 192 +; 102: const DOT_TKN = $AE ; . + ; DOT_TKN = 174 +; 103: const COLON_TKN = $BA ; : + ; COLON_TKN = 186 +; 104: const NEG_TKN = $AD ; - + ; NEG_TKN = 173 +; 105: const COMP_TKN = $A3 ; # + ; COMP_TKN = 163 +; 106: const LOGIC_NOT_TKN = $A1 ; ! + ; LOGIC_NOT_TKN = 161 +; 107: const BPTR_TKN = $DE ; ^ + ; BPTR_TKN = 222 +; 108: const WPTR_TKN = $AA ; * + ; WPTR_TKN = 170 +; 109: const INC_TKN = $C1 ; A + ; INC_TKN = 193 +; 110: const DEC_TKN = $C4 ; D + ; DEC_TKN = 196 +; 111: ; +; 112: ; Enclosure tokens +; 113: ; +; 114: const OPEN_PAREN_TKN = $A8 ; ( + ; OPEN_PAREN_TKN = 168 +; 115: const CLOSE_PAREN_TKN = $A9 ; ) + ; CLOSE_PAREN_TKN = 169 +; 116: const OPEN_BRACKET_TKN = $DB ; [ + ; OPEN_BRACKET_TKN = 219 +; 117: const CLOSE_BRACKET_TKN = $DD ; ] + ; CLOSE_BRACKET_TKN = 221 +; 118: ; +; 119: ; Misc. tokens +; 120: ; +; 121: const COMMA_TKN = $AC ; , + ; COMMA_TKN = 172 +; 122: const COMMENT_TKN = $BB ; ; + ; COMMENT_TKN = 187 +; 123: ; +; 124: ; Keyword tokens +; 125: ; +; 126: const CONST_TKN = $80 + ; CONST_TKN = 128 +; 127: const BYTE_TKN = $81 + ; BYTE_TKN = 129 +; 128: const WORD_TKN = $82 + ; WORD_TKN = 130 +; 129: const IF_TKN = $83 + ; IF_TKN = 131 +; 130: const ELSEIF_TKN = $84 + ; ELSEIF_TKN = 132 +; 131: const ELSE_TKN = $85 + ; ELSE_TKN = 133 +; 132: const FIN_TKN = $86 + ; FIN_TKN = 134 +; 133: const END_TKN = $87 + ; END_TKN = 135 +; 134: const WHILE_TKN = $88 + ; WHILE_TKN = 136 +; 135: const LOOP_TKN = $89 + ; LOOP_TKN = 137 +; 136: const CASE_TKN = $8A + ; CASE_TKN = 138 +; 137: const OF_TKN = $8B + ; OF_TKN = 139 +; 138: const DEFAULT_TKN = $8C + ; DEFAULT_TKN = 140 +; 139: const ENDCASE_TKN = $8D + ; ENDCASE_TKN = 141 +; 140: const FOR_TKN = $8E + ; FOR_TKN = 142 +; 141: const TO_TKN = $8F + ; TO_TKN = 143 +; 142: const DOWNTO_TKN = $90 + ; DOWNTO_TKN = 144 +; 143: const STEP_TKN = $91 + ; STEP_TKN = 145 +; 144: const NEXT_TKN = $92 + ; NEXT_TKN = 146 +; 145: const REPEAT_TKN = $93 + ; REPEAT_TKN = 147 +; 146: const UNTIL_TKN = $94 + ; UNTIL_TKN = 148 +; 147: const DEF_TKN = $95 + ; DEF_TKN = 149 +; 148: const OPT_TKN = $96 + ; OPT_TKN = 150 +; 149: const DROP_TKN = $97 + ; DROP_TKN = 151 +; 150: const DONE_TKN = $98 + ; DONE_TKN = 152 +; 151: const RETURN_TKN = $99 + ; RETURN_TKN = 153 +; 152: const BREAK_TKN = $9A + ; BREAK_TKN = 154 +; 153: const START_TKN = $9B + ; START_TKN = 155 +; 154: const EXIT_TKN = $9C + ; EXIT_TKN = 156 +; 155: const EVAL_TKN = $9D + ; EVAL_TKN = 157 +; 156: const FUNC_TKN = $9E + ; FUNC_TKN = 158 +; 157: const EXTERN_TKN = $9F + ; EXTERN_TKN = 159 +; 158: const ENTRY_TKN = $A0 + ; ENTRY_TKN = 160 +; 159: const IMPORT_TKN = $A1 + ; IMPORT_TKN = 161 +; 160: const INCLUDE_TKN = $A2 + ; INCLUDE_TKN = 162 +; 161: ; +; 162: ; Types +; 163: ; +; 164: const CONST_TYPE = $01 + ; CONST_TYPE = 1 +; 165: const BYTE_TYPE = $02 + ; BYTE_TYPE = 2 +; 166: const WORD_TYPE = $04 + ; WORD_TYPE = 4 +; 167: const VAR_TYPE = $06 ; (WORD_TYPE | BYTE_TYPE) + ; VAR_TYPE = 6 +; 168: const FUNC_TYPE = $08 + ; FUNC_TYPE = 8 +; 169: const FUNC_CONST_TYPE = $09 + ; FUNC_CONST_TYPE = 9 +; 170: const ADDR_TYPE = $0E ; (VAR_TYPE | FUNC_TYPE) + ; ADDR_TYPE = 14 +; 171: const LOCAL_TYPE = $10 + ; LOCAL_TYPE = 16 +; 172: const BPTR_TYPE = $20 + ; BPTR_TYPE = 32 +; 173: const WPTR_TYPE = $40 + ; WPTR_TYPE = 64 +; 174: const PTR_TYPE = $60 ; (BPTR_TYPE | WPTR_TYPE) + ; PTR_TYPE = 96 +; 175: const XBYTE_TYPE = $22 ; (BPTR_TYPE | BYTE_TYPE) + ; XBYTE_TYPE = 34 +; 176: const XWORD_TYPE = $44 ; (WPTR_TYPE | WORD_TYPE) + ; XWORD_TYPE = 68 +; 177: const STR_TYPE = $80 + ; STR_TYPE = 128 +; 178: ; +; 179: ; Keywords +; 180: ; +; 181: byte keywrds[] +D0075: ; keywrds +; 182: byte = "IF", IF_TKN + DB $02 + DB $49,$46 + DB $83 +; 183: byte = "TO", TO_TKN + DB $02 + DB $54,$4F + DB $8F +; 184: byte = "IS", OF_TKN + DB $02 + DB $49,$53 + DB $8B +; 185: byte = "OR", LOGIC_OR_TKN + DB $02 + DB $4F,$52 + DB $CF +; 186: byte = "FOR", FOR_TKN + DB $03 + DB $46,$4F,$52 + DB $8E +; 187: byte = "FIN", FIN_TKN + DB $03 + DB $46,$49,$4E + DB $86 +; 188: byte = "DEF", DEF_TKN + DB $03 + DB $44,$45,$46 + DB $95 +; 189: byte = "END", END_TKN + DB $03 + DB $45,$4E,$44 + DB $87 +; 190: byte = "AND", LOGIC_AND_TKN + DB $03 + DB $41,$4E,$44 + DB $CE +; 191: byte = "NOT", LOGIC_NOT_TKN + DB $03 + DB $4E,$4F,$54 + DB $A1 +; 192: byte = "BYTE", BYTE_TKN + DB $04 + DB $42,$59,$54,$45 + DB $81 +; 193: byte = "WORD", WORD_TKN + DB $04 + DB $57,$4F,$52,$44 + DB $82 +; 194: byte = "DROP", DROP_TKN + DB $04 + DB $44,$52,$4F,$50 + DB $97 +; 195: byte = "ELSE", ELSE_TKN + DB $04 + DB $45,$4C,$53,$45 + DB $85 +; 196: byte = "NEXT", NEXT_TKN + DB $04 + DB $4E,$45,$58,$54 + DB $92 +; 197: byte = "WHEN", CASE_TKN + DB $04 + DB $57,$48,$45,$4E + DB $8A +; 198: byte = "LOOP", LOOP_TKN + DB $04 + DB $4C,$4F,$4F,$50 + DB $89 +; 199: byte = "FUNC", FUNC_TKN + DB $04 + DB $46,$55,$4E,$43 + DB $9E +; 200: byte = "STEP", STEP_TKN + DB $04 + DB $53,$54,$45,$50 + DB $91 +; 201: byte = "EXIT", EXIT_TKN + DB $04 + DB $45,$58,$49,$54 + DB $9C +; 202: byte = "DONE", DONE_TKN + DB $04 + DB $44,$4F,$4E,$45 + DB $98 +; 203: byte = "WEND", ENDCASE_TKN + DB $04 + DB $57,$45,$4E,$44 + DB $8D +; 204: byte = "ENTRY", ENTRY_TKN + DB $05 + DB $45,$4E,$54,$52,$59 + DB $A0 +; 205: byte = "CONST", CONST_TKN + DB $05 + DB $43,$4F,$4E,$53,$54 + DB $80 +; 206: byte = "ELSIF", ELSEIF_TKN + DB $05 + DB $45,$4C,$53,$49,$46 + DB $84 +; 207: byte = "WHILE", WHILE_TKN + DB $05 + DB $57,$48,$49,$4C,$45 + DB $88 +; 208: byte = "UNTIL", UNTIL_TKN + DB $05 + DB $55,$4E,$54,$49,$4C + DB $94 +; 209: byte = "BREAK", BREAK_TKN + DB $05 + DB $42,$52,$45,$41,$4B + DB $9A +; 210: byte = "OTHER", DEFAULT_TKN + DB $05 + DB $4F,$54,$48,$45,$52 + DB $8C +; 211: byte = "DOWNTO", DOWNTO_TKN + DB $06 + DB $44,$4F,$57,$4E,$54,$4F + DB $90 +; 212: byte = "REPEAT", REPEAT_TKN + DB $06 + DB $52,$45,$50,$45,$41,$54 + DB $93 +; 213: byte = "RETURN", RETURN_TKN + DB $06 + DB $52,$45,$54,$55,$52,$4E + DB $99 +; 214: byte = "EXTERN", EXTERN_TKN + DB $06 + DB $45,$58,$54,$45,$52,$4E + DB $9F +; 215: byte = "IMPORT", IMPORT_TKN + DB $06 + DB $49,$4D,$50,$4F,$52,$54 + DB $A1 +; 216: byte = "INCLUDE", INCLUDE_TKN + DB $07 + DB $49,$4E,$43,$4C,$55,$44,$45 + DB $A2 +; 217: byte = $FF + DB $FF +; 218: ; +; 219: ; Mathematical ops +; 220: ; +; 221: const bops_tblsz = 18 ; minus 1 + ; bops_tblsz = 18 +; 222: byte bops_tbl[] ; Highest precedence +D0292: ; bops_tbl +; 223: byte = MUL_TKN, DIV_TKN, MOD_TKN + DB $AA + DB $AF + DB $A5 +; 224: byte = ADD_TKN, SUB_TKN + DB $AB + DB $AD +; 225: byte = SHR_TKN, SHL_TKN + DB $D2 + DB $CC +; 226: byte = AND_TKN + DB $A6 +; 227: byte = EOR_TKN + DB $DE +; 228: byte = OR_TKN + DB $BF +; 229: byte = GT_TKN, GE_TKN, LT_TKN, LE_TKN + DB $BE + DB $C8 + DB $BC + DB $C2 +; 230: byte = EQ_TKN, NE_TKN + DB $C5 + DB $D5 +; 231: byte = LOGIC_AND_TKN + DB $CE +; 232: byte = LOGIC_OR_TKN + DB $CF +; 233: byte = COMMA_TKN + DB $AC +; 234: ; Lowest precedence +; 235: byte bops_prec[] ; Highest precedence +D0311: ; bops_prec +; 236: byte = 1, 1, 1 + DB $01 + DB $01 + DB $01 +; 237: byte = 2, 2 + DB $02 + DB $02 +; 238: byte = 3, 3 + DB $03 + DB $03 +; 239: byte = 4 + DB $04 +; 240: byte = 5 + DB $05 +; 241: byte = 6 + DB $06 +; 242: byte = 7, 7, 7, 7 + DB $07 + DB $07 + DB $07 + DB $07 +; 243: byte = 8, 8 + DB $08 + DB $08 +; 244: byte = 9 + DB $09 +; 245: byte = 10 + DB $0A +; 246: byte = 11 + DB $0B +; 247: ; Lowest precedence +; 248: byte opstack[16] +D0330: DS 16 ; opstack +; 249: byte precstack[16] +D0346: DS 16 ; precstack +; 250: word opsp = -1 +D0362: ; opsp + DW $FFFF +; 251: ; +; 252: ; Scanner variables +; 253: ; +; 254: byte token, tknlen +D0364: DS 1 ; token +D0365: DS 1 ; tknlen +; 255: word scanptr, tknptr +D0366: DS 2 ; scanptr +D0368: DS 2 ; tknptr +; 256: word constval +D0370: DS 2 ; constval +; 257: word lineno = 0 +D0372: ; lineno + DW $0000 +; 258: ; +; 259: ; Compiler output messages +; 260: ; +; 261: byte entrypt_str[] = "START: " +D0374: ; entrypt_str + DB $07 + DB $53,$54,$41,$52,$54,$3A,$20 +; 262: byte dup_id[] = "DUPLICATE IDENTIFIER" +D0382: ; dup_id + DB $14 + DB $44,$55,$50,$4C,$49,$43,$41,$54 + DB $45,$20,$49,$44,$45,$4E,$54,$49 + DB $46,$49,$45,$52 +; 263: byte undecl_id[] = "UNDECLARED IDENTIFIER" +D0403: ; undecl_id + DB $15 + DB $55,$4E,$44,$45,$43,$4C,$41,$52 + DB $45,$44,$20,$49,$44,$45,$4E,$54 + DB $49,$46,$49,$45,$52 +; 264: byte bad_cnst[] = "BAD CONSTANT" +D0425: ; bad_cnst + DB $0C + DB $42,$41,$44,$20,$43,$4F,$4E,$53 + DB $54,$41,$4E,$54 +; 265: byte bad_offset[] = "BAD STRUCT OFFSET" +D0438: ; bad_offset + DB $11 + DB $42,$41,$44,$20,$53,$54,$52,$55 + DB $43,$54,$20,$4F,$46,$46,$53,$45 + DB $54 +; 266: byte bad_decl[] = "BAD DECLARATION" +D0456: ; bad_decl + DB $0F + DB $42,$41,$44,$20,$44,$45,$43,$4C + DB $41,$52,$41,$54,$49,$4F,$4E +; 267: byte bad_op[] = "BAD OPERATION" +D0472: ; bad_op + DB $0D + DB $42,$41,$44,$20,$4F,$50,$45,$52 + DB $41,$54,$49,$4F,$4E +; 268: byte bad_stmnt[] = "BAD STATMENT" +D0486: ; bad_stmnt + DB $0C + DB $42,$41,$44,$20,$53,$54,$41,$54 + DB $4D,$45,$4E,$54 +; 269: byte bad_expr[] = "BAD EXPRESSION" +D0499: ; bad_expr + DB $0E + DB $42,$41,$44,$20,$45,$58,$50,$52 + DB $45,$53,$53,$49,$4F,$4E +; 270: byte bad_syntax[] = "BAD SYNTAX" +D0514: ; bad_syntax + DB $0A + DB $42,$41,$44,$20,$53,$59,$4E,$54 + DB $41,$58 +; 271: byte estk_overflw[] = "EVAL STACK OVERFLOW" +D0525: ; estk_overflw + DB $13 + DB $45,$56,$41,$4C,$20,$53,$54,$41 + DB $43,$4B,$20,$4F,$56,$45,$52,$46 + DB $4C,$4F,$57 +; 272: byte estk_underflw[] = "EVAL STACK UNDERFLOW" +D0545: ; estk_underflw + DB $14 + DB $45,$56,$41,$4C,$20,$53,$54,$41 + DB $43,$4B,$20,$55,$4E,$44,$45,$52 + DB $46,$4C,$4F,$57 +; 273: byte local_overflw[] = "LOCAL FRAME OVERFLOW" +D0566: ; local_overflw + DB $14 + DB $4C,$4F,$43,$41,$4C,$20,$46,$52 + DB $41,$4D,$45,$20,$4F,$56,$45,$52 + DB $46,$4C,$4F,$57 +; 274: byte global_sym_overflw[] = "GLOBAL SYMBOL TABLE OVERFLOW" +D0587: ; global_sym_overflw + DB $1C + DB $47,$4C,$4F,$42,$41,$4C,$20,$53 + DB $59,$4D,$42,$4F,$4C,$20,$54,$41 + DB $42,$4C,$45,$20,$4F,$56,$45,$52 + DB $46,$4C,$4F,$57 +; 275: byte local_sym_overflw[] = "LOCAL SYMBOL TABLE OVERFLOW" +D0616: ; local_sym_overflw + DB $1B + DB $4C,$4F,$43,$41,$4C,$20,$53,$59 + DB $4D,$42,$4F,$4C,$20,$54,$41,$42 + DB $4C,$45,$20,$4F,$56,$45,$52,$46 + DB $4C,$4F,$57 +; 276: byte ctag_full[] = "CODE LABEL OVERFLOW" +D0644: ; ctag_full + DB $13 + DB $43,$4F,$44,$45,$20,$4C,$41,$42 + DB $45,$4C,$20,$4F,$56,$45,$52,$46 + DB $4C,$4F,$57 +; 277: byte no_close_paren[] = "MISSING CLOSING PAREN" +D0664: ; no_close_paren + DB $15 + DB $4D,$49,$53,$53,$49,$4E,$47,$20 + DB $43,$4C,$4F,$53,$49,$4E,$47,$20 + DB $50,$41,$52,$45,$4E +; 278: byte no_close_bracket[] = "MISSING CLOSING BRACKET" +D0686: ; no_close_bracket + DB $17 + DB $4D,$49,$53,$53,$49,$4E,$47,$20 + DB $43,$4C,$4F,$53,$49,$4E,$47,$20 + DB $42,$52,$41,$43,$4B,$45,$54 +; 279: byte missing_op[] = "MISSING OPERAND" +D0710: ; missing_op + DB $0F + DB $4D,$49,$53,$53,$49,$4E,$47,$20 + DB $4F,$50,$45,$52,$41,$4E,$44 +; 280: byte no_fin[] = "MISSING FIN" +D0726: ; no_fin + DB $0B + DB $4D,$49,$53,$53,$49,$4E,$47,$20 + DB $46,$49,$4E +; 281: byte no_loop[] = "MISSING LOOP" +D0738: ; no_loop + DB $0C + DB $4D,$49,$53,$53,$49,$4E,$47,$20 + DB $4C,$4F,$4F,$50 +; 282: byte no_until[] = "MISSING UNTIL" +D0751: ; no_until + DB $0D + DB $4D,$49,$53,$53,$49,$4E,$47,$20 + DB $55,$4E,$54,$49,$4C +; 283: byte no_done[] = "MISSING DONE" +D0765: ; no_done + DB $0C + DB $4D,$49,$53,$53,$49,$4E,$47,$20 + DB $44,$4F,$4E,$45 +; 284: byte no_local_init[] = "NO INITIALIZED LOCALS" +D0778: ; no_local_init + DB $15 + DB $4E,$4F,$20,$49,$4E,$49,$54,$49 + DB $41,$4C,$49,$5A,$45,$44,$20,$4C + DB $4F,$43,$41,$4C,$53 +; 285: ; +; 286: ; Runtime functions +; 287: ; +; 288: byte runtime0[] = "romcall" +D0800: ; runtime0 + DB $07 + DB $72,$6F,$6D,$63,$61,$6C,$6C +; 289: byte RUNTIME0[] = "ROMCALL" +D0808: ; RUNTIME0 + DB $07 + DB $52,$4F,$4D,$43,$41,$4C,$4C +; 290: byte runtime1[] = "syscall" +D0816: ; runtime1 + DB $07 + DB $73,$79,$73,$63,$61,$6C,$6C +; 291: byte RUNTIME1[] = "SYSCALL" +D0824: ; RUNTIME1 + DB $07 + DB $53,$59,$53,$43,$41,$4C,$4C +; 292: byte runtime2[] = "memset" +D0832: ; runtime2 + DB $06 + DB $6D,$65,$6D,$73,$65,$74 +; 293: byte RUNTIME2[] = "MEMSET" +D0839: ; RUNTIME2 + DB $06 + DB $4D,$45,$4D,$53,$45,$54 +; 294: byte runtime3[] = "memcpy" +D0846: ; runtime3 + DB $06 + DB $6D,$65,$6D,$63,$70,$79 +; 295: byte RUNTIME3[] = "MEMCPY" +D0853: ; RUNTIME3 + DB $06 + DB $4D,$45,$4D,$43,$50,$59 +; 296: byte runtime4[] = "cout" +D0860: ; runtime4 + DB $04 + DB $63,$6F,$75,$74 +; 297: byte RUNTIME4[] = "COUT" +D0865: ; RUNTIME4 + DB $04 + DB $43,$4F,$55,$54 +; 298: byte runtime5[] = "cin" +D0870: ; runtime5 + DB $03 + DB $63,$69,$6E +; 299: byte RUNTIME5[] = "CIN" +D0874: ; RUNTIME5 + DB $03 + DB $43,$49,$4E +; 300: byte runtime6[] = "prstr" +D0878: ; runtime6 + DB $05 + DB $70,$72,$73,$74,$72 +; 301: byte RUNTIME6[] = "PRSTR" +D0884: ; RUNTIME6 + DB $05 + DB $50,$52,$53,$54,$52 +; 302: byte runtime7[] = "rdstr" +D0890: ; runtime7 + DB $05 + DB $72,$64,$73,$74,$72 +; 303: byte RUNTIME7[] = "RDSTR" +D0896: ; RUNTIME7 + DB $05 + DB $52,$44,$53,$54,$52 +; 304: ; +; 305: ; Parser variables +; 306: ; +; 307: byte infunc = 0 +D0902: ; infunc + DB $00 +; 308: byte stack_loop = 0 +D0903: ; stack_loop + DB $00 +; 309: byte prevstmnt = 0 +D0904: ; prevstmnt + DB $00 +; 310: word retfunc_tag = 0 +D0905: ; retfunc_tag + DW $0000 +; 311: word break_tag = 0 +D0907: ; break_tag + DW $0000 +; 312: func parse_expr_01, parse_module_01 +; 313: ; +; 314: ; Defines for ASM routines +; 315: ; +; 316: asm equates +C0002: ; equates() +; 317: TMP EQU $F0 + TMP EQU $F0 +; 318: TMPL EQU TMP + TMPL EQU TMP +; 319: TMPH EQU TMP+1 + TMPH EQU TMP+1 +; 320: SRC EQU TMP + SRC EQU TMP +; 321: SRCL EQU SRC + SRCL EQU SRC +; 322: SRCH EQU SRC+1 + SRCH EQU SRC+1 +; 323: DST EQU SRC+2 + DST EQU SRC+2 +; 324: DSTL EQU DST + DSTL EQU DST +; 325: DSTH EQU DST+1 + DSTH EQU DST+1 +; 326: ESP EQU DST+2 + ESP EQU DST+2 +; 327: SAVEESP EQU ESP+1 + SAVEESP EQU ESP+1 +; 328: SAVESP EQU SAVEESP+1 + SAVESP EQU SAVEESP+1 +; 329: SAVEFP EQU SAVESP+1 + SAVEFP EQU SAVESP+1 +; 330: SAVETMR EQU SAVEFP+2 + SAVETMR EQU SAVEFP+2 +; 331: SAVEINT EQU SAVETMR+2 + SAVEINT EQU SAVETMR+2 +; 332: TMRVEC EQU $03E8 + TMRVEC EQU $03E8 +; 333: INTVEC EQU $03EA + INTVEC EQU $03EA +; 334: JMPTMP: JMP (TMP) +JMPTMP: JMP (TMP) +; 335: STKOVFLW: +STKOVFLW: +; 336: LDY #$02 + LDY #$02 +; 337: JMP EXECRET + JMP EXECRET +; 338: BRKCHK: +BRKCHK: +; 339: LDA $C000 + LDA $C000 +; 340: CMP #$83 ; CTRL-C + CMP #$83 ; CTRL-C +; 341: BNE :+ + BNE :+ +; 342: BIT $C010 + BIT $C010 +; 343: LDY #$01 + LDY #$01 +; 344: JMP EXECRET + JMP EXECRET +; 345: : +: +; 346: end + RTS +; 347: ; +; 348: ; CALL 6502 ROUTINE +; 349: ; ROMCALL(AREG, XREG, YREG, STATUS, ADDR) +; 350: ; +; 351: asm romcall +C0004: ; romcall() +; 352: PHP + PHP +; 353: LDA ESTKL,X + LDA ESTKL,X +; 354: STA TMPL + STA TMPL +; 355: LDA ESTKH,X + LDA ESTKH,X +; 356: STA TMPH + STA TMPH +; 357: INX + INX +; 358: LDA ESTKL,X + LDA ESTKL,X +; 359: PHA + PHA +; 360: INX + INX +; 361: LDA ESTKL,X + LDA ESTKL,X +; 362: TAY + TAY +; 363: INX + INX +; 364: LDA ESTKL+1,X + LDA ESTKL+1,X +; 365: PHA + PHA +; 366: LDA ESTKL,X + LDA ESTKL,X +; 367: INX + INX +; 368: STX ESP + STX ESP +; 369: TAX + TAX +; 370: PLA + PLA +; 371: BIT ROMIN + BIT ROMIN +; 372: PLP + PLP +; 373: JSR JMPTMP + JSR JMPTMP +; 374: PHP + PHP +; 375: BIT LCBNK2 + BIT LCBNK2 +; 376: STA REGVALS+0 + STA REGVALS+0 +; 377: STX REGVALS+1 + STX REGVALS+1 +; 378: STY REGVALS+2 + STY REGVALS+2 +; 379: PLA + PLA +; 380: STA REGVALS+3 + STA REGVALS+3 +; 381: LDX ESP + LDX ESP +; 382: LDA #REGVALS + LDY #>REGVALS +; 384: STA ESTKL,X + STA ESTKL,X +; 385: STY ESTKH,X + STY ESTKH,X +; 386: PLP + PLP +; 387: RTS + RTS +; 388: REGVALS: DS 4 +REGVALS: DS 4 +; 389: end + RTS +; 390: ; +; 391: ; CALL PRODOS +; 392: ; SYSCALL(CMD, PARAMS) +; 393: ; +; 394: asm syscall +C0006: ; syscall() +; 395: LDA ESTKL,X + LDA ESTKL,X +; 396: LDY ESTKH,X + LDY ESTKH,X +; 397: STA PARAMS + STA PARAMS +; 398: STY PARAMS+1 + STY PARAMS+1 +; 399: INX + INX +; 400: LDA ESTKL,X + LDA ESTKL,X +; 401: STA CMD + STA CMD +; 402: STX ESP + STX ESP +; 403: BIT ROMIN + BIT ROMIN +; 404: JSR $BF00 + JSR $BF00 +; 405: CMD: DB 00 +CMD: DB 00 +; 406: PARAMS: DW 0000 +PARAMS: DW 0000 +; 407: BIT LCBNK2 + BIT LCBNK2 +; 408: LDX ESP + LDX ESP +; 409: STA ESTKL,X + STA ESTKL,X +; 410: LDY #$00 + LDY #$00 +; 411: STY ESTKH,X + STY ESTKH,X +; 412: end + RTS +; 413: ; +; 414: ; SET MEMORY TO VALUE +; 415: ; MEMSET(VALUE, ADDR, SIZE) +; 416: ; +; 417: asm memset +C0008: ; memset() +; 418: LDY #$00 + LDY #$00 +; 419: LDA ESTKL+1,X + LDA ESTKL+1,X +; 420: STA DSTL + STA DSTL +; 421: LDA ESTKH+1,X + LDA ESTKH+1,X +; 422: STA DSTH + STA DSTH +; 423: INC ESTKL,X + INC ESTKL,X +; 424: INC ESTKH,X + INC ESTKH,X +; 425: SETMEM: DEC ESTKL,X +SETMEM: DEC ESTKL,X +; 426: BNE :+ + BNE :+ +; 427: DEC ESTKH,X + DEC ESTKH,X +; 428: BEQ MEMEXIT + BEQ MEMEXIT +; 429: : LDA ESTKL+2,X +: LDA ESTKL+2,X +; 430: STA (DST),Y + STA (DST),Y +; 431: INY + INY +; 432: BNE :+ + BNE :+ +; 433: INC DSTH + INC DSTH +; 434: : DEC ESTKL,X +: DEC ESTKL,X +; 435: BNE :+ + BNE :+ +; 436: DEC ESTKH,X + DEC ESTKH,X +; 437: BEQ MEMEXIT + BEQ MEMEXIT +; 438: : LDA ESTKH+2,X +: LDA ESTKH+2,X +; 439: STA (DST),Y + STA (DST),Y +; 440: INY + INY +; 441: BNE SETMEM + BNE SETMEM +; 442: INC DSTH + INC DSTH +; 443: BNE SETMEM + BNE SETMEM +; 444: MEMEXIT: INX +MEMEXIT: INX +; 445: INX + INX +; 446: INX + INX +; 447: end + RTS +; 448: ; +; 449: ; COPY MEMORY +; 450: ; MEMCPY(SRCADDR, DSTADDR, SIZE) +; 451: ; +; 452: asm memcpy +C0010: ; memcpy() +; 453: LDY #$00 + LDY #$00 +; 454: LDA ESTKL,X + LDA ESTKL,X +; 455: BNE :+ + BNE :+ +; 456: LDA ESTKH,X + LDA ESTKH,X +; 457: BEQ MEMEXIT + BEQ MEMEXIT +; 458: : LDA ESTKL+1,X +: LDA ESTKL+1,X +; 459: STA DSTL + STA DSTL +; 460: LDA ESTKH+1,X + LDA ESTKH+1,X +; 461: STA DSTH + STA DSTH +; 462: LDA ESTKL+2,X + LDA ESTKL+2,X +; 463: STA SRCL + STA SRCL +; 464: LDA ESTKH+2,X + LDA ESTKH+2,X +; 465: STA SRCH + STA SRCH +; 466: CMP DSTH + CMP DSTH +; 467: BCC REVCPY + BCC REVCPY +; 468: BNE FORCPY + BNE FORCPY +; 469: LDA SRCL + LDA SRCL +; 470: CMP DSTL + CMP DSTL +; 471: BCS FORCPY + BCS FORCPY +; 472: REVCPY: ; REVERSE DIRECTION COPY +REVCPY: ; REVERSE DIRECTION COPY +; 473: ; CLC +; 474: LDA ESTKL,X + LDA ESTKL,X +; 475: ADC DSTL + ADC DSTL +; 476: STA DSTL + STA DSTL +; 477: LDA ESTKH,X + LDA ESTKH,X +; 478: ADC DSTH + ADC DSTH +; 479: STA DSTH + STA DSTH +; 480: CLC + CLC +; 481: LDA ESTKL,X + LDA ESTKL,X +; 482: ADC SRCL + ADC SRCL +; 483: STA SRCL + STA SRCL +; 484: LDA ESTKH,X + LDA ESTKH,X +; 485: ADC SRCH + ADC SRCH +; 486: STA SRCH + STA SRCH +; 487: INC ESTKH,X + INC ESTKH,X +; 488: REVCPYLP: +REVCPYLP: +; 489: LDA DSTL + LDA DSTL +; 490: BNE :+ + BNE :+ +; 491: DEC DSTH + DEC DSTH +; 492: : DEC DSTL +: DEC DSTL +; 493: LDA SRCL + LDA SRCL +; 494: BNE :+ + BNE :+ +; 495: DEC SRCH + DEC SRCH +; 496: : DEC SRCL +: DEC SRCL +; 497: LDA (SRC),Y + LDA (SRC),Y +; 498: STA (DST),Y + STA (DST),Y +; 499: DEC ESTKL,X + DEC ESTKL,X +; 500: BNE REVCPYLP + BNE REVCPYLP +; 501: DEC ESTKH,X + DEC ESTKH,X +; 502: BNE REVCPYLP + BNE REVCPYLP +; 503: BEQ MEMEXIT + BEQ MEMEXIT +; 504: FORCPY: INC ESTKH,X +FORCPY: INC ESTKH,X +; 505: FORCPYLP: +FORCPYLP: +; 506: LDA (SRC),Y + LDA (SRC),Y +; 507: STA (DST),Y + STA (DST),Y +; 508: INC DSTL + INC DSTL +; 509: BNE :+ + BNE :+ +; 510: INC DSTH + INC DSTH +; 511: : INC SRCL +: INC SRCL +; 512: BNE :+ + BNE :+ +; 513: INC SRCH + INC SRCH +; 514: : DEC ESTKL,X +: DEC ESTKL,X +; 515: BNE FORCPYLP + BNE FORCPYLP +; 516: DEC ESTKH,X + DEC ESTKH,X +; 517: BNE FORCPYLP + BNE FORCPYLP +; 518: BEQ MEMEXIT + BEQ MEMEXIT +; 519: end + RTS +; 520: ; +; 521: ; CHAR OUT +; 522: ; COUT(CHAR) +; 523: ; +; 524: asm cout +C0012: ; cout() +; 525: LDA ESTKL,X + LDA ESTKL,X +; 526: INX + INX +; 527: ORA #$80 + ORA #$80 +; 528: BIT ROMIN + BIT ROMIN +; 529: JSR $FDED + JSR $FDED +; 530: BIT LCBNK2 + BIT LCBNK2 +; 531: end + RTS +; 532: ; +; 533: ; CHAR IN +; 534: ; RDKEY() +; 535: ; +; 536: asm cin +C0014: ; cin() +; 537: BIT ROMIN + BIT ROMIN +; 538: STX ESP + STX ESP +; 539: JSR $FD0C + JSR $FD0C +; 540: LDX ESP + LDX ESP +; 541: BIT LCBNK2 + BIT LCBNK2 +; 542: DEX + DEX +; 543: AND #$7F + AND #$7F +; 544: STA ESTKL,X + STA ESTKL,X +; 545: LDY #$00 + LDY #$00 +; 546: STY ESTKH,X + STY ESTKH,X +; 547: end + RTS +; 548: ; +; 549: ; PRINT STRING +; 550: ; PRSTR(STR) +; 551: ; +; 552: asm prstr +C0016: ; prstr() +; 553: LDY #$00 + LDY #$00 +; 554: LDA ESTKL,X + LDA ESTKL,X +; 555: STA SRCL + STA SRCL +; 556: LDA ESTKH,X + LDA ESTKH,X +; 557: STA SRCH + STA SRCH +; 558: BIT ROMIN + BIT ROMIN +; 559: LDA (SRC),Y + LDA (SRC),Y +; 560: STA ESTKL,X + STA ESTKL,X +; 561: BEQ :+ + BEQ :+ +; 562: _PRS1: INY +_PRS1: INY +; 563: LDA (SRC),Y + LDA (SRC),Y +; 564: ORA #$80 + ORA #$80 +; 565: JSR $FDED + JSR $FDED +; 566: TYA + TYA +; 567: CMP ESTKL,X + CMP ESTKL,X +; 568: BNE _PRS1 + BNE _PRS1 +; 569: : INX +: INX +; 570: BIT LCBNK2 + BIT LCBNK2 +; 571: end + RTS +; 572: ; +; 573: ; READ STRING +; 574: ; STR = RDSTR(PROMPTCHAR) +; 575: ; +; 576: asm rdstr +C0018: ; rdstr() +; 577: LDA ESTKL,X + LDA ESTKL,X +; 578: STA $33 + STA $33 +; 579: STX ESP + STX ESP +; 580: BIT ROMIN + BIT ROMIN +; 581: JSR $FD6A + JSR $FD6A +; 582: BIT LCBNK2 + BIT LCBNK2 +; 583: STX $01FF + STX $01FF +; 584: : LDA $01FF,X +: LDA $01FF,X +; 585: AND #$7F + AND #$7F +; 586: STA $01FF,X + STA $01FF,X +; 587: DEX + DEX +; 588: BPL :- + BPL :- +; 589: LDX ESP + LDX ESP +; 590: LDA #$FF + LDA #$FF +; 591: STA ESTKL,X + STA ESTKL,X +; 592: LDA #$01 + LDA #$01 +; 593: STA ESTKH,X + STA ESTKH,X +; 594: end + RTS +; 595: ;def toupper_11(c) +; 596: ; if c >= 'a' +; 597: ; if c <= 'z' +; 598: ; return c - $20 +; 599: ; fin +; 600: ; fin +; 601: ; return c +; 602: ;end +; 603: asm toupper_11 +C0020: ; toupper_11() +; 604: LDA ESTKL,X + LDA ESTKL,X +; 605: CMP #'a' + CMP #'a' +; 606: BCC :+ + BCC :+ +; 607: CMP #'z'+1 + CMP #'z'+1 +; 608: BCS :+ + BCS :+ +; 609: SEC + SEC +; 610: SBC #$20 + SBC #$20 +; 611: STA ESTKL,X + STA ESTKL,X +; 612: : +: +; 613: end + RTS +; 614: ; +; 615: ; EXIT +; 616: ; +; 617: asm exit +C0022: ; exit() +; 618: JSR $BF00 + JSR $BF00 +; 619: DB $65 + DB $65 +; 620: DW EXITTBL + DW EXITTBL +; 621: EXITTBL: +EXITTBL: +; 622: DB 4 + DB 4 +; 623: DB 0 + DB 0 +; 624: end + RTS +; 625: ; +; 626: ; ProDOS routines +; 627: ; +; 628: def getpfx_11(path) +C0024: ; getpfx_11() + ; path = 2 +; 629: byte params[3] + ; params = 4 +; 630: +; 631: ^path = 0 + JSR _INTERP + DB $58,$07,$01 ; ENTER 7,1 + DB $66,$02 ; LLW 2 + DB $00 ; ZERO + DB $70 ; SB +; 632: params.0 = 1 + DB $28,$04 ; LLA 4 + DB $2A,$01 ; CB 1 + DB $70 ; SB +; 633: params:1 = path + DB $28,$05 ; LLA 5 + DB $66,$02 ; LLW 2 + DB $72 ; SW +; 634: perr = syscall($C7, @params) + DB $2A,$C7 ; CB 199 + DB $28,$04 ; LLA 4 + DB $54,C0006 ; CALL C0006 + DB $78,D0027 ; SAB D0027 +; 635: return path + DB $66,$02 ; LLW 2 + DB $5A ; LEAVE +; 636: end +; 637: def setpfx_11(path) +C0026: ; setpfx_11() + ; path = 2 +; 638: byte params[3] + ; params = 4 +; 639: +; 640: params.0 = 1 + JSR _INTERP + DB $58,$07,$01 ; ENTER 7,1 + DB $28,$04 ; LLA 4 + DB $2A,$01 ; CB 1 + DB $70 ; SB +; 641: params:1 = path + DB $28,$05 ; LLA 5 + DB $66,$02 ; LLW 2 + DB $72 ; SW +; 642: perr = syscall($C6, @params) + DB $2A,$C6 ; CB 198 + DB $28,$04 ; LLA 4 + DB $54,C0006 ; CALL C0006 + DB $78,D0027 ; SAB D0027 +; 643: return path + DB $66,$02 ; LLW 2 + DB $5A ; LEAVE +; 644: end +; 645: def open_21(path, buff) +C0028: ; open_21() + ; path = 2 + ; buff = 4 +; 646: byte params[6] + ; params = 6 +; 647: +; 648: params.0 = 3 + JSR _INTERP + DB $58,$0C,$02 ; ENTER 12,2 + DB $28,$06 ; LLA 6 + DB $2A,$03 ; CB 3 + DB $70 ; SB +; 649: params:1 = path + DB $28,$07 ; LLA 7 + DB $66,$02 ; LLW 2 + DB $72 ; SW +; 650: params:3 = buff + DB $28,$09 ; LLA 9 + DB $66,$04 ; LLW 4 + DB $72 ; SW +; 651: params.5 = 0 + DB $28,$0B ; LLA 11 + DB $00 ; ZERO + DB $70 ; SB +; 652: perr = syscall($C8, @params) + DB $2A,$C8 ; CB 200 + DB $28,$06 ; LLA 6 + DB $54,C0006 ; CALL C0006 + DB $78,D0027 ; SAB D0027 +; 653: return params.5 + DB $28,$0B ; LLA 11 + DB $60 ; LB + DB $5A ; LEAVE +; 654: end +; 655: def close_11(refnum) +C0030: ; close_11() + ; refnum = 2 +; 656: byte params[2] + ; params = 4 +; 657: +; 658: params.0 = 1 + JSR _INTERP + DB $58,$06,$01 ; ENTER 6,1 + DB $28,$04 ; LLA 4 + DB $2A,$01 ; CB 1 + DB $70 ; SB +; 659: params.1 = refnum + DB $28,$05 ; LLA 5 + DB $66,$02 ; LLW 2 + DB $70 ; SB +; 660: perr = syscall($CC, @params) + DB $2A,$CC ; CB 204 + DB $28,$04 ; LLA 4 + DB $54,C0006 ; CALL C0006 + DB $78,D0027 ; SAB D0027 +; 661: return perr + DB $68,D0027 ; LAB D0027 + DB $5A ; LEAVE +; 662: end +; 663: def read_31(refnum, buff, len) +C0032: ; read_31() + ; refnum = 2 + ; buff = 4 + ; len = 6 +; 664: byte params[8] + ; params = 8 +; 665: +; 666: params.0 = 4 + JSR _INTERP + DB $58,$10,$03 ; ENTER 16,3 + DB $28,$08 ; LLA 8 + DB $2A,$04 ; CB 4 + DB $70 ; SB +; 667: params.1 = refnum + DB $28,$09 ; LLA 9 + DB $66,$02 ; LLW 2 + DB $70 ; SB +; 668: params:2 = buff + DB $28,$0A ; LLA 10 + DB $66,$04 ; LLW 4 + DB $72 ; SW +; 669: params:4 = len + DB $28,$0C ; LLA 12 + DB $66,$06 ; LLW 6 + DB $72 ; SW +; 670: params:6 = 0 + DB $28,$0E ; LLA 14 + DB $00 ; ZERO + DB $72 ; SW +; 671: perr = syscall($CA, @params) + DB $2A,$CA ; CB 202 + DB $28,$08 ; LLA 8 + DB $54,C0006 ; CALL C0006 + DB $78,D0027 ; SAB D0027 +; 672: return params:6 + DB $28,$0E ; LLA 14 + DB $62 ; LW + DB $5A ; LEAVE +; 673: end +; 674: def write_31(refnum, buff, len) +C0034: ; write_31() + ; refnum = 2 + ; buff = 4 + ; len = 6 +; 675: byte params[8] + ; params = 8 +; 676: +; 677: params.0 = 4 + JSR _INTERP + DB $58,$10,$03 ; ENTER 16,3 + DB $28,$08 ; LLA 8 + DB $2A,$04 ; CB 4 + DB $70 ; SB +; 678: params.1 = refnum + DB $28,$09 ; LLA 9 + DB $66,$02 ; LLW 2 + DB $70 ; SB +; 679: params:2 = buff + DB $28,$0A ; LLA 10 + DB $66,$04 ; LLW 4 + DB $72 ; SW +; 680: params:4 = len + DB $28,$0C ; LLA 12 + DB $66,$06 ; LLW 6 + DB $72 ; SW +; 681: params:6 = 0 + DB $28,$0E ; LLA 14 + DB $00 ; ZERO + DB $72 ; SW +; 682: perr = syscall($CB, @params) + DB $2A,$CB ; CB 203 + DB $28,$08 ; LLA 8 + DB $54,C0006 ; CALL C0006 + DB $78,D0027 ; SAB D0027 +; 683: return params:6 + DB $28,$0E ; LLA 14 + DB $62 ; LW + DB $5A ; LEAVE +; 684: end +; 685: def create_41(path, access, type, aux) +C0036: ; create_41() + ; path = 2 + ; access = 4 + ; type = 6 + ; aux = 8 +; 686: byte params[12] + ; params = 10 +; 687: +; 688: params.0 = 7 + JSR _INTERP + DB $58,$16,$04 ; ENTER 22,4 + DB $28,$0A ; LLA 10 + DB $2A,$07 ; CB 7 + DB $70 ; SB +; 689: params:1 = path + DB $28,$0B ; LLA 11 + DB $66,$02 ; LLW 2 + DB $72 ; SW +; 690: params.3 = access + DB $28,$0D ; LLA 13 + DB $66,$04 ; LLW 4 + DB $70 ; SB +; 691: params.4 = type + DB $28,$0E ; LLA 14 + DB $66,$06 ; LLW 6 + DB $70 ; SB +; 692: params:5 = aux + DB $28,$0F ; LLA 15 + DB $66,$08 ; LLW 8 + DB $72 ; SW +; 693: params.7 = $1 + DB $28,$11 ; LLA 17 + DB $2A,$01 ; CB 1 + DB $70 ; SB +; 694: params:8 = 0 + DB $28,$12 ; LLA 18 + DB $00 ; ZERO + DB $72 ; SW +; 695: params:10 = 0 + DB $28,$14 ; LLA 20 + DB $00 ; ZERO + DB $72 ; SW +; 696: perr = syscall($C0, @params) + DB $2A,$C0 ; CB 192 + DB $28,$0A ; LLA 10 + DB $54,C0006 ; CALL C0006 + DB $78,D0027 ; SAB D0027 +; 697: return perr + DB $68,D0027 ; LAB D0027 + DB $5A ; LEAVE +; 698: end +; 699: def destroy_11(path) +C0038: ; destroy_11() + ; path = 2 +; 700: byte params[12] + ; params = 4 +; 701: +; 702: params.0 = 1 + JSR _INTERP + DB $58,$10,$01 ; ENTER 16,1 + DB $28,$04 ; LLA 4 + DB $2A,$01 ; CB 1 + DB $70 ; SB +; 703: params:1 = path + DB $28,$05 ; LLA 5 + DB $66,$02 ; LLW 2 + DB $72 ; SW +; 704: perr = syscall($C1, @params) + DB $2A,$C1 ; CB 193 + DB $28,$04 ; LLA 4 + DB $54,C0006 ; CALL C0006 + DB $78,D0027 ; SAB D0027 +; 705: return perr + DB $68,D0027 ; LAB D0027 + DB $5A ; LEAVE +; 706: end +; 707: def newline_31(refnum, emask, nlchar) +C0040: ; newline_31() + ; refnum = 2 + ; emask = 4 + ; nlchar = 6 +; 708: byte params[4] + ; params = 8 +; 709: +; 710: params.0 = 3 + JSR _INTERP + DB $58,$0C,$03 ; ENTER 12,3 + DB $28,$08 ; LLA 8 + DB $2A,$03 ; CB 3 + DB $70 ; SB +; 711: params.1 = refnum + DB $28,$09 ; LLA 9 + DB $66,$02 ; LLW 2 + DB $70 ; SB +; 712: params.2 = emask + DB $28,$0A ; LLA 10 + DB $66,$04 ; LLW 4 + DB $70 ; SB +; 713: params.3 = nlchar + DB $28,$0B ; LLA 11 + DB $66,$06 ; LLW 6 + DB $70 ; SB +; 714: perr = syscall($C9, @params) + DB $2A,$C9 ; CB 201 + DB $28,$08 ; LLA 8 + DB $54,C0006 ; CALL C0006 + DB $78,D0027 ; SAB D0027 +; 715: return perr + DB $68,D0027 ; LAB D0027 + DB $5A ; LEAVE +; 716: end +; 717: def crout +C0042: ; crout() +; 718: cout($0D) + JSR _INTERP + DB $2A,$0D ; CB 13 + DB $54,C0012 ; CALL C0012 +; 719: end + DB $5C ; RET +; 720: def prbyte_10(h) +C0044: ; prbyte_10() + ; h = 2 +; 721: cout('$') + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$24 ; CB 36 + DB $54,C0012 ; CALL C0012 +; 722: drop romcall(h, 0, 0, 0, $FDDA) + DB $66,$02 ; LLW 2 + DB $00 ; ZERO + DB $00 ; ZERO + DB $00 ; ZERO + DB $2C,$DA,$FD ; CW 64986 + DB $54,C0004 ; CALL C0004 + DB $30 ; DROP +; 723: end + DB $5A ; LEAVE +; 724: def prword_10(h) +C0046: ; prword_10() + ; h = 2 +; 725: cout('$') + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$24 ; CB 36 + DB $54,C0012 ; CALL C0012 +; 726: drop romcall(h >> 8, h, 0, 0, $F941) + DB $66,$02 ; LLW 2 + DB $2A,$08 ; CB 8 + DB $1C ; SHR + DB $66,$02 ; LLW 2 + DB $00 ; ZERO + DB $00 ; ZERO + DB $2C,$41,$F9 ; CW 63809 + DB $54,C0004 ; CALL C0004 + DB $30 ; DROP +; 727: end + DB $5A ; LEAVE +; 728: def print_10(i) +C0048: ; print_10() + ; i = 2 +; 729: byte numstr[7] + ; numstr = 4 +; 730: byte place, sign + ; place = 11 + ; sign = 12 +; 731: +; 732: place = 6 + JSR _INTERP + DB $58,$0D,$01 ; ENTER 13,1 + DB $2A,$06 ; CB 6 + DB $74,$0B ; SLB 11 +; 733: if i < 0 + DB $66,$02 ; LLW 2 + DB $00 ; ZERO + DB $46 ; ISLT + DB $4C,C0050 ; SKPFLS C0050 +; 734: sign = 1 + DB $2A,$01 ; CB 1 + DB $74,$0C ; SLB 12 +; 735: i = -i + DB $66,$02 ; LLW 2 + DB $10 ; NEG + DB $76,$02 ; SLW 2 +; 736: else + DB $50,C0051 ; SKIP C0051 +C0050: +; 737: sign = 0 + DB $00 ; ZERO + DB $74,$0C ; SLB 12 +; 738: fin +C0051: +; 739: while i >= 10 +C0052: + DB $66,$02 ; LLW 2 + DB $2A,$0A ; CB 10 + DB $48 ; ISGE + DB $4C,C0053 ; SKPFLS C0053 +; 740: i =, numstr[place] = i % 10 + '0' + DB $28,$04 ; LLA 4 + DB $64,$0B ; LLB 11 + DB $02 ; IDXB + DB $34 ; PUSH + DB $66,$02 ; LLW 2 + DB $2A,$0A ; CB 10 + DB $0A ; DIV,MOD + DB $2A,$30 ; CB 48 + DB $02 ; ADD + DB $36 ; PULL + DB $2E ; SWAP + DB $70 ; SB + DB $76,$02 ; SLW 2 +; 741: place = place - 1 + DB $64,$0B ; LLB 11 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $74,$0B ; SLB 11 +; 742: loop + DB $50,C0052 ; SKIP C0052 +C0053: +; 743: numstr[place] = i + '0' + DB $28,$04 ; LLA 4 + DB $64,$0B ; LLB 11 + DB $02 ; IDXB + DB $66,$02 ; LLW 2 + DB $2A,$30 ; CB 48 + DB $02 ; ADD + DB $70 ; SB +; 744: place = place - 1 + DB $64,$0B ; LLB 11 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $74,$0B ; SLB 11 +; 745: if sign + DB $64,$0C ; LLB 12 + DB $4C,C0054 ; SKPFLS C0054 +; 746: numstr[place] = '-' + DB $28,$04 ; LLA 4 + DB $64,$0B ; LLB 11 + DB $02 ; IDXB + DB $2A,$2D ; CB 45 + DB $70 ; SB +; 747: place = place - 1 + DB $64,$0B ; LLB 11 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $74,$0B ; SLB 11 +; 748: fin +C0054: +C0055: +; 749: numstr[place] = 6 - place + DB $28,$04 ; LLA 4 + DB $64,$0B ; LLB 11 + DB $02 ; IDXB + DB $2A,$06 ; CB 6 + DB $64,$0B ; LLB 11 + DB $04 ; SUB + DB $70 ; SB +; 750: prstr(@numstr[place]) + DB $28,$04 ; LLA 4 + DB $64,$0B ; LLB 11 + DB $02 ; IDXB + DB $54,C0016 ; CALL C0016 +; 751: end + DB $5A ; LEAVE +; 752: def nametostr_30(namestr, len, strptr) +C0056: ; nametostr_30() + ; namestr = 2 + ; len = 4 + ; strptr = 6 +; 753: ^strptr = len + JSR _INTERP + DB $58,$08,$03 ; ENTER 8,3 + DB $66,$06 ; LLW 6 + DB $66,$04 ; LLW 4 + DB $70 ; SB +; 754: memcpy(namestr, strptr + 1, len) + DB $66,$02 ; LLW 2 + DB $66,$06 ; LLW 6 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $66,$04 ; LLW 4 + DB $54,C0010 ; CALL C0010 +; 755: end + DB $5A ; LEAVE +; 756: +; 757: ;===================================== +; 758: ; +; 759: ; PLASMA Compiler +; 760: ; +; 761: ;===================================== +; 762: +; 763: ; +; 764: ; Error handler +; 765: ; +; 766: def parse_err_11(err) +C0058: ; parse_err_11() + ; err = 2 +; 767: word i + ; i = 4 +; 768: +; 769: drop close_11(0) + JSR _INTERP + DB $58,$06,$01 ; ENTER 6,1 + DB $00 ; ZERO + DB $54,C0030 ; CALL C0030 + DB $30 ; DROP +; 770: crout() + DB $54,C0042 ; CALL C0042 +; 771: print_10(lineno) + DB $6A,D0372 ; LAW D0372 + DB $54,C0048 ; CALL C0048 +; 772: cout(':') + DB $2A,$3A ; CB 58 + DB $54,C0012 ; CALL C0012 +; 773: prstr(err) + DB $66,$02 ; LLW 2 + DB $54,C0016 ; CALL C0016 +; 774: crout() + DB $54,C0042 ; CALL C0042 +; 775: prstr(instr) + DB $2C,$FF,$01 ; CW 511 + DB $54,C0016 ; CALL C0016 +; 776: crout() + DB $54,C0042 ; CALL C0042 +; 777: for i = inbuff to tknptr - 1 + DB $2C,$00,$02 ; CW 512 +C0061: + DB $6E,$04 ; DLW 4 + DB $6A,D0368 ; LAW D0368 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $3A,C0060 ; SKPGT C0060 + DB $0C ; INCR +; 778: cout(' ') + DB $2A,$20 ; CB 32 + DB $54,C0012 ; CALL C0012 +; 779: next + DB $50,C0061 ; SKIP C0061 +C0060: + DB $30 ; DROP +; 780: cout('^') + DB $2A,$5E ; CB 94 + DB $54,C0012 ; CALL C0012 +; 781: cin() + DB $54,C0014 ; CALL C0014 +; 782: exit() + DB $54,C0022 ; CALL C0022 +; 783: return ERR_TKN + DB $00 ; ZERO + DB $5A ; LEAVE +; 784: end +; 785: ; +; 786: ; Fixup table and function directory +; 787: ; +; 788: def fixupword_add10(addr) +C0062: ; fixupword_add10() + ; addr = 2 +; 789: end + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $5A ; LEAVE +; 790: def fixupbyte_add10(addr) +C0064: ; fixupbyte_add10() + ; addr = 2 +; 791: end + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $5A ; LEAVE +; 792: def func_add(offset, len, flags) +C0066: ; func_add() + ; offset = 2 + ; len = 4 + ; flags = 6 +; 793: end + JSR _INTERP + DB $58,$08,$03 ; ENTER 8,3 + DB $5A ; LEAVE +; 794: ; +; 795: ; Emit bytecode +; 796: ; +; 797: def ctag_new_01 +C0068: ; ctag_new_01() +; 798: if codetag >= ctag_max + JSR _INTERP + DB $6A,D0020 ; LAW D0020 + DB $2C,$00,$03 ; CW 768 + DB $48 ; ISGE + DB $4C,C0070 ; SKPFLS C0070 +; 799: return parse_err_11(@ctag_full) + DB $26,D0644 ; LA D0644 + DB $54,C0058 ; CALL C0058 + DB $5C ; RET +; 800: fin +C0070: +C0071: +; 801: codetag = codetag + 1 + DB $6A,D0020 ; LAW D0020 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $7A,D0020 ; SAW D0020 +; 802: ctag_value:[codetag] = 0 + DB $2C,$00,$1A ; CW 6656 + DB $6A,D0020 ; LAW D0020 + DB $1E ; IDXW + DB $00 ; ZERO + DB $72 ; SW +; 803: ctag_flags.[codetag] = 0 + DB $2C,$00,$0D ; CW 3328 + DB $6A,D0020 ; LAW D0020 + DB $02 ; IDXB + DB $00 ; ZERO + DB $70 ; SB +; 804: return codetag ? is_ctag + DB $6A,D0020 ; LAW D0020 + DB $2C,$00,$80 ; CW 32768 + DB $16 ; IOR + DB $5C ; RET +; 805: end +; 806: defopt ctag_resolve_21(tag, addr) +C0072: ; ctag_resolve_21() + ; tag = 2 + ; addr = 4 +; 807: word updtptr, nextptr + ; updtptr = 6 + ; nextptr = 8 +; 808: +; 809: tag = tag & mask_ctag + LDY #10 + LDA #2 + JSR ENTER + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$FF + STA ESTKL,X + LDA #$7F + STA ESTKH,X + JSR BAND + LDY #$02 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 810: if ctag_flags.[tag] & resolved + LDY #$00 + STY ESTKL,X + LDA #$0D + STA ESTKH,X + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JSR ADD + LDY #$00 + JSR LB + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR BAND + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0074 +: +; 811: return parse_err_11(@dup_id) + DEX + LDA #D0382 + STA ESTKH,X + JSR C0058 + JMP LEAVE +; 812: fin +C0074: +C0075: +; 813: updtptr = ctag_value:[tag] + DEX + LDY #$00 + STY ESTKL,X + LDA #$1A + STA ESTKH,X + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JSR IDXW + LDY #$00 + JSR LW + LDY #$06 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 814: while updtptr + INX +C0076: + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0077 +: +; 815: ; +; 816: ; Update list of addresses needing resolution +; 817: ; +; 818: nextptr = *updtptr + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR LW + LDY #$08 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 819: *updtptr = addr + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR SW +; 820: updtptr = nextptr + DEX + LDY #$08 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$06 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 821: loop + INX + JMP C0076 +C0077: +; 822: ctag_value:[tag] = addr + DEX + LDY #$00 + STY ESTKL,X + LDA #$1A + STA ESTKH,X + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JSR IDXW + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR SW +; 823: ctag_flags.[tag] = ctag_flags.[tag] ? resolved + DEX + LDY #$00 + STY ESTKL,X + LDA #$0D + STA ESTKH,X + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JSR ADD + DEX + LDY #$00 + STY ESTKL,X + LDA #$0D + STA ESTKH,X + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JSR ADD + LDY #$00 + JSR LB + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR IOR + JSR SB +; 824: return 0 + DEX + STY ESTKL,X + STY ESTKH,X + JMP LEAVE +; 825: end +; 826: defopt emit_byte_10(bval) +C0078: ; emit_byte_10() + ; bval = 2 +; 827: ^codeptr = bval + LDY #4 + LDA #1 + JSR ENTER + DEX + LDA D0022 + STA ESTKL,X + LDA D0022+1 + STA ESTKH,X + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR SB +; 828: codeptr = codeptr + 1 + DEX + LDA D0022 + STA ESTKL,X + LDA D0022+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0022 + LDA ESTKH,X + STA D0022+1 +; 829: end + INX + JMP LEAVE +; 830: defopt emit_word_10(wval) +C0080: ; emit_word_10() + ; wval = 2 +; 831: *codeptr = wval + LDY #4 + LDA #1 + JSR ENTER + DEX + LDA D0022 + STA ESTKL,X + LDA D0022+1 + STA ESTKH,X + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR SW +; 832: codeptr = codeptr + 2 + DEX + LDA D0022 + STA ESTKL,X + LDA D0022+1 + STA ESTKH,X + DEX + LDA #$02 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0022 + LDA ESTKH,X + STA D0022+1 +; 833: end + INX + JMP LEAVE +; 834: def emit_fill_10(size) +C0082: ; emit_fill_10() + ; size = 2 +; 835: memset(0, codeptr, size) + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $00 ; ZERO + DB $6A,D0022 ; LAW D0022 + DB $66,$02 ; LLW 2 + DB $54,C0008 ; CALL C0008 +; 836: codeptr = codeptr + size + DB $6A,D0022 ; LAW D0022 + DB $66,$02 ; LLW 2 + DB $02 ; ADD + DB $7A,D0022 ; SAW D0022 +; 837: end + DB $5A ; LEAVE +; 838: def emit_codetag_10(tag) +C0084: ; emit_codetag_10() + ; tag = 2 +; 839: drop ctag_resolve_21(tag, codeptr) + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $66,$02 ; LLW 2 + DB $6A,D0022 ; LAW D0022 + DB $54,C0072 ; CALL C0072 + DB $30 ; DROP +; 840: end + DB $5A ; LEAVE +; 841: defopt emit_op_10(op) +C0086: ; emit_op_10() + ; op = 2 +; 842: lastop = op + LDY #4 + LDA #1 + JSR ENTER + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDA ESTKL,X + STA D0026 +; 843: ^codeptr = op + LDA D0022 + STA ESTKL,X + LDA D0022+1 + STA ESTKH,X + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR SB +; 844: codeptr = codeptr + 1 + DEX + LDA D0022 + STA ESTKL,X + LDA D0022+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0022 + LDA ESTKH,X + STA D0022+1 +; 845: end + INX + JMP LEAVE +; 846: def emit_tag_10(tag) +C0088: ; emit_tag_10() + ; tag = 2 +; 847: word updtptr + ; updtptr = 4 +; 848: +; 849: if tag & is_ctag + JSR _INTERP + DB $58,$06,$01 ; ENTER 6,1 + DB $66,$02 ; LLW 2 + DB $2C,$00,$80 ; CW 32768 + DB $14 ; BAND + DB $4C,C0090 ; SKPFLS C0090 +; 850: tag = tag & mask_ctag + DB $66,$02 ; LLW 2 + DB $2C,$FF,$7F ; CW 32767 + DB $14 ; BAND + DB $76,$02 ; SLW 2 +; 851: updtptr = ctag_value:[tag] + DB $2C,$00,$1A ; CW 6656 + DB $66,$02 ; LLW 2 + DB $1E ; IDXW + DB $62 ; LW + DB $76,$04 ; SLW 4 +; 852: if !(ctag_flags.[tag] & resolved) + DB $2C,$00,$0D ; CW 3328 + DB $66,$02 ; LLW 2 + DB $02 ; IDXB + DB $60 ; LB + DB $2A,$01 ; CB 1 + DB $14 ; BAND + DB $20 ; NOT + DB $4C,C0092 ; SKPFLS C0092 +; 853: ; +; 854: ; Add to list of tags needing resolution +; 855: ; +; 856: ctag_value:[tag] = codeptr + DB $2C,$00,$1A ; CW 6656 + DB $66,$02 ; LLW 2 + DB $1E ; IDXW + DB $6A,D0022 ; LAW D0022 + DB $72 ; SW +; 857: fin +C0092: +C0093: +; 858: emit_word_10(updtptr) + DB $66,$04 ; LLW 4 + DB $54,C0080 ; CALL C0080 +; 859: else + DB $50,C0091 ; SKIP C0091 +C0090: +; 860: emit_word_10(tag + compbuff) + DB $66,$02 ; LLW 2 + DB $2C,$00,$60 ; CW 24576 + DB $02 ; ADD + DB $54,C0080 ; CALL C0080 +; 861: fin +C0091: +; 862: end + DB $5A ; LEAVE +; 863: def emit_iddata_30(value, size, namestr) +C0094: ; emit_iddata_30() + ; value = 2 + ; size = 4 + ; namestr = 6 +; 864: emit_fill_10(size) + JSR _INTERP + DB $58,$08,$03 ; ENTER 8,3 + DB $66,$04 ; LLW 4 + DB $54,C0082 ; CALL C0082 +; 865: end + DB $5A ; LEAVE +; 866: def emit_data_41(vartype, consttype, constval, constsize) +C0096: ; emit_data_41() + ; vartype = 2 + ; consttype = 4 + ; constval = 6 + ; constsize = 8 +; 867: byte i + ; i = 10 +; 868: word size, chrptr + ; size = 11 + ; chrptr = 13 +; 869: +; 870: if consttype == 0 + JSR _INTERP + DB $58,$0F,$04 ; ENTER 15,4 + DB $66,$04 ; LLW 4 + DB $00 ; ZERO + DB $40 ; ISEQ + DB $4C,C0098 ; SKPFLS C0098 +; 871: size = constsize + DB $66,$08 ; LLW 8 + DB $76,$0B ; SLW 11 +; 872: emit_fill_10(constsize) + DB $66,$08 ; LLW 8 + DB $54,C0082 ; CALL C0082 +; 873: elsif consttype == STR_TYPE + DB $50,C0099 ; SKIP C0099 +C0098: + DB $66,$04 ; LLW 4 + DB $2A,$80 ; CB 128 + DB $40 ; ISEQ + DB $4C,C0100 ; SKPFLS C0100 +; 874: size = constsize + DB $66,$08 ; LLW 8 + DB $76,$0B ; SLW 11 +; 875: chrptr = constval + DB $66,$06 ; LLW 6 + DB $76,$0D ; SLW 13 +; 876: constsize = constsize - 1 + DB $66,$08 ; LLW 8 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $76,$08 ; SLW 8 +; 877: emit_byte_10(constsize) + DB $66,$08 ; LLW 8 + DB $54,C0078 ; CALL C0078 +; 878: while constsize > 0 +C0101: + DB $66,$08 ; LLW 8 + DB $00 ; ZERO + DB $44 ; ISGT + DB $4C,C0102 ; SKPFLS C0102 +; 879: emit_byte_10(^chrptr) + DB $66,$0D ; LLW 13 + DB $60 ; LB + DB $54,C0078 ; CALL C0078 +; 880: chrptr = chrptr + 1 + DB $66,$0D ; LLW 13 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $76,$0D ; SLW 13 +; 881: constsize = constsize - 1 + DB $66,$08 ; LLW 8 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $76,$08 ; SLW 8 +; 882: loop + DB $50,C0101 ; SKIP C0101 +C0102: +; 883: else + DB $50,C0099 ; SKIP C0099 +C0100: +; 884: if vartype == WORD_TYPE + DB $66,$02 ; LLW 2 + DB $2A,$04 ; CB 4 + DB $40 ; ISEQ + DB $4C,C0103 ; SKPFLS C0103 +; 885: size = 2 + DB $2A,$02 ; CB 2 + DB $76,$0B ; SLW 11 +; 886: emit_word_10(constval) + DB $66,$06 ; LLW 6 + DB $54,C0080 ; CALL C0080 +; 887: else + DB $50,C0104 ; SKIP C0104 +C0103: +; 888: size = 1 + DB $2A,$01 ; CB 1 + DB $76,$0B ; SLW 11 +; 889: emit_byte_10(constval) + DB $66,$06 ; LLW 6 + DB $54,C0078 ; CALL C0078 +; 890: fin +C0104: +; 891: fin +C0099: +; 892: return size + DB $66,$0B ; LLW 11 + DB $5A ; LEAVE +; 893: end +; 894: def emit_const_10(cval) +C0105: ; emit_const_10() + ; cval = 2 +; 895: if cval == 0 + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $66,$02 ; LLW 2 + DB $00 ; ZERO + DB $40 ; ISEQ + DB $4C,C0107 ; SKPFLS C0107 +; 896: emit_op_10($00) + DB $00 ; ZERO + DB $54,C0086 ; CALL C0086 +; 897: elsif cval > 0 and cval < 256 + DB $50,C0108 ; SKIP C0108 +C0107: + DB $66,$02 ; LLW 2 + DB $00 ; ZERO + DB $44 ; ISGT + DB $66,$02 ; LLW 2 + DB $2C,$00,$01 ; CW 256 + DB $46 ; ISLT + DB $24 ; LAND + DB $4C,C0109 ; SKPFLS C0109 +; 898: emit_op_10($2A) + DB $2A,$2A ; CB 42 + DB $54,C0086 ; CALL C0086 +; 899: emit_byte_10(cval) + DB $66,$02 ; LLW 2 + DB $54,C0078 ; CALL C0078 +; 900: else + DB $50,C0108 ; SKIP C0108 +C0109: +; 901: emit_op_10($2C) + DB $2A,$2C ; CB 44 + DB $54,C0086 ; CALL C0086 +; 902: emit_word_10(cval) + DB $66,$02 ; LLW 2 + DB $54,C0080 ; CALL C0080 +; 903: fin +C0108: +; 904: end + DB $5A ; LEAVE +; 905: def emit_lb +C0110: ; emit_lb() +; 906: emit_op_10($60) + JSR _INTERP + DB $2A,$60 ; CB 96 + DB $54,C0086 ; CALL C0086 +; 907: end + DB $5C ; RET +; 908: def emit_lw +C0112: ; emit_lw() +; 909: emit_op_10($62) + JSR _INTERP + DB $2A,$62 ; CB 98 + DB $54,C0086 ; CALL C0086 +; 910: end + DB $5C ; RET +; 911: def emit_llb_10(index) +C0114: ; emit_llb_10() + ; index = 2 +; 912: emit_op_10($64) + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$64 ; CB 100 + DB $54,C0086 ; CALL C0086 +; 913: emit_byte_10(index) + DB $66,$02 ; LLW 2 + DB $54,C0078 ; CALL C0078 +; 914: end + DB $5A ; LEAVE +; 915: def emit_llw_10(index) +C0116: ; emit_llw_10() + ; index = 2 +; 916: emit_op_10($66) + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$66 ; CB 102 + DB $54,C0086 ; CALL C0086 +; 917: emit_byte_10(index) + DB $66,$02 ; LLW 2 + DB $54,C0078 ; CALL C0078 +; 918: end + DB $5A ; LEAVE +; 919: def emit_lab_10(tag) +C0118: ; emit_lab_10() + ; tag = 2 +; 920: emit_op_10($68) + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$68 ; CB 104 + DB $54,C0086 ; CALL C0086 +; 921: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0088 ; CALL C0088 +; 922: end + DB $5A ; LEAVE +; 923: def emit_law_10(tag) +C0120: ; emit_law_10() + ; tag = 2 +; 924: emit_op_10($6A) + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$6A ; CB 106 + DB $54,C0086 ; CALL C0086 +; 925: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0088 ; CALL C0088 +; 926: end + DB $5A ; LEAVE +; 927: def emit_sb +C0122: ; emit_sb() +; 928: emit_op_10($70) + JSR _INTERP + DB $2A,$70 ; CB 112 + DB $54,C0086 ; CALL C0086 +; 929: end + DB $5C ; RET +; 930: def emit_sw +C0124: ; emit_sw() +; 931: emit_op_10($72) + JSR _INTERP + DB $2A,$72 ; CB 114 + DB $54,C0086 ; CALL C0086 +; 932: end + DB $5C ; RET +; 933: def emit_slb_10(index) +C0126: ; emit_slb_10() + ; index = 2 +; 934: emit_op_10($74) + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$74 ; CB 116 + DB $54,C0086 ; CALL C0086 +; 935: emit_byte_10(index) + DB $66,$02 ; LLW 2 + DB $54,C0078 ; CALL C0078 +; 936: end + DB $5A ; LEAVE +; 937: def emit_slw_10(index) +C0128: ; emit_slw_10() + ; index = 2 +; 938: emit_op_10($76) + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$76 ; CB 118 + DB $54,C0086 ; CALL C0086 +; 939: emit_byte_10(index) + DB $66,$02 ; LLW 2 + DB $54,C0078 ; CALL C0078 +; 940: end + DB $5A ; LEAVE +; 941: def emit_dlb_10(index) +C0130: ; emit_dlb_10() + ; index = 2 +; 942: emit_op_10($6C) + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$6C ; CB 108 + DB $54,C0086 ; CALL C0086 +; 943: emit_byte_10(index) + DB $66,$02 ; LLW 2 + DB $54,C0078 ; CALL C0078 +; 944: end + DB $5A ; LEAVE +; 945: def emit_dlw_10(index) +C0132: ; emit_dlw_10() + ; index = 2 +; 946: emit_op_10($6E) + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$6E ; CB 110 + DB $54,C0086 ; CALL C0086 +; 947: emit_byte_10(index) + DB $66,$02 ; LLW 2 + DB $54,C0078 ; CALL C0078 +; 948: end + DB $5A ; LEAVE +; 949: def emit_sab_10(tag) +C0134: ; emit_sab_10() + ; tag = 2 +; 950: emit_op_10($78) + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$78 ; CB 120 + DB $54,C0086 ; CALL C0086 +; 951: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0088 ; CALL C0088 +; 952: end + DB $5A ; LEAVE +; 953: def emit_saw_10(tag) +C0136: ; emit_saw_10() + ; tag = 2 +; 954: emit_op_10($7A) + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$7A ; CB 122 + DB $54,C0086 ; CALL C0086 +; 955: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0088 ; CALL C0088 +; 956: end + DB $5A ; LEAVE +; 957: def emit_dab_10(tag) +C0138: ; emit_dab_10() + ; tag = 2 +; 958: emit_op_10($7C) + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$7C ; CB 124 + DB $54,C0086 ; CALL C0086 +; 959: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0088 ; CALL C0088 +; 960: end + DB $5A ; LEAVE +; 961: def emit_daw_10(tag) +C0140: ; emit_daw_10() + ; tag = 2 +; 962: emit_op_10($7E) + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$7E ; CB 126 + DB $54,C0086 ; CALL C0086 +; 963: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0088 ; CALL C0088 +; 964: end + DB $5A ; LEAVE +; 965: def emit_call_10(tag) +C0142: ; emit_call_10() + ; tag = 2 +; 966: emit_op_10($54) + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$54 ; CB 84 + DB $54,C0086 ; CALL C0086 +; 967: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0088 ; CALL C0088 +; 968: end + DB $5A ; LEAVE +; 969: def emit_ical +C0144: ; emit_ical() +; 970: emit_op_10($56) + JSR _INTERP + DB $2A,$56 ; CB 86 + DB $54,C0086 ; CALL C0086 +; 971: end + DB $5C ; RET +; 972: def emit_push +C0146: ; emit_push() +; 973: emit_op_10($34) + JSR _INTERP + DB $2A,$34 ; CB 52 + DB $54,C0086 ; CALL C0086 +; 974: end + DB $5C ; RET +; 975: def emit_pull +C0148: ; emit_pull() +; 976: ; +; 977: ; Skip if last op was push +; 978: ; +; 979: if lastop == $34 + JSR _INTERP + DB $68,D0026 ; LAB D0026 + DB $2A,$34 ; CB 52 + DB $40 ; ISEQ + DB $4C,C0150 ; SKPFLS C0150 +; 980: codeptr = codeptr - 1 + DB $6A,D0022 ; LAW D0022 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $7A,D0022 ; SAW D0022 +; 981: lastop = $FF + DB $2A,$FF ; CB 255 + DB $78,D0026 ; SAB D0026 +; 982: else + DB $50,C0151 ; SKIP C0151 +C0150: +; 983: emit_op_10($36) + DB $2A,$36 ; CB 54 + DB $54,C0086 ; CALL C0086 +; 984: fin +C0151: +; 985: end + DB $5C ; RET +; 986: def emit_localaddr_10(index) +C0152: ; emit_localaddr_10() + ; index = 2 +; 987: emit_op_10($28) + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$28 ; CB 40 + DB $54,C0086 ; CALL C0086 +; 988: emit_byte_10(index) + DB $66,$02 ; LLW 2 + DB $54,C0078 ; CALL C0078 +; 989: end + DB $5A ; LEAVE +; 990: def emit_globaladdr_10(tag) +C0154: ; emit_globaladdr_10() + ; tag = 2 +; 991: emit_op_10($26) + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$26 ; CB 38 + DB $54,C0086 ; CALL C0086 +; 992: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0088 ; CALL C0088 +; 993: end + DB $5A ; LEAVE +; 994: def emit_indexbyte +C0156: ; emit_indexbyte() +; 995: emit_op_10($02) + JSR _INTERP + DB $2A,$02 ; CB 2 + DB $54,C0086 ; CALL C0086 +; 996: end + DB $5C ; RET +; 997: def emit_indexword +C0158: ; emit_indexword() +; 998: emit_op_10($1E) + JSR _INTERP + DB $2A,$1E ; CB 30 + DB $54,C0086 ; CALL C0086 +; 999: end + DB $5C ; RET +; 1000: defopt emit_unaryop_11(op) +C0160: ; emit_unaryop_11() + ; op = 2 +; 1001: when op + LDY #4 + LDA #1 + JSR ENTER + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X +; 1002: is NEG_TKN + DEX + LDA #$AD + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0163 +: +; 1003: emit_op_10($10) + DEX + LDA #$10 + STA ESTKL,X + STY ESTKH,X + JSR C0086 +; 1004: is COMP_TKN + JMP C0162 +C0163: + DEX + LDA #$A3 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0164 +: +; 1005: emit_op_10($12) + DEX + LDA #$12 + STA ESTKL,X + STY ESTKH,X + JSR C0086 +; 1006: is LOGIC_NOT_TKN + JMP C0162 +C0164: + DEX + LDA #$A1 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0165 +: +; 1007: emit_op_10($20) + DEX + LDA #$20 + STA ESTKL,X + STY ESTKH,X + JSR C0086 +; 1008: is INC_TKN + JMP C0162 +C0165: + DEX + LDA #$C1 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0166 +: +; 1009: emit_op_10($0C) + DEX + LDA #$0C + STA ESTKL,X + STY ESTKH,X + JSR C0086 +; 1010: is DEC_TKN + JMP C0162 +C0166: + DEX + LDA #$C4 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0167 +: +; 1011: emit_op_10($0E) + DEX + LDA #$0E + STA ESTKL,X + STY ESTKH,X + JSR C0086 +; 1012: is BPTR_TKN + JMP C0162 +C0167: + DEX + LDA #$DE + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0168 +: +; 1013: emit_op_10($60) + DEX + LDA #$60 + STA ESTKL,X + STY ESTKH,X + JSR C0086 +; 1014: is WPTR_TKN + JMP C0162 +C0168: + DEX + LDA #$AA + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0169 +: +; 1015: emit_op_10($62) + DEX + LDA #$62 + STA ESTKL,X + STY ESTKH,X + JSR C0086 +; 1016: otherwise + JMP C0162 +C0169: +; 1017: return FALSE + LDY #$00 + STY ESTKL,X + STY ESTKH,X + JMP LEAVE +; 1018: wend +C0162: +; 1019: return TRUE + LDA #$FF + STA ESTKL,X + STA ESTKH,X + JMP LEAVE +; 1020: end +; 1021: defopt emit_binaryop_11(op) +C0171: ; emit_binaryop_11() + ; op = 2 +; 1022: when op + LDY #4 + LDA #1 + JSR ENTER + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X +; 1023: is MUL_TKN + DEX + LDA #$AA + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0174 +: +; 1024: ; +; 1025: ; Replace MUL 2 with SHL 1 +; 1026: ; +; 1027: if lastop == $2A and ^(codeptr - 1) == 2 ; CB 2 + DEX + LDA D0026 + STA ESTKL,X + STY ESTKH,X + DEX + LDA #$2A + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + DEX + LDA D0022 + STA ESTKL,X + LDA D0022+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SUB + JSR LB + DEX + LDA #$02 + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + JSR LAND + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0175 +: +; 1028: codeptr = codeptr - 1 + DEX + LDA D0022 + STA ESTKL,X + LDA D0022+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SUB + LDA ESTKL,X + STA D0022 + LDA ESTKH,X + STA D0022+1 +; 1029: emit_byte_10(1) ; CB 1 + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR C0078 +; 1030: emit_op_10($1A) ; SHL + DEX + LDA #$1A + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR C0086 +; 1031: else + JMP C0176 +C0175: +; 1032: emit_op_10($06) + DEX + LDA #$06 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR C0086 +; 1033: fin +C0176: +; 1034: is DIV_TKN + JMP C0173 +C0174: + DEX + LDA #$AF + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0177 +: +; 1035: ; +; 1036: ; Replace DIV 2 with SHR 1 +; 1037: ; +; 1038: if lastop == $2A and ^(codeptr - 1) == 2 ; CB 2 + DEX + LDA D0026 + STA ESTKL,X + STY ESTKH,X + DEX + LDA #$2A + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + DEX + LDA D0022 + STA ESTKL,X + LDA D0022+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SUB + JSR LB + DEX + LDA #$02 + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + JSR LAND + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0178 +: +; 1039: codeptr = codeptr - 1 + DEX + LDA D0022 + STA ESTKL,X + LDA D0022+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SUB + LDA ESTKL,X + STA D0022 + LDA ESTKH,X + STA D0022+1 +; 1040: emit_byte_10(1) ; CB 1 + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR C0078 +; 1041: emit_op_10($1C) ; SHR + DEX + LDA #$1C + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR C0086 +; 1042: else + JMP C0179 +C0178: +; 1043: emit_op_10($08) + DEX + LDA #$08 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR C0086 +; 1044: fin +C0179: +; 1045: is MOD_TKN + JMP C0173 +C0177: + DEX + LDA #$A5 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0180 +: +; 1046: emit_op_10($0A) + DEX + LDA #$0A + STA ESTKL,X + STY ESTKH,X + JSR C0086 +; 1047: is ADD_TKN + JMP C0173 +C0180: + DEX + LDA #$AB + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0181 +: +; 1048: ; +; 1049: ; Replace ADD 1 with INCR +; 1050: ; +; 1051: if lastop == $2A and ^(codeptr - 1) == 1 ; CB 1 + DEX + LDA D0026 + STA ESTKL,X + STY ESTKH,X + DEX + LDA #$2A + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + DEX + LDA D0022 + STA ESTKL,X + LDA D0022+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SUB + JSR LB + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + JSR LAND + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0182 +: +; 1052: codeptr = codeptr - 2 + DEX + LDA D0022 + STA ESTKL,X + LDA D0022+1 + STA ESTKH,X + DEX + LDA #$02 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SUB + LDA ESTKL,X + STA D0022 + LDA ESTKH,X + STA D0022+1 +; 1053: emit_op_10($0C) ; INC_OP + LDA #$0C + STA ESTKL,X + STY ESTKH,X + JSR C0086 +; 1054: else + JMP C0183 +C0182: +; 1055: emit_op_10($02) + DEX + LDA #$02 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR C0086 +; 1056: fin +C0183: +; 1057: is SUB_TKN + JMP C0173 +C0181: + DEX + LDA #$AD + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0184 +: +; 1058: ; +; 1059: ; Replace SUB 1 with DECR +; 1060: ; +; 1061: if lastop == $2A and ^(codeptr - 1) == 1 ; CB 1 + DEX + LDA D0026 + STA ESTKL,X + STY ESTKH,X + DEX + LDA #$2A + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + DEX + LDA D0022 + STA ESTKL,X + LDA D0022+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SUB + JSR LB + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + JSR LAND + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0185 +: +; 1062: codeptr = codeptr - 2 + DEX + LDA D0022 + STA ESTKL,X + LDA D0022+1 + STA ESTKH,X + DEX + LDA #$02 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SUB + LDA ESTKL,X + STA D0022 + LDA ESTKH,X + STA D0022+1 +; 1063: emit_op_10($0E) ; DEC_OP + LDA #$0E + STA ESTKL,X + STY ESTKH,X + JSR C0086 +; 1064: else + JMP C0186 +C0185: +; 1065: emit_op_10($04) + DEX + LDA #$04 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR C0086 +; 1066: fin +C0186: +; 1067: is SHL_TKN + JMP C0173 +C0184: + DEX + LDA #$CC + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0187 +: +; 1068: emit_op_10($1A) + DEX + LDA #$1A + STA ESTKL,X + STY ESTKH,X + JSR C0086 +; 1069: is SHR_TKN + JMP C0173 +C0187: + DEX + LDA #$D2 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0188 +: +; 1070: emit_op_10($1C) + DEX + LDA #$1C + STA ESTKL,X + STY ESTKH,X + JSR C0086 +; 1071: is AND_TKN + JMP C0173 +C0188: + DEX + LDA #$A6 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0189 +: +; 1072: emit_op_10($14) + DEX + LDA #$14 + STA ESTKL,X + STY ESTKH,X + JSR C0086 +; 1073: is OR_TKN + JMP C0173 +C0189: + DEX + LDA #$BF + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0190 +: +; 1074: emit_op_10($16) + DEX + LDA #$16 + STA ESTKL,X + STY ESTKH,X + JSR C0086 +; 1075: is EOR_TKN + JMP C0173 +C0190: + DEX + LDA #$DE + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0191 +: +; 1076: emit_op_10($18) + DEX + LDA #$18 + STA ESTKL,X + STY ESTKH,X + JSR C0086 +; 1077: is EQ_TKN + JMP C0173 +C0191: + DEX + LDA #$C5 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0192 +: +; 1078: emit_op_10($40) + DEX + LDA #$40 + STA ESTKL,X + STY ESTKH,X + JSR C0086 +; 1079: is NE_TKN + JMP C0173 +C0192: + DEX + LDA #$D5 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0193 +: +; 1080: emit_op_10($42) + DEX + LDA #$42 + STA ESTKL,X + STY ESTKH,X + JSR C0086 +; 1081: is GE_TKN + JMP C0173 +C0193: + DEX + LDA #$C8 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0194 +: +; 1082: emit_op_10($48) + DEX + LDA #$48 + STA ESTKL,X + STY ESTKH,X + JSR C0086 +; 1083: is LT_TKN + JMP C0173 +C0194: + DEX + LDA #$BC + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0195 +: +; 1084: emit_op_10($46) + DEX + LDA #$46 + STA ESTKL,X + STY ESTKH,X + JSR C0086 +; 1085: is GT_TKN + JMP C0173 +C0195: + DEX + LDA #$BE + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0196 +: +; 1086: emit_op_10($44) + DEX + LDA #$44 + STA ESTKL,X + STY ESTKH,X + JSR C0086 +; 1087: is LE_TKN + JMP C0173 +C0196: + DEX + LDA #$C2 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0197 +: +; 1088: emit_op_10($4A) + DEX + LDA #$4A + STA ESTKL,X + STY ESTKH,X + JSR C0086 +; 1089: is LOGIC_OR_TKN + JMP C0173 +C0197: + DEX + LDA #$CF + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0198 +: +; 1090: emit_op_10($22) + DEX + LDA #$22 + STA ESTKL,X + STY ESTKH,X + JSR C0086 +; 1091: is LOGIC_AND_TKN + JMP C0173 +C0198: + DEX + LDA #$CE + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0199 +: +; 1092: emit_op_10($24) + DEX + LDA #$24 + STA ESTKL,X + STY ESTKH,X + JSR C0086 +; 1093: is COMMA_TKN + JMP C0173 +C0199: + DEX + LDA #$AC + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0200 +: +; 1094: ; Do nothing except move to next stanza in expression +; 1095: otherwise + JMP C0173 +C0200: +; 1096: return FALSE + LDY #$00 + STY ESTKL,X + STY ESTKH,X + JMP LEAVE +; 1097: wend +C0173: +; 1098: return TRUE + LDA #$FF + STA ESTKL,X + STA ESTKH,X + JMP LEAVE +; 1099: end +; 1100: def emit_brtru_10(tag) +C0202: ; emit_brtru_10() + ; tag = 2 +; 1101: emit_op_10($4E) + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$4E ; CB 78 + DB $54,C0086 ; CALL C0086 +; 1102: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0088 ; CALL C0088 +; 1103: end + DB $5A ; LEAVE +; 1104: def emit_brfls_10(tag) +C0204: ; emit_brfls_10() + ; tag = 2 +; 1105: emit_op_10($4C) + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$4C ; CB 76 + DB $54,C0086 ; CALL C0086 +; 1106: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0088 ; CALL C0088 +; 1107: end + DB $5A ; LEAVE +; 1108: def emit_brgt_10(tag) +C0206: ; emit_brgt_10() + ; tag = 2 +; 1109: emit_op_10($3A) + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$3A ; CB 58 + DB $54,C0086 ; CALL C0086 +; 1110: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0088 ; CALL C0088 +; 1111: end + DB $5A ; LEAVE +; 1112: def emit_brlt_10(tag) +C0208: ; emit_brlt_10() + ; tag = 2 +; 1113: emit_op_10($38) + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$38 ; CB 56 + DB $54,C0086 ; CALL C0086 +; 1114: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0088 ; CALL C0088 +; 1115: end + DB $5A ; LEAVE +; 1116: def emit_brne_10(tag) +C0210: ; emit_brne_10() + ; tag = 2 +; 1117: emit_op_10($3E) + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$3E ; CB 62 + DB $54,C0086 ; CALL C0086 +; 1118: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0088 ; CALL C0088 +; 1119: end + DB $5A ; LEAVE +; 1120: def emit_jump_10(tag) +C0212: ; emit_jump_10() + ; tag = 2 +; 1121: emit_op_10($50) + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$50 ; CB 80 + DB $54,C0086 ; CALL C0086 +; 1122: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0088 ; CALL C0088 +; 1123: end + DB $5A ; LEAVE +; 1124: def emit_drop +C0214: ; emit_drop() +; 1125: emit_op_10($30) + JSR _INTERP + DB $2A,$30 ; CB 48 + DB $54,C0086 ; CALL C0086 +; 1126: end + DB $5C ; RET +; 1127: def emit_swap +C0216: ; emit_swap() +; 1128: emit_op_10($2E) + JSR _INTERP + DB $2A,$2E ; CB 46 + DB $54,C0086 ; CALL C0086 +; 1129: end + DB $5C ; RET +; 1130: def emit_leave_10(framesize) +C0218: ; emit_leave_10() + ; framesize = 2 +; 1131: if framesize > 2 + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $66,$02 ; LLW 2 + DB $2A,$02 ; CB 2 + DB $44 ; ISGT + DB $4C,C0220 ; SKPFLS C0220 +; 1132: emit_op_10($5A) + DB $2A,$5A ; CB 90 + DB $54,C0086 ; CALL C0086 +; 1133: else + DB $50,C0221 ; SKIP C0221 +C0220: +; 1134: emit_op_10($5C) + DB $2A,$5C ; CB 92 + DB $54,C0086 ; CALL C0086 +; 1135: fin +C0221: +; 1136: end + DB $5A ; LEAVE +; 1137: def emit_enter_20(framesize, cparams) +C0222: ; emit_enter_20() + ; framesize = 2 + ; cparams = 4 +; 1138: emit_byte_10($20) + JSR _INTERP + DB $58,$06,$02 ; ENTER 6,2 + DB $2A,$20 ; CB 32 + DB $54,C0078 ; CALL C0078 +; 1139: emit_byte_10($D0) + DB $2A,$D0 ; CB 208 + DB $54,C0078 ; CALL C0078 +; 1140: emit_byte_10($03) + DB $2A,$03 ; CB 3 + DB $54,C0078 ; CALL C0078 +; 1141: if framesize > 2 + DB $66,$02 ; LLW 2 + DB $2A,$02 ; CB 2 + DB $44 ; ISGT + DB $4C,C0224 ; SKPFLS C0224 +; 1142: emit_op_10($58) + DB $2A,$58 ; CB 88 + DB $54,C0086 ; CALL C0086 +; 1143: emit_byte_10(framesize) + DB $66,$02 ; LLW 2 + DB $54,C0078 ; CALL C0078 +; 1144: emit_byte_10(cparams) + DB $66,$04 ; LLW 4 + DB $54,C0078 ; CALL C0078 +; 1145: fin +C0224: +C0225: +; 1146: end + DB $5A ; LEAVE +; 1147: def emit_start +C0226: ; emit_start() +; 1148: ; +; 1149: ; Save address +; 1150: ; +; 1151: entrypoint = codeptr + JSR _INTERP + DB $6A,D0022 ; LAW D0022 + DB $7A,D0024 ; SAW D0024 +; 1152: emit_byte_10(emit_start.[0]) + DB $26,C0226 ; LA C0226 + DB $00 ; ZERO + DB $02 ; IDXB + DB $60 ; LB + DB $54,C0078 ; CALL C0078 +; 1153: emit_byte_10(emit_start.[1]) + DB $26,C0226 ; LA C0226 + DB $2A,$01 ; CB 1 + DB $02 ; IDXB + DB $60 ; LB + DB $54,C0078 ; CALL C0078 +; 1154: emit_byte_10(emit_start.[2]) + DB $26,C0226 ; LA C0226 + DB $2A,$02 ; CB 2 + DB $02 ; IDXB + DB $60 ; LB + DB $54,C0078 ; CALL C0078 +; 1155: end + DB $5C ; RET +; 1156: def emit_exit +C0228: ; emit_exit() +; 1157: emit_op_10($00) + JSR _INTERP + DB $00 ; ZERO + DB $54,C0086 ; CALL C0086 +; 1158: emit_op_10($5C) + DB $2A,$5C ; CB 92 + DB $54,C0086 ; CALL C0086 +; 1159: end + DB $5C ; RET +; 1160: ; +; 1161: ; Lexical anaylzer +; 1162: ; +; 1163: ;def isalpha_11(c) +; 1164: ; if c >= 'A' and c <= 'Z' +; 1165: ; return TRUE +; 1166: ; elsif c >= 'a' and c <= 'z' +; 1167: ; return TRUE +; 1168: ; elsif c == '_' +; 1169: ; return TRUE +; 1170: ; fin +; 1171: ; return FALSE +; 1172: ;end +; 1173: asm isalpha_11 +C0230: ; isalpha_11() +; 1174: LDY #$00 + LDY #$00 +; 1175: LDA ESTKL,X + LDA ESTKL,X +; 1176: CMP #'A' + CMP #'A' +; 1177: BCC ISALRET + BCC ISALRET +; 1178: CMP #'Z'+1 + CMP #'Z'+1 +; 1179: BCS :+ + BCS :+ +; 1180: DEY + DEY +; 1181: BNE ISALRET + BNE ISALRET +; 1182: : CMP #'a' +: CMP #'a' +; 1183: BCC ISALRET + BCC ISALRET +; 1184: CMP #'z'+1 + CMP #'z'+1 +; 1185: BCS :+ + BCS :+ +; 1186: DEY + DEY +; 1187: BNE ISALRET + BNE ISALRET +; 1188: : CMP #'_' +: CMP #'_' +; 1189: BNE ISALRET + BNE ISALRET +; 1190: DEY + DEY +; 1191: ISALRET: +ISALRET: +; 1192: STY ESTKL,X + STY ESTKL,X +; 1193: STY ESTKH,X + STY ESTKH,X +; 1194: RTS + RTS +; 1195: end + RTS +; 1196: ;def isnum_11(c) +; 1197: ; if c >= '0' and c <= '9' +; 1198: ; return TRUE +; 1199: ; fin +; 1200: ; return FALSE +; 1201: ;end +; 1202: asm isnum_11 +C0232: ; isnum_11() +; 1203: LDY #$00 + LDY #$00 +; 1204: LDA ESTKL,X + LDA ESTKL,X +; 1205: CMP #'0' + CMP #'0' +; 1206: BCC :+ + BCC :+ +; 1207: CMP #'9'+1 + CMP #'9'+1 +; 1208: BCS :+ + BCS :+ +; 1209: DEY + DEY +; 1210: : STY ESTKL,X +: STY ESTKL,X +; 1211: STY ESTKH,X + STY ESTKH,X +; 1212: RTS + RTS +; 1213: end + RTS +; 1214: ;def isalphanum_11(c) +; 1215: ; if c >= 'A' and c <= 'Z' +; 1216: ; return TRUE +; 1217: ; elsif c >= '0' and c <= '9' +; 1218: ; return TRUE +; 1219: ; elsif c >= 'a' and c <= 'z' +; 1220: ; return TRUE +; 1221: ; elsif c == '_' +; 1222: ; return TRUE +; 1223: ; fin +; 1224: ; return FALSE +; 1225: ;end +; 1226: asm isalphanum_11 +C0234: ; isalphanum_11() +; 1227: LDY #$00 + LDY #$00 +; 1228: LDA ESTKL,X + LDA ESTKL,X +; 1229: CMP #'0' + CMP #'0' +; 1230: BCC ISANRET + BCC ISANRET +; 1231: CMP #'9'+1 + CMP #'9'+1 +; 1232: BCS :+ + BCS :+ +; 1233: DEY + DEY +; 1234: BNE ISANRET + BNE ISANRET +; 1235: : CMP #'A' +: CMP #'A' +; 1236: BCC ISANRET + BCC ISANRET +; 1237: CMP #'Z'+1 + CMP #'Z'+1 +; 1238: BCS :+ + BCS :+ +; 1239: DEY + DEY +; 1240: BNE ISANRET + BNE ISANRET +; 1241: : CMP #'a' +: CMP #'a' +; 1242: BCC :+ + BCC :+ +; 1243: CMP #'z'+1 + CMP #'z'+1 +; 1244: BCS ISANRET + BCS ISANRET +; 1245: DEY + DEY +; 1246: BNE ISANRET + BNE ISANRET +; 1247: : CMP #'_' +: CMP #'_' +; 1248: BNE ISANRET + BNE ISANRET +; 1249: DEY + DEY +; 1250: ISANRET: +ISANRET: +; 1251: STY ESTKL,X + STY ESTKL,X +; 1252: STY ESTKH,X + STY ESTKH,X +; 1253: RTS + RTS +; 1254: end + RTS +; 1255: defopt keymatch_21(chrptr, len) +C0236: ; keymatch_21() + ; chrptr = 2 + ; len = 4 +; 1256: byte i, keypos + ; i = 6 + ; keypos = 7 +; 1257: +; 1258: keypos = 0 + LDY #8 + LDA #2 + JSR ENTER + DEX + STY ESTKL,X + STY ESTKH,X + LDY #$07 + LDA ESTKL,X + STA (FRMP),Y +; 1259: while keywrds[keypos] < len + INX +C0238: + DEX + LDA #D0075 + STA ESTKH,X + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR ISLT + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0239 +: +; 1260: keypos = keypos + keywrds[keypos] + 2 + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA #D0075 + STA ESTKH,X + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + JSR ADD + DEX + LDA #$02 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDY #$07 + LDA ESTKL,X + STA (FRMP),Y +; 1261: loop + INX + JMP C0238 +C0239: +; 1262: while keywrds[keypos] == len +C0240: + DEX + LDA #D0075 + STA ESTKH,X + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0241 +: +; 1263: for i = 1 to len + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X +C0243: + LDY #$06 + LDA ESTKL,X + STA (FRMP),Y + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + LDA ESTKH-1,X + SBC ESTKH,X + BPL :+ + JMP C0242 +: + INC ESTKL,X + BNE :+ + INC ESTKH,X +: +; 1264: if toupper_11((chrptr).[i - 1]) <> keywrds[keypos + i] + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR SUB + JSR ADD + JSR LB + JSR C0020 + DEX + LDA #D0075 + STA ESTKH,X + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR ADD + JSR LB + JSR ISNE + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0244 +: +; 1265: break + JMP C0242 +; 1266: fin +C0244: +C0245: +; 1267: next + JMP C0243 +C0242: +; 1268: if i > len + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR ISGT + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0246 +: +; 1269: return keywrds[keypos + keywrds[keypos] + 1] + DEX + LDA #D0075 + STA ESTKH,X + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA #D0075 + STA ESTKH,X + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + JSR ADD + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ADD + JSR ADD + JSR LB + JMP LEAVE +; 1270: fin +C0246: +C0247: +; 1271: keypos = keypos + keywrds[keypos] + 2 + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA #D0075 + STA ESTKH,X + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + JSR ADD + DEX + LDA #$02 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDY #$07 + LDA ESTKL,X + STA (FRMP),Y +; 1272: loop + INX + JMP C0240 +C0241: +; 1273: return ID_TKN + DEX + LDA #$D6 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JMP LEAVE +; 1274: end +; 1275: defopt scan_01 +C0248: ; scan_01() +; 1276: ; +; 1277: ; Scan for token based on first character +; 1278: ; +; 1279: while ^scanptr and ^scanptr <= ' ' +C0250: + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + LDY #$00 + JSR LB + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + JSR LB + DEX + LDA #$20 + STA ESTKL,X + STY ESTKH,X + JSR ISLE + JSR LAND + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0251 +: +; 1280: scanptr = scanptr + 1 + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0366 + LDA ESTKH,X + STA D0366+1 +; 1281: loop + INX + JMP C0250 +C0251: +; 1282: tknptr = scanptr + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + LDA ESTKL,X + STA D0368 + LDA ESTKH,X + STA D0368+1 +; 1283: if !^scanptr or ^scanptr == ';' + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + LDY #$00 + JSR LB + JSR NOT + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + JSR LB + DEX + LDA #$3B + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + JSR LOR + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0252 +: +; 1284: if token <> EOF_TKN + DEX + LDA D0364 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ISNE + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0254 +: +; 1285: token = EOL_TKN + DEX + LDA #$02 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDA ESTKL,X + STA D0364 +; 1286: fin + INX +C0254: +C0255: +; 1287: elsif isalpha_11(^scanptr) + JMP C0253 +C0252: + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + LDY #$00 + JSR LB + JSR C0230 + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0256 +: +; 1288: ; +; 1289: ; ID, either variable name or reserved word +; 1290: ; +; 1291: repeat +C0258: +; 1292: scanptr = scanptr + 1 + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0366 + LDA ESTKH,X + STA D0366+1 +; 1293: until !isalphanum_11(^scanptr) + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + JSR LB + JSR C0234 + LDY #$00 + JSR NOT + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0258 +: +C0257: +; 1294: tknlen = scanptr - tknptr; + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA D0368 + STA ESTKL,X + LDA D0368+1 + STA ESTKH,X + JSR SUB + LDA ESTKL,X + STA D0365 +; 1295: token = keymatch_21(tknptr, tknlen) + LDA D0368 + STA ESTKL,X + LDA D0368+1 + STA ESTKH,X + DEX + LDA D0365 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR C0236 + LDA ESTKL,X + STA D0364 +; 1296: elsif isnum_11(^scanptr) + INX + JMP C0253 +C0256: + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + LDY #$00 + JSR LB + JSR C0232 + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0259 +: +; 1297: ; +; 1298: ; Number constant +; 1299: ; +; 1300: token = INT_TKN + DEX + LDA #$C9 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDA ESTKL,X + STA D0364 +; 1301: constval = 0 + STY ESTKL,X + STY ESTKH,X + LDA ESTKL,X + STA D0370 + LDA ESTKH,X + STA D0370+1 +; 1302: repeat + INX +C0261: +; 1303: constval = constval * 10 + ^scanptr - '0' + DEX + LDA D0370 + STA ESTKL,X + LDA D0370+1 + STA ESTKH,X + DEX + LDA #$0A + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR MUL + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + JSR LB + JSR ADD + DEX + LDA #$30 + STA ESTKL,X + STY ESTKH,X + JSR SUB + LDA ESTKL,X + STA D0370 + LDA ESTKH,X + STA D0370+1 +; 1304: scanptr = scanptr + 1 + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0366 + LDA ESTKH,X + STA D0366+1 +; 1305: until !isnum_11(^scanptr) + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + JSR LB + JSR C0232 + LDY #$00 + JSR NOT + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0261 +: +C0260: +; 1306: elsif ^scanptr == '$' + JMP C0253 +C0259: + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + LDY #$00 + JSR LB + DEX + LDA #$24 + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0262 +: +; 1307: ; +; 1308: ; Hexadecimal constant +; 1309: ; +; 1310: token = INT_TKN; + DEX + LDA #$C9 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDA ESTKL,X + STA D0364 +; 1311: constval = 0 + STY ESTKL,X + STY ESTKH,X + LDA ESTKL,X + STA D0370 + LDA ESTKH,X + STA D0370+1 +; 1312: repeat + INX +C0264: +; 1313: scanptr = scanptr + 1 + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0366 + LDA ESTKH,X + STA D0366+1 +; 1314: if ^scanptr >= '0' and ^scanptr <= '9' + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + JSR LB + DEX + LDA #$30 + STA ESTKL,X + STY ESTKH,X + JSR ISGE + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + LDY #$00 + JSR LB + DEX + LDA #$39 + STA ESTKL,X + STY ESTKH,X + JSR ISLE + JSR LAND + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0265 +: +; 1315: constval = (constval << 4) + ^scanptr - '0' + DEX + LDA D0370 + STA ESTKL,X + LDA D0370+1 + STA ESTKH,X + DEX + LDA #$04 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SHL + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + JSR LB + JSR ADD + DEX + LDA #$30 + STA ESTKL,X + STY ESTKH,X + JSR SUB + LDA ESTKL,X + STA D0370 + LDA ESTKH,X + STA D0370+1 +; 1316: elsif ^scanptr >= 'A' and ^scanptr <= 'F' + INX + JMP C0266 +C0265: + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + LDY #$00 + JSR LB + DEX + LDA #$41 + STA ESTKL,X + STY ESTKH,X + JSR ISGE + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + LDY #$00 + JSR LB + DEX + LDA #$46 + STA ESTKL,X + STY ESTKH,X + JSR ISLE + JSR LAND + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0267 +: +; 1317: constval = (constval << 4) + ^scanptr - '7'; 'A'-10 + DEX + LDA D0370 + STA ESTKL,X + LDA D0370+1 + STA ESTKH,X + DEX + LDA #$04 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SHL + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + JSR LB + JSR ADD + DEX + LDA #$37 + STA ESTKL,X + STY ESTKH,X + JSR SUB + LDA ESTKL,X + STA D0370 + LDA ESTKH,X + STA D0370+1 +; 1318: elsif ^scanptr >= 'a' and ^scanptr <= 'f' + INX + JMP C0266 +C0267: + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + LDY #$00 + JSR LB + DEX + LDA #$61 + STA ESTKL,X + STY ESTKH,X + JSR ISGE + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + LDY #$00 + JSR LB + DEX + LDA #$66 + STA ESTKL,X + STY ESTKH,X + JSR ISLE + JSR LAND + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0268 +: +; 1319: constval = (constval << 4) + ^scanptr - 'W'; 'a'-10 + DEX + LDA D0370 + STA ESTKL,X + LDA D0370+1 + STA ESTKH,X + DEX + LDA #$04 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SHL + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + JSR LB + JSR ADD + DEX + LDA #$57 + STA ESTKL,X + STY ESTKH,X + JSR SUB + LDA ESTKL,X + STA D0370 + LDA ESTKH,X + STA D0370+1 +; 1320: else + INX + JMP C0266 +C0268: +; 1321: break; + JMP C0263 +; 1322: fin +C0266: +; 1323: until !^scanptr + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + LDY #$00 + JSR LB + JSR NOT + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0264 +: +C0263: +; 1324: elsif ^scanptr == $27 ; ' + JMP C0253 +C0262: + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + LDY #$00 + JSR LB + DEX + LDA #$27 + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0269 +: +; 1325: ; +; 1326: ; Character constant +; 1327: ; +; 1328: token = CHR_TKN + DEX + LDA #$C3 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDA ESTKL,X + STA D0364 +; 1329: if ^(scanptr + 1) <> $5C ; \ + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDA #$5C + STA ESTKL,X + STY ESTKH,X + JSR ISNE + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0270 +: +; 1330: constval = ^(scanptr + 1) + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + LDA ESTKL,X + STA D0370 + LDA ESTKH,X + STA D0370+1 +; 1331: if ^(scanptr + 2) <> $27 ; ' + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA #$02 + STA ESTKL,X + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDA #$27 + STA ESTKL,X + STY ESTKH,X + JSR ISNE + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0272 +: +; 1332: return parse_err_11(@bad_cnst) + DEX + LDA #D0425 + STA ESTKH,X + JSR C0058 + RTS +; 1333: fin +C0272: +C0273: +; 1334: scanptr = scanptr + 3 + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA #$03 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0366 + LDA ESTKH,X + STA D0366+1 +; 1335: else + INX + JMP C0271 +C0270: +; 1336: when ^(scanptr + 2) + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA #$02 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB +; 1337: is 'n' + DEX + LDA #$6E + STA ESTKL,X + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0275 +: +; 1338: constval = $0D + DEX + LDA #$0D + STA ESTKL,X + STY ESTKH,X + LDA ESTKL,X + STA D0370 + LDA ESTKH,X + STA D0370+1 +; 1339: is 'r' + INX + JMP C0274 +C0275: + DEX + LDA #$72 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0276 +: +; 1340: constval = $0A + DEX + LDA #$0A + STA ESTKL,X + STY ESTKH,X + LDA ESTKL,X + STA D0370 + LDA ESTKH,X + STA D0370+1 +; 1341: is 't' + INX + JMP C0274 +C0276: + DEX + LDA #$74 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0277 +: +; 1342: constval = $09 + DEX + LDA #$09 + STA ESTKL,X + STY ESTKH,X + LDA ESTKL,X + STA D0370 + LDA ESTKH,X + STA D0370+1 +; 1343: otherwise + INX + JMP C0274 +C0277: +; 1344: constval = ^(scanptr + 2) + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA #$02 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + LDA ESTKL,X + STA D0370 + LDA ESTKH,X + STA D0370+1 +; 1345: wend + INX +C0274: +; 1346: if ^(scanptr + 3) <> $27 ; ' + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA #$03 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDA #$27 + STA ESTKL,X + STY ESTKH,X + JSR ISNE + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0279 +: +; 1347: return parse_err_11(@bad_cnst) + DEX + LDA #D0425 + STA ESTKH,X + JSR C0058 + RTS +; 1348: fin +C0279: +C0280: +; 1349: scanptr = scanptr + 4 + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA #$04 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0366 + LDA ESTKH,X + STA D0366+1 +; 1350: fin + INX +C0271: +; 1351: elsif ^scanptr == '"' + JMP C0253 +C0269: + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + LDY #$00 + JSR LB + DEX + LDA #$22 + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0281 +: +; 1352: ; +; 1353: ; String constant +; 1354: ; +; 1355: token = STR_TKN + DEX + LDA #$D3 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDA ESTKL,X + STA D0364 +; 1356: scanptr = scanptr + 1 + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0366 + LDA ESTKH,X + STA D0366+1 +; 1357: constval = scanptr + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + LDA ESTKL,X + STA D0370 + LDA ESTKH,X + STA D0370+1 +; 1358: while ^scanptr and ^scanptr <> '"' + INX +C0282: + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + LDY #$00 + JSR LB + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + JSR LB + DEX + LDA #$22 + STA ESTKL,X + STY ESTKH,X + JSR ISNE + JSR LAND + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0283 +: +; 1359: scanptr = scanptr + 1 + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0366 + LDA ESTKH,X + STA D0366+1 +; 1360: loop + INX + JMP C0282 +C0283: +; 1361: if !^scanptr + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + LDY #$00 + JSR LB + JSR NOT + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0284 +: +; 1362: return parse_err_11(@bad_cnst) + DEX + LDA #D0425 + STA ESTKH,X + JSR C0058 + RTS +; 1363: fin +C0284: +C0285: +; 1364: scanptr = scanptr + 1 + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0366 + LDA ESTKH,X + STA D0366+1 +; 1365: else + INX + JMP C0253 +C0281: +; 1366: ; +; 1367: ; Potential two and three character tokens +; 1368: ; +; 1369: when ^scanptr + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + LDY #$00 + JSR LB +; 1370: is '>' + DEX + LDA #$3E + STA ESTKL,X + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0287 +: +; 1371: if ^(scanptr + 1) == '>' + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDA #$3E + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0288 +: +; 1372: token = SHR_TKN + DEX + LDA #$D2 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDA ESTKL,X + STA D0364 +; 1373: scanptr = scanptr + 2 + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA #$02 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0366 + LDA ESTKH,X + STA D0366+1 +; 1374: elsif ^(scanptr + 1) == '=' + INX + JMP C0289 +C0288: + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDA #$3D + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0290 +: +; 1375: token = GE_TKN + DEX + LDA #$C8 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDA ESTKL,X + STA D0364 +; 1376: scanptr = scanptr + 2 + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA #$02 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0366 + LDA ESTKH,X + STA D0366+1 +; 1377: else + INX + JMP C0289 +C0290: +; 1378: token = GT_TKN + DEX + LDA #$BE + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDA ESTKL,X + STA D0364 +; 1379: scanptr = scanptr + 1 + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0366 + LDA ESTKH,X + STA D0366+1 +; 1380: fin + INX +C0289: +; 1381: is '<' + JMP C0286 +C0287: + DEX + LDA #$3C + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0291 +: +; 1382: if ^(scanptr + 1) == '<' + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDA #$3C + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0292 +: +; 1383: token = SHL_TKN + DEX + LDA #$CC + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDA ESTKL,X + STA D0364 +; 1384: scanptr = scanptr + 2 + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA #$02 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0366 + LDA ESTKH,X + STA D0366+1 +; 1385: elsif ^(scanptr + 1) == '=' + INX + JMP C0293 +C0292: + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDA #$3D + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0294 +: +; 1386: token = LE_TKN + DEX + LDA #$C2 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDA ESTKL,X + STA D0364 +; 1387: scanptr = scanptr + 2 + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA #$02 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0366 + LDA ESTKH,X + STA D0366+1 +; 1388: elsif ^(scanptr + 1) == '>' + INX + JMP C0293 +C0294: + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDA #$3E + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0295 +: +; 1389: token = NE_TKN + DEX + LDA #$D5 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDA ESTKL,X + STA D0364 +; 1390: scanptr = scanptr + 2 + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA #$02 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0366 + LDA ESTKH,X + STA D0366+1 +; 1391: else + INX + JMP C0293 +C0295: +; 1392: token = LT_TKN + DEX + LDA #$BC + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDA ESTKL,X + STA D0364 +; 1393: scanptr = scanptr + 1 + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0366 + LDA ESTKH,X + STA D0366+1 +; 1394: fin + INX +C0293: +; 1395: is '=' + JMP C0286 +C0291: + DEX + LDA #$3D + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0296 +: +; 1396: if ^(scanptr + 1) == '=' + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDA #$3D + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0297 +: +; 1397: token = EQ_TKN + DEX + LDA #$C5 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDA ESTKL,X + STA D0364 +; 1398: scanptr = scanptr + 2; + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA #$02 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0366 + LDA ESTKH,X + STA D0366+1 +; 1399: elsif ^(scanptr + 1) == ',' + INX + JMP C0298 +C0297: + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDA #$2C + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0299 +: +; 1400: token = SETLIST_TKN + DEX + LDA #$B9 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDA ESTKL,X + STA D0364 +; 1401: scanptr = scanptr + 2; + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA #$02 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0366 + LDA ESTKH,X + STA D0366+1 +; 1402: else + INX + JMP C0298 +C0299: +; 1403: token = SET_TKN; + DEX + LDA #$BD + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDA ESTKL,X + STA D0364 +; 1404: scanptr = scanptr + 1 + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0366 + LDA ESTKH,X + STA D0366+1 +; 1405: fin + INX +C0298: +; 1406: otherwise + JMP C0286 +C0296: +; 1407: ; +; 1408: ; Simple single character tokens +; 1409: ; +; 1410: token = ^scanptr ? $80 + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + LDY #$00 + JSR LB + DEX + LDA #$80 + STA ESTKL,X + STY ESTKH,X + JSR IOR + LDA ESTKL,X + STA D0364 +; 1411: scanptr = scanptr + 1 + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0366 + LDA ESTKH,X + STA D0366+1 +; 1412: wend + INX +C0286: +; 1413: fin + INX +C0253: +; 1414: tknlen = scanptr - tknptr + DEX + LDA D0366 + STA ESTKL,X + LDA D0366+1 + STA ESTKH,X + DEX + LDA D0368 + STA ESTKL,X + LDA D0368+1 + STA ESTKH,X + JSR SUB + LDA ESTKL,X + STA D0365 +; 1415: return token + LDA D0364 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + RTS +; 1416: end +; 1417: def rewind_10(ptr) +C0301: ; rewind_10() + ; ptr = 2 +; 1418: scanptr = ptr + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $66,$02 ; LLW 2 + DB $7A,D0366 ; SAW D0366 +; 1419: end + DB $5A ; LEAVE +; 1420: ; +; 1421: ; Get next line of input +; 1422: ; +; 1423: def nextln_01 +C0303: ; nextln_01() +; 1424: byte i, chr + ; i = 2 + ; chr = 3 +; 1425: +; 1426: scanptr = inbuff + JSR _INTERP + DB $58,$04,$00 ; ENTER 4,0 + DB $2C,$00,$02 ; CW 512 + DB $7A,D0366 ; SAW D0366 +; 1427: ^instr = read_31(inref, inbuff, $7F) + DB $2C,$FF,$01 ; CW 511 + DB $68,D0000 ; LAB D0000 + DB $2C,$00,$02 ; CW 512 + DB $2A,$7F ; CB 127 + DB $54,C0032 ; CALL C0032 + DB $70 ; SB +; 1428: inbuff[^instr] = $00 + DB $2C,$00,$02 ; CW 512 + DB $2C,$FF,$01 ; CW 511 + DB $60 ; LB + DB $02 ; IDXB + DB $00 ; ZERO + DB $70 ; SB +; 1429: if ^instr + DB $2C,$FF,$01 ; CW 511 + DB $60 ; LB + DB $4C,C0305 ; SKPFLS C0305 +; 1430: lineno = lineno + 1 + DB $6A,D0372 ; LAW D0372 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $7A,D0372 ; SAW D0372 +; 1431: if !(lineno & $0F) + DB $6A,D0372 ; LAW D0372 + DB $2A,$0F ; CB 15 + DB $14 ; BAND + DB $20 ; NOT + DB $4C,C0307 ; SKPFLS C0307 +; 1432: cout('.') + DB $2A,$2E ; CB 46 + DB $54,C0012 ; CALL C0012 +; 1433: fin +C0307: +C0308: +; 1434: ; cout('>') +; 1435: ; prstr(instr) +; 1436: ; crout +; 1437: drop scan_01() + DB $54,C0248 ; CALL C0248 + DB $30 ; DROP +; 1438: else + DB $50,C0306 ; SKIP C0306 +C0305: +; 1439: ^instr = 0 + DB $2C,$FF,$01 ; CW 511 + DB $00 ; ZERO + DB $70 ; SB +; 1440: ^inbuff = $00 + DB $2C,$00,$02 ; CW 512 + DB $00 ; ZERO + DB $70 ; SB +; 1441: token = DONE_TKN + DB $2A,$98 ; CB 152 + DB $78,D0364 ; SAB D0364 +; 1442: fin +C0306: +; 1443: return ^instr + DB $2C,$FF,$01 ; CW 511 + DB $60 ; LB + DB $5A ; LEAVE +; 1444: end +; 1445: ; +; 1446: ; Alebraic op to stack op +; 1447: ; +; 1448: def push_op_21(op, prec) +C0309: ; push_op_21() + ; op = 2 + ; prec = 4 +; 1449: opsp = opsp + 1 + JSR _INTERP + DB $58,$06,$02 ; ENTER 6,2 + DB $6A,D0362 ; LAW D0362 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $7A,D0362 ; SAW D0362 +; 1450: if opsp == 16 + DB $6A,D0362 ; LAW D0362 + DB $2A,$10 ; CB 16 + DB $40 ; ISEQ + DB $4C,C0311 ; SKPFLS C0311 +; 1451: return parse_err_11(@estk_overflw) + DB $26,D0525 ; LA D0525 + DB $54,C0058 ; CALL C0058 + DB $5A ; LEAVE +; 1452: fin +C0311: +C0312: +; 1453: opstack[opsp] = op + DB $26,D0330 ; LA D0330 + DB $6A,D0362 ; LAW D0362 + DB $02 ; IDXB + DB $66,$02 ; LLW 2 + DB $70 ; SB +; 1454: precstack[opsp] = prec + DB $26,D0346 ; LA D0346 + DB $6A,D0362 ; LAW D0362 + DB $02 ; IDXB + DB $66,$04 ; LLW 4 + DB $70 ; SB +; 1455: return 0 + DB $00 ; ZERO + DB $5A ; LEAVE +; 1456: end +; 1457: def pop_op_01 +C0313: ; pop_op_01() +; 1458: if opsp < 0 + JSR _INTERP + DB $6A,D0362 ; LAW D0362 + DB $00 ; ZERO + DB $46 ; ISLT + DB $4C,C0315 ; SKPFLS C0315 +; 1459: return parse_err_11(@estk_underflw) + DB $26,D0545 ; LA D0545 + DB $54,C0058 ; CALL C0058 + DB $5C ; RET +; 1460: fin +C0315: +C0316: +; 1461: opsp = opsp - 1 + DB $6A,D0362 ; LAW D0362 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $7A,D0362 ; SAW D0362 +; 1462: return opstack[opsp + 1] + DB $26,D0330 ; LA D0330 + DB $6A,D0362 ; LAW D0362 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $02 ; IDXB + DB $60 ; LB + DB $5C ; RET +; 1463: end +; 1464: def tos_op_01 +C0317: ; tos_op_01() +; 1465: if opsp < 0 + JSR _INTERP + DB $6A,D0362 ; LAW D0362 + DB $00 ; ZERO + DB $46 ; ISLT + DB $4C,C0319 ; SKPFLS C0319 +; 1466: return 0 + DB $00 ; ZERO + DB $5C ; RET +; 1467: fin +C0319: +C0320: +; 1468: return opstack[opsp] + DB $26,D0330 ; LA D0330 + DB $6A,D0362 ; LAW D0362 + DB $02 ; IDXB + DB $60 ; LB + DB $5C ; RET +; 1469: end +; 1470: def tos_op_prec_11(tos) +C0321: ; tos_op_prec_11() + ; tos = 2 +; 1471: if opsp <= tos + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $6A,D0362 ; LAW D0362 + DB $66,$02 ; LLW 2 + DB $4A ; ISLE + DB $4C,C0323 ; SKPFLS C0323 +; 1472: return 100 + DB $2A,$64 ; CB 100 + DB $5A ; LEAVE +; 1473: fin +C0323: +C0324: +; 1474: return precstack[opsp] + DB $26,D0346 ; LA D0346 + DB $6A,D0362 ; LAW D0362 + DB $02 ; IDXB + DB $60 ; LB + DB $5A ; LEAVE +; 1475: end +; 1476: ; +; 1477: ; Symbol table +; 1478: ; +; 1479: defopt idmatch_41(nameptr, len, idptr, idcnt) +C0325: ; idmatch_41() + ; nameptr = 2 + ; len = 4 + ; idptr = 6 + ; idcnt = 8 +; 1480: byte i + ; i = 10 +; 1481: +; 1482: while idcnt + LDY #11 + LDA #4 + JSR ENTER +C0327: + DEX + LDY #$08 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0328 +: +; 1483: if len == (idptr).idname + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$03 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0329 +: +; 1484: for i = 1 to len + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X +C0332: + LDY #$0A + LDA ESTKL,X + STA (FRMP),Y + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + LDA ESTKH-1,X + SBC ESTKH,X + BPL :+ + JMP C0331 +: + INC ESTKL,X + BNE :+ + INC ESTKH,X +: +; 1485: if (nameptr).[i - 1] <> (idptr).idname.[i] + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$0A + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR SUB + JSR ADD + JSR LB + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$03 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + DEX + LDY #$0A + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + JSR ISNE + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0333 +: +; 1486: break + JMP C0331 +; 1487: fin +C0333: +C0334: +; 1488: next + JMP C0332 +C0331: +; 1489: if i > len + LDY #$0A + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR ISGT + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0335 +: +; 1490: return idptr + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JMP LEAVE +; 1491: fin +C0335: +C0336: +; 1492: fin +C0329: +C0330: +; 1493: idptr = idptr + (idptr).idname + idrecsz + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$03 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + JSR ADD + DEX + LDA #$04 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDY #$06 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 1494: idcnt = idcnt - 1 + LDY #$08 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SUB + LDY #$08 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 1495: loop + INX + JMP C0327 +C0328: +; 1496: return 0 + DEX + LDY #$00 + STY ESTKL,X + STY ESTKH,X + JMP LEAVE +; 1497: end +; 1498: ;def dumpsym_20(idptr, idcnt) +; 1499: ; while idcnt +; 1500: ; prword_10((idptr):idval) +; 1501: ; cout(' ') +; 1502: ; prbyte_10((idptr).idtype) +; 1503: ; cout(' ') +; 1504: ; prstr(@(idptr).idname) +; 1505: ; cout('=') +; 1506: ; if (idptr).idtype & ADDR_TYPE +; 1507: ; if (idptr):idval & is_ctag +; 1508: ; prword_10(ctag_value:[(idptr):idval & mask_ctag]) +; 1509: ; else +; 1510: ; prword_10((idptr):idval + compbuff) +; 1511: ; fin +; 1512: ; else +; 1513: ; prword_10((idptr):idval) +; 1514: ; fin +; 1515: ; crout() +; 1516: ; idptr = idptr + (idptr).idname + idrecsz +; 1517: ; idcnt = idcnt - 1 +; 1518: ; loop +; 1519: ;end +; 1520: def id_lookup_21(nameptr, len) +C0337: ; id_lookup_21() + ; nameptr = 2 + ; len = 4 +; 1521: word idptr + ; idptr = 6 +; 1522: +; 1523: idptr = idmatch_41(nameptr, len, idlocal_tbl, locals) + JSR _INTERP + DB $58,$08,$02 ; ENTER 8,2 + DB $66,$02 ; LLW 2 + DB $66,$04 ; LLW 4 + DB $2C,$00,$18 ; CW 6144 + DB $68,D0015 ; LAB D0015 + DB $54,C0325 ; CALL C0325 + DB $76,$06 ; SLW 6 +; 1524: if idptr + DB $66,$06 ; LLW 6 + DB $4C,C0339 ; SKPFLS C0339 +; 1525: return idptr + DB $66,$06 ; LLW 6 + DB $5A ; LEAVE +; 1526: fin +C0339: +C0340: +; 1527: idptr = idmatch_41(nameptr, len, idglobal_tbl, globals) + DB $66,$02 ; LLW 2 + DB $66,$04 ; LLW 4 + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0009 ; LAW D0009 + DB $54,C0325 ; CALL C0325 + DB $76,$06 ; SLW 6 +; 1528: if idptr + DB $66,$06 ; LLW 6 + DB $4C,C0341 ; SKPFLS C0341 +; 1529: return idptr + DB $66,$06 ; LLW 6 + DB $5A ; LEAVE +; 1530: fin +C0341: +C0342: +; 1531: return parse_err_11(@undecl_id) + DB $26,D0403 ; LA D0403 + DB $54,C0058 ; CALL C0058 + DB $5A ; LEAVE +; 1532: end +; 1533: def idglobal_lookup_21(nameptr, len) +C0343: ; idglobal_lookup_21() + ; nameptr = 2 + ; len = 4 +; 1534: return idmatch_41(nameptr, len, idglobal_tbl, globals) + JSR _INTERP + DB $58,$06,$02 ; ENTER 6,2 + DB $66,$02 ; LLW 2 + DB $66,$04 ; LLW 4 + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0009 ; LAW D0009 + DB $54,C0325 ; CALL C0325 + DB $5A ; LEAVE +; 1535: end +; 1536: def idlocal_add_41(namestr, len, type, size) +C0345: ; idlocal_add_41() + ; namestr = 2 + ; len = 4 + ; type = 6 + ; size = 8 +; 1537: if idmatch_41(namestr, len, @idlocal_tbl, locals) + JSR _INTERP + DB $58,$0A,$04 ; ENTER 10,4 + DB $66,$02 ; LLW 2 + DB $66,$04 ; LLW 4 + DB $2C,$00,$18 ; CW 6144 + DB $68,D0015 ; LAB D0015 + DB $54,C0325 ; CALL C0325 + DB $4C,C0347 ; SKPFLS C0347 +; 1538: return parse_err_11(@dup_id) + DB $26,D0382 ; LA D0382 + DB $54,C0058 ; CALL C0058 + DB $5A ; LEAVE +; 1539: fin +C0347: +C0348: +; 1540: (lastlocal):idval = framesize + DB $6A,D0018 ; LAW D0018 + DB $6A,D0016 ; LAW D0016 + DB $72 ; SW +; 1541: (lastlocal).idtype = type ? LOCAL_TYPE + DB $6A,D0018 ; LAW D0018 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $66,$06 ; LLW 6 + DB $2A,$10 ; CB 16 + DB $16 ; IOR + DB $70 ; SB +; 1542: nametostr_30(namestr, len, lastlocal + idname) + DB $66,$02 ; LLW 2 + DB $66,$04 ; LLW 4 + DB $6A,D0018 ; LAW D0018 + DB $2A,$03 ; CB 3 + DB $02 ; ADD + DB $54,C0056 ; CALL C0056 +; 1543: locals = locals + 1 + DB $68,D0015 ; LAB D0015 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $78,D0015 ; SAB D0015 +; 1544: lastlocal = lastlocal + idrecsz + len + DB $6A,D0018 ; LAW D0018 + DB $2A,$04 ; CB 4 + DB $02 ; ADD + DB $66,$04 ; LLW 4 + DB $02 ; ADD + DB $7A,D0018 ; SAW D0018 +; 1545: if lastlocal > idlocal_tbl + idlocal_tblsz + DB $6A,D0018 ; LAW D0018 + DB $2C,$00,$18 ; CW 6144 + DB $2C,$00,$02 ; CW 512 + DB $02 ; ADD + DB $44 ; ISGT + DB $4C,C0349 ; SKPFLS C0349 +; 1546: prstr(@local_sym_overflw) + DB $26,D0616 ; LA D0616 + DB $54,C0016 ; CALL C0016 +; 1547: exit + DB $54,C0022 ; CALL C0022 +; 1548: fin +C0349: +C0350: +; 1549: framesize = framesize + size + DB $6A,D0016 ; LAW D0016 + DB $66,$08 ; LLW 8 + DB $02 ; ADD + DB $7A,D0016 ; SAW D0016 +; 1550: if framesize > 255 + DB $6A,D0016 ; LAW D0016 + DB $2A,$FF ; CB 255 + DB $44 ; ISGT + DB $4C,C0351 ; SKPFLS C0351 +; 1551: prstr(@local_overflw) + DB $26,D0566 ; LA D0566 + DB $54,C0016 ; CALL C0016 +; 1552: return FALSE + DB $00 ; ZERO + DB $5A ; LEAVE +; 1553: fin +C0351: +C0352: +; 1554: return TRUE + DB $2C,$FF,$FF ; CW -1 + DB $5A ; LEAVE +; 1555: end +; 1556: def iddata_add_41(namestr, len, type, size) +C0353: ; iddata_add_41() + ; namestr = 2 + ; len = 4 + ; type = 6 + ; size = 8 +; 1557: if idmatch_41(namestr, len, idglobal_tbl, globals) + JSR _INTERP + DB $58,$0A,$04 ; ENTER 10,4 + DB $66,$02 ; LLW 2 + DB $66,$04 ; LLW 4 + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0009 ; LAW D0009 + DB $54,C0325 ; CALL C0325 + DB $4C,C0355 ; SKPFLS C0355 +; 1558: return parse_err_11(@dup_id) + DB $26,D0382 ; LA D0382 + DB $54,C0058 ; CALL C0058 + DB $5A ; LEAVE +; 1559: fin +C0355: +C0356: +; 1560: (lastglobal):idval = datasize + DB $6A,D0013 ; LAW D0013 + DB $6A,D0011 ; LAW D0011 + DB $72 ; SW +; 1561: (lastglobal).idtype = type + DB $6A,D0013 ; LAW D0013 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $66,$06 ; LLW 6 + DB $70 ; SB +; 1562: nametostr_30(namestr, len, lastglobal + idname) + DB $66,$02 ; LLW 2 + DB $66,$04 ; LLW 4 + DB $6A,D0013 ; LAW D0013 + DB $2A,$03 ; CB 3 + DB $02 ; ADD + DB $54,C0056 ; CALL C0056 +; 1563: emit_iddata_30(datasize, size, lastglobal + idname) + DB $6A,D0011 ; LAW D0011 + DB $66,$08 ; LLW 8 + DB $6A,D0013 ; LAW D0013 + DB $2A,$03 ; CB 3 + DB $02 ; ADD + DB $54,C0094 ; CALL C0094 +; 1564: globals = globals + 1 + DB $6A,D0009 ; LAW D0009 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $7A,D0009 ; SAW D0009 +; 1565: lastglobal = lastglobal + idrecsz + len + DB $6A,D0013 ; LAW D0013 + DB $2A,$04 ; CB 4 + DB $02 ; ADD + DB $66,$04 ; LLW 4 + DB $02 ; ADD + DB $7A,D0013 ; SAW D0013 +; 1566: if lastglobal > idglobal_tbl + idglobal_tblsz + DB $6A,D0013 ; LAW D0013 + DB $2C,$00,$10 ; CW 4096 + DB $2C,$00,$08 ; CW 2048 + DB $02 ; ADD + DB $44 ; ISGT + DB $4C,C0357 ; SKPFLS C0357 +; 1567: prstr(@global_sym_overflw) + DB $26,D0587 ; LA D0587 + DB $54,C0016 ; CALL C0016 +; 1568: exit + DB $54,C0022 ; CALL C0022 +; 1569: fin +C0357: +C0358: +; 1570: datasize = datasize + size + DB $6A,D0011 ; LAW D0011 + DB $66,$08 ; LLW 8 + DB $02 ; ADD + DB $7A,D0011 ; SAW D0011 +; 1571: return TRUE + DB $2C,$FF,$FF ; CW -1 + DB $5A ; LEAVE +; 1572: end +; 1573: def iddata_size_30(type, varsize, initsize) +C0359: ; iddata_size_30() + ; type = 2 + ; varsize = 4 + ; initsize = 6 +; 1574: if varsize > initsize + JSR _INTERP + DB $58,$08,$03 ; ENTER 8,3 + DB $66,$04 ; LLW 4 + DB $66,$06 ; LLW 6 + DB $44 ; ISGT + DB $4C,C0361 ; SKPFLS C0361 +; 1575: datasize = datasize + emit_data_41(0, 0, 0, varsize - initsize) + DB $6A,D0011 ; LAW D0011 + DB $00 ; ZERO + DB $00 ; ZERO + DB $00 ; ZERO + DB $66,$04 ; LLW 4 + DB $66,$06 ; LLW 6 + DB $04 ; SUB + DB $54,C0096 ; CALL C0096 + DB $02 ; ADD + DB $7A,D0011 ; SAW D0011 +; 1576: else + DB $50,C0362 ; SKIP C0362 +C0361: +; 1577: datasize = datasize + initsize + DB $6A,D0011 ; LAW D0011 + DB $66,$06 ; LLW 6 + DB $02 ; ADD + DB $7A,D0011 ; SAW D0011 +; 1578: fin +C0362: +; 1579: ; if datasize <> codeptr - compbuff +; 1580: ; prstr(@emiterr) +; 1581: ; keyin_01() +; 1582: ; fin +; 1583: end + DB $5A ; LEAVE +; 1584: def idglobal_add_41(namestr, len, type, value) +C0363: ; idglobal_add_41() + ; namestr = 2 + ; len = 4 + ; type = 6 + ; value = 8 +; 1585: if idmatch_41(namestr, len, idglobal_tbl, globals) + JSR _INTERP + DB $58,$0A,$04 ; ENTER 10,4 + DB $66,$02 ; LLW 2 + DB $66,$04 ; LLW 4 + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0009 ; LAW D0009 + DB $54,C0325 ; CALL C0325 + DB $4C,C0365 ; SKPFLS C0365 +; 1586: return parse_err_11(@dup_id) + DB $26,D0382 ; LA D0382 + DB $54,C0058 ; CALL C0058 + DB $5A ; LEAVE +; 1587: fin +C0365: +C0366: +; 1588: (lastglobal):idval = value + DB $6A,D0013 ; LAW D0013 + DB $66,$08 ; LLW 8 + DB $72 ; SW +; 1589: (lastglobal).idtype = type + DB $6A,D0013 ; LAW D0013 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $66,$06 ; LLW 6 + DB $70 ; SB +; 1590: nametostr_30(namestr, len, lastglobal + idname) + DB $66,$02 ; LLW 2 + DB $66,$04 ; LLW 4 + DB $6A,D0013 ; LAW D0013 + DB $2A,$03 ; CB 3 + DB $02 ; ADD + DB $54,C0056 ; CALL C0056 +; 1591: globals = globals + 1 + DB $6A,D0009 ; LAW D0009 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $7A,D0009 ; SAW D0009 +; 1592: lastglobal = lastglobal + idrecsz + len + DB $6A,D0013 ; LAW D0013 + DB $2A,$04 ; CB 4 + DB $02 ; ADD + DB $66,$04 ; LLW 4 + DB $02 ; ADD + DB $7A,D0013 ; SAW D0013 +; 1593: if lastglobal > idglobal_tbl + idglobal_tblsz + DB $6A,D0013 ; LAW D0013 + DB $2C,$00,$10 ; CW 4096 + DB $2C,$00,$08 ; CW 2048 + DB $02 ; ADD + DB $44 ; ISGT + DB $4C,C0367 ; SKPFLS C0367 +; 1594: prstr(@global_sym_overflw) + DB $26,D0587 ; LA D0587 + DB $54,C0016 ; CALL C0016 +; 1595: exit + DB $54,C0022 ; CALL C0022 +; 1596: fin +C0367: +C0368: +; 1597: return TRUE + DB $2C,$FF,$FF ; CW -1 + DB $5A ; LEAVE +; 1598: end +; 1599: def idfunc_add_31(namestr, len, tag) +C0369: ; idfunc_add_31() + ; namestr = 2 + ; len = 4 + ; tag = 6 +; 1600: return idglobal_add_41(namestr, len, FUNC_TYPE, tag) + JSR _INTERP + DB $58,$08,$03 ; ENTER 8,3 + DB $66,$02 ; LLW 2 + DB $66,$04 ; LLW 4 + DB $2A,$08 ; CB 8 + DB $66,$06 ; LLW 6 + DB $54,C0363 ; CALL C0363 + DB $5A ; LEAVE +; 1601: end +; 1602: def idconst_add_31(namestr, len, value) +C0371: ; idconst_add_31() + ; namestr = 2 + ; len = 4 + ; value = 6 +; 1603: return idglobal_add_41(namestr, len, CONST_TYPE, value) + JSR _INTERP + DB $58,$08,$03 ; ENTER 8,3 + DB $66,$02 ; LLW 2 + DB $66,$04 ; LLW 4 + DB $2A,$01 ; CB 1 + DB $66,$06 ; LLW 6 + DB $54,C0363 ; CALL C0363 + DB $5A ; LEAVE +; 1604: end +; 1605: def idglobal_init +C0373: ; idglobal_init() +; 1606: word ctag + ; ctag = 2 +; 1607: +; 1608: lineno = 0 + JSR _INTERP + DB $58,$04,$00 ; ENTER 4,0 + DB $00 ; ZERO + DB $7A,D0372 ; SAW D0372 +; 1609: codeptr = compbuff + DB $2C,$00,$60 ; CW 24576 + DB $7A,D0022 ; SAW D0022 +; 1610: lastop = $FF + DB $2A,$FF ; CB 255 + DB $78,D0026 ; SAB D0026 +; 1611: entrypoint = 0 + DB $00 ; ZERO + DB $7A,D0024 ; SAW D0024 +; 1612: datasize = 0 + DB $00 ; ZERO + DB $7A,D0011 ; SAW D0011 +; 1613: globals = 0 + DB $00 ; ZERO + DB $7A,D0009 ; SAW D0009 +; 1614: lastglobal = idglobal_tbl + DB $2C,$00,$10 ; CW 4096 + DB $7A,D0013 ; SAW D0013 +; 1615: codetag = -1 + DB $2C,$FF,$FF ; CW -1 + DB $7A,D0020 ; SAW D0020 +; 1616: ctag = ctag_new_01() + DB $54,C0068 ; CALL C0068 + DB $76,$02 ; SLW 2 +; 1617: drop idfunc_add_31(@runtime0 + 1, runtime0, ctag) + DB $26,D0800 ; LA D0800 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0800 ; LAB D0800 + DB $66,$02 ; LLW 2 + DB $54,C0369 ; CALL C0369 + DB $30 ; DROP +; 1618: drop idfunc_add_31(@RUNTIME0 + 1, RUNTIME0, ctag) + DB $26,D0808 ; LA D0808 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0808 ; LAB D0808 + DB $66,$02 ; LLW 2 + DB $54,C0369 ; CALL C0369 + DB $30 ; DROP +; 1619: drop ctag_resolve_21(ctag, @romcall) + DB $66,$02 ; LLW 2 + DB $26,C0004 ; LA C0004 + DB $54,C0072 ; CALL C0072 + DB $30 ; DROP +; 1620: ctag = ctag_new_01() + DB $54,C0068 ; CALL C0068 + DB $76,$02 ; SLW 2 +; 1621: drop idfunc_add_31(@runtime1 + 1, runtime1, ctag) + DB $26,D0816 ; LA D0816 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0816 ; LAB D0816 + DB $66,$02 ; LLW 2 + DB $54,C0369 ; CALL C0369 + DB $30 ; DROP +; 1622: drop idfunc_add_31(@RUNTIME1 + 1, RUNTIME1, ctag) + DB $26,D0824 ; LA D0824 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0824 ; LAB D0824 + DB $66,$02 ; LLW 2 + DB $54,C0369 ; CALL C0369 + DB $30 ; DROP +; 1623: drop ctag_resolve_21(ctag, @syscall) + DB $66,$02 ; LLW 2 + DB $26,C0006 ; LA C0006 + DB $54,C0072 ; CALL C0072 + DB $30 ; DROP +; 1624: ctag = ctag_new_01() + DB $54,C0068 ; CALL C0068 + DB $76,$02 ; SLW 2 +; 1625: drop idfunc_add_31(@runtime2 + 1, runtime2, ctag) + DB $26,D0832 ; LA D0832 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0832 ; LAB D0832 + DB $66,$02 ; LLW 2 + DB $54,C0369 ; CALL C0369 + DB $30 ; DROP +; 1626: drop idfunc_add_31(@RUNTIME2 + 1, RUNTIME2, ctag) + DB $26,D0839 ; LA D0839 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0839 ; LAB D0839 + DB $66,$02 ; LLW 2 + DB $54,C0369 ; CALL C0369 + DB $30 ; DROP +; 1627: drop ctag_resolve_21(ctag, @memset) + DB $66,$02 ; LLW 2 + DB $26,C0008 ; LA C0008 + DB $54,C0072 ; CALL C0072 + DB $30 ; DROP +; 1628: ctag = ctag_new_01() + DB $54,C0068 ; CALL C0068 + DB $76,$02 ; SLW 2 +; 1629: drop idfunc_add_31(@runtime3 + 1, runtime3, ctag) + DB $26,D0846 ; LA D0846 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0846 ; LAB D0846 + DB $66,$02 ; LLW 2 + DB $54,C0369 ; CALL C0369 + DB $30 ; DROP +; 1630: drop idfunc_add_31(@RUNTIME3 + 1, RUNTIME3, ctag) + DB $26,D0853 ; LA D0853 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0853 ; LAB D0853 + DB $66,$02 ; LLW 2 + DB $54,C0369 ; CALL C0369 + DB $30 ; DROP +; 1631: drop ctag_resolve_21(ctag, @memcpy) + DB $66,$02 ; LLW 2 + DB $26,C0010 ; LA C0010 + DB $54,C0072 ; CALL C0072 + DB $30 ; DROP +; 1632: ctag = ctag_new_01() + DB $54,C0068 ; CALL C0068 + DB $76,$02 ; SLW 2 +; 1633: drop idfunc_add_31(@runtime4 + 1, runtime4, ctag) + DB $26,D0860 ; LA D0860 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0860 ; LAB D0860 + DB $66,$02 ; LLW 2 + DB $54,C0369 ; CALL C0369 + DB $30 ; DROP +; 1634: drop idfunc_add_31(@RUNTIME4 + 1, RUNTIME4, ctag) + DB $26,D0865 ; LA D0865 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0865 ; LAB D0865 + DB $66,$02 ; LLW 2 + DB $54,C0369 ; CALL C0369 + DB $30 ; DROP +; 1635: drop ctag_resolve_21(ctag, @cout) + DB $66,$02 ; LLW 2 + DB $26,C0012 ; LA C0012 + DB $54,C0072 ; CALL C0072 + DB $30 ; DROP +; 1636: ctag = ctag_new_01() + DB $54,C0068 ; CALL C0068 + DB $76,$02 ; SLW 2 +; 1637: drop idfunc_add_31(@runtime5 + 1, runtime5, ctag) + DB $26,D0870 ; LA D0870 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0870 ; LAB D0870 + DB $66,$02 ; LLW 2 + DB $54,C0369 ; CALL C0369 + DB $30 ; DROP +; 1638: drop idfunc_add_31(@RUNTIME5 + 1, RUNTIME5, ctag) + DB $26,D0874 ; LA D0874 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0874 ; LAB D0874 + DB $66,$02 ; LLW 2 + DB $54,C0369 ; CALL C0369 + DB $30 ; DROP +; 1639: drop ctag_resolve_21(ctag, @cin) + DB $66,$02 ; LLW 2 + DB $26,C0014 ; LA C0014 + DB $54,C0072 ; CALL C0072 + DB $30 ; DROP +; 1640: ctag = ctag_new_01() + DB $54,C0068 ; CALL C0068 + DB $76,$02 ; SLW 2 +; 1641: drop idfunc_add_31(@runtime6 + 1, runtime6, ctag) + DB $26,D0878 ; LA D0878 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0878 ; LAB D0878 + DB $66,$02 ; LLW 2 + DB $54,C0369 ; CALL C0369 + DB $30 ; DROP +; 1642: drop idfunc_add_31(@RUNTIME6 + 1, RUNTIME6, ctag) + DB $26,D0884 ; LA D0884 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0884 ; LAB D0884 + DB $66,$02 ; LLW 2 + DB $54,C0369 ; CALL C0369 + DB $30 ; DROP +; 1643: drop ctag_resolve_21(ctag, @prstr) + DB $66,$02 ; LLW 2 + DB $26,C0016 ; LA C0016 + DB $54,C0072 ; CALL C0072 + DB $30 ; DROP +; 1644: ctag = ctag_new_01() + DB $54,C0068 ; CALL C0068 + DB $76,$02 ; SLW 2 +; 1645: drop idfunc_add_31(@runtime7 + 1, runtime7, ctag) + DB $26,D0890 ; LA D0890 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0890 ; LAB D0890 + DB $66,$02 ; LLW 2 + DB $54,C0369 ; CALL C0369 + DB $30 ; DROP +; 1646: drop idfunc_add_31(@RUNTIME7 + 1, RUNTIME7, ctag) + DB $26,D0896 ; LA D0896 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0896 ; LAB D0896 + DB $66,$02 ; LLW 2 + DB $54,C0369 ; CALL C0369 + DB $30 ; DROP +; 1647: drop ctag_resolve_21(ctag, @rdstr) + DB $66,$02 ; LLW 2 + DB $26,C0018 ; LA C0018 + DB $54,C0072 ; CALL C0072 + DB $30 ; DROP +; 1648: end + DB $5A ; LEAVE +; 1649: def idlocal_init +C0375: ; idlocal_init() +; 1650: locals = 0 + JSR _INTERP + DB $00 ; ZERO + DB $78,D0015 ; SAB D0015 +; 1651: framesize = 2 + DB $2A,$02 ; CB 2 + DB $7A,D0016 ; SAW D0016 +; 1652: lastlocal = idlocal_tbl + DB $2C,$00,$18 ; CW 6144 + DB $7A,D0018 ; SAW D0018 +; 1653: end + DB $5C ; RET +; 1654: ; +; 1655: ; Parser +; 1656: ; +; 1657: def parse_term_01 +C0377: ; parse_term_01() +; 1658: when scan_01() + JSR _INTERP + DB $54,C0248 ; CALL C0248 +; 1659: is ID_TKN + DB $2A,$D6 ; CB 214 + DB $3E,C0380 ; SKPNE C0380 +; 1660: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5C ; RET +; 1661: is INT_TKN + DB $50,C0379 ; SKIP C0379 +C0380: + DB $2A,$C9 ; CB 201 + DB $3E,C0381 ; SKPNE C0381 +; 1662: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5C ; RET +; 1663: is CHR_TKN + DB $50,C0379 ; SKIP C0379 +C0381: + DB $2A,$C3 ; CB 195 + DB $3E,C0382 ; SKPNE C0382 +; 1664: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5C ; RET +; 1665: is STR_TKN + DB $50,C0379 ; SKIP C0379 +C0382: + DB $2A,$D3 ; CB 211 + DB $3E,C0383 ; SKPNE C0383 +; 1666: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5C ; RET +; 1667: is OPEN_PAREN_TKN + DB $50,C0379 ; SKIP C0379 +C0383: + DB $2A,$A8 ; CB 168 + DB $3E,C0384 ; SKPNE C0384 +; 1668: if !parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $20 ; NOT + DB $4C,C0385 ; SKPFLS C0385 +; 1669: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5C ; RET +; 1670: fin +C0385: +C0386: +; 1671: if token <> CLOSE_PAREN_TKN + DB $68,D0364 ; LAB D0364 + DB $2A,$A9 ; CB 169 + DB $42 ; ISNE + DB $4C,C0387 ; SKPFLS C0387 +; 1672: return parse_err_11(@no_close_paren) + DB $30 ; DROP + DB $26,D0664 ; LA D0664 + DB $54,C0058 ; CALL C0058 + DB $5C ; RET +; 1673: fin +C0387: +C0388: +; 1674: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5C ; RET +; 1675: wend + DB $50,C0379 ; SKIP C0379 +C0384: +C0379: + DB $30 ; DROP +; 1676: return FALSE + DB $00 ; ZERO + DB $5C ; RET +; 1677: end +; 1678: def parse_constval_21(valptr, sizeptr) +C0390: ; parse_constval_21() + ; valptr = 2 + ; sizeptr = 4 +; 1679: byte mod, type + ; mod = 6 + ; type = 7 +; 1680: word idptr + ; idptr = 8 +; 1681: +; 1682: mod = 0 + JSR _INTERP + DB $58,$0A,$02 ; ENTER 10,2 + DB $00 ; ZERO + DB $74,$06 ; SLB 6 +; 1683: type = 0 + DB $00 ; ZERO + DB $74,$07 ; SLB 7 +; 1684: *valptr = 0 + DB $66,$02 ; LLW 2 + DB $00 ; ZERO + DB $72 ; SW +; 1685: while !parse_term_01() +C0392: + DB $54,C0377 ; CALL C0377 + DB $20 ; NOT + DB $4C,C0393 ; SKPFLS C0393 +; 1686: when token + DB $68,D0364 ; LAB D0364 +; 1687: is SUB_TKN + DB $2A,$AD ; CB 173 + DB $3E,C0395 ; SKPNE C0395 +; 1688: mod = mod ? 1 + DB $64,$06 ; LLB 6 + DB $2A,$01 ; CB 1 + DB $16 ; IOR + DB $74,$06 ; SLB 6 +; 1689: is COMP_TKN + DB $50,C0394 ; SKIP C0394 +C0395: + DB $2A,$A3 ; CB 163 + DB $3E,C0396 ; SKPNE C0396 +; 1690: mod = mod ? 2 + DB $64,$06 ; LLB 6 + DB $2A,$02 ; CB 2 + DB $16 ; IOR + DB $74,$06 ; SLB 6 +; 1691: is LOGIC_NOT_TKN + DB $50,C0394 ; SKIP C0394 +C0396: + DB $2A,$A1 ; CB 161 + DB $3E,C0397 ; SKPNE C0397 +; 1692: mod = mod ? 4 + DB $64,$06 ; LLB 6 + DB $2A,$04 ; CB 4 + DB $16 ; IOR + DB $74,$06 ; SLB 6 +; 1693: is AT_TKN + DB $50,C0394 ; SKIP C0394 +C0397: + DB $2A,$C0 ; CB 192 + DB $3E,C0398 ; SKPNE C0398 +; 1694: mod = mod ? 8 + DB $64,$06 ; LLB 6 + DB $2A,$08 ; CB 8 + DB $16 ; IOR + DB $74,$06 ; SLB 6 +; 1695: otherwise + DB $50,C0394 ; SKIP C0394 +C0398: +; 1696: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 1697: wend +C0394: + DB $30 ; DROP +; 1698: loop + DB $50,C0392 ; SKIP C0392 +C0393: +; 1699: when token + DB $68,D0364 ; LAB D0364 +; 1700: is STR_TKN + DB $2A,$D3 ; CB 211 + DB $3E,C0401 ; SKPNE C0401 +; 1701: *valptr = constval + DB $66,$02 ; LLW 2 + DB $6A,D0370 ; LAW D0370 + DB $72 ; SW +; 1702: ^sizeptr = tknlen - 1 + DB $66,$04 ; LLW 4 + DB $68,D0365 ; LAB D0365 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $70 ; SB +; 1703: type = STR_TYPE + DB $2A,$80 ; CB 128 + DB $74,$07 ; SLB 7 +; 1704: if mod + DB $64,$06 ; LLB 6 + DB $4C,C0402 ; SKPFLS C0402 +; 1705: return parse_err_11(@bad_op) + DB $30 ; DROP + DB $26,D0472 ; LA D0472 + DB $54,C0058 ; CALL C0058 + DB $5A ; LEAVE +; 1706: fin +C0402: +C0403: +; 1707: is CHR_TKN + DB $50,C0400 ; SKIP C0400 +C0401: + DB $2A,$C3 ; CB 195 + DB $3E,C0404 ; SKPNE C0404 +; 1708: *valptr = constval + DB $66,$02 ; LLW 2 + DB $6A,D0370 ; LAW D0370 + DB $72 ; SW +; 1709: ^sizeptr = 1 + DB $66,$04 ; LLW 4 + DB $2A,$01 ; CB 1 + DB $70 ; SB +; 1710: type = BYTE_TYPE + DB $2A,$02 ; CB 2 + DB $74,$07 ; SLB 7 +; 1711: is INT_TKN + DB $50,C0400 ; SKIP C0400 +C0404: + DB $2A,$C9 ; CB 201 + DB $3E,C0405 ; SKPNE C0405 +; 1712: *valptr = constval + DB $66,$02 ; LLW 2 + DB $6A,D0370 ; LAW D0370 + DB $72 ; SW +; 1713: ^sizeptr = 2 + DB $66,$04 ; LLW 4 + DB $2A,$02 ; CB 2 + DB $70 ; SB +; 1714: type = WORD_TYPE + DB $2A,$04 ; CB 4 + DB $74,$07 ; SLB 7 +; 1715: is ID_TKN + DB $50,C0400 ; SKIP C0400 +C0405: + DB $2A,$D6 ; CB 214 + DB $3E,C0406 ; SKPNE C0406 +; 1716: ^sizeptr = 2 + DB $66,$04 ; LLW 4 + DB $2A,$02 ; CB 2 + DB $70 ; SB +; 1717: idptr = id_lookup_21(tknptr, tknlen) + DB $6A,D0368 ; LAW D0368 + DB $68,D0365 ; LAB D0365 + DB $54,C0337 ; CALL C0337 + DB $76,$08 ; SLW 8 +; 1718: if !idptr + DB $66,$08 ; LLW 8 + DB $20 ; NOT + DB $4C,C0407 ; SKPFLS C0407 +; 1719: return parse_err_11(@bad_cnst) + DB $30 ; DROP + DB $26,D0425 ; LA D0425 + DB $54,C0058 ; CALL C0058 + DB $5A ; LEAVE +; 1720: fin +C0407: +C0408: +; 1721: type = (idptr).idtype + DB $66,$08 ; LLW 8 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $60 ; LB + DB $74,$07 ; SLB 7 +; 1722: *valptr = (idptr):idval + DB $66,$02 ; LLW 2 + DB $66,$08 ; LLW 8 + DB $62 ; LW + DB $72 ; SW +; 1723: if type & VAR_TYPE and !(mod & 8) + DB $64,$07 ; LLB 7 + DB $2A,$06 ; CB 6 + DB $14 ; BAND + DB $64,$06 ; LLB 6 + DB $2A,$08 ; CB 8 + DB $14 ; BAND + DB $20 ; NOT + DB $24 ; LAND + DB $4C,C0409 ; SKPFLS C0409 +; 1724: return parse_err_11(@bad_cnst) + DB $30 ; DROP + DB $26,D0425 ; LA D0425 + DB $54,C0058 ; CALL C0058 + DB $5A ; LEAVE +; 1725: fin +C0409: +C0410: +; 1726: otherwise + DB $50,C0400 ; SKIP C0400 +C0406: +; 1727: return parse_err_11(@bad_cnst) + DB $30 ; DROP + DB $26,D0425 ; LA D0425 + DB $54,C0058 ; CALL C0058 + DB $5A ; LEAVE +; 1728: wend +C0400: + DB $30 ; DROP +; 1729: if mod & 1 + DB $64,$06 ; LLB 6 + DB $2A,$01 ; CB 1 + DB $14 ; BAND + DB $4C,C0412 ; SKPFLS C0412 +; 1730: *valptr = -*valptr + DB $66,$02 ; LLW 2 + DB $66,$02 ; LLW 2 + DB $62 ; LW + DB $10 ; NEG + DB $72 ; SW +; 1731: fin +C0412: +C0413: +; 1732: if mod & 2 + DB $64,$06 ; LLB 6 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C0414 ; SKPFLS C0414 +; 1733: *valptr = #*valptr + DB $66,$02 ; LLW 2 + DB $66,$02 ; LLW 2 + DB $62 ; LW + DB $12 ; COMP + DB $72 ; SW +; 1734: fin +C0414: +C0415: +; 1735: if mod & 4 + DB $64,$06 ; LLB 6 + DB $2A,$04 ; CB 4 + DB $14 ; BAND + DB $4C,C0416 ; SKPFLS C0416 +; 1736: *valptr = !*valptr + DB $66,$02 ; LLW 2 + DB $66,$02 ; LLW 2 + DB $62 ; LW + DB $20 ; NOT + DB $72 ; SW +; 1737: fin +C0416: +C0417: +; 1738: return type + DB $64,$07 ; LLB 7 + DB $5A ; LEAVE +; 1739: end +; 1740: def ispostop_01 +C0418: ; ispostop_01() +; 1741: when token + JSR _INTERP + DB $68,D0364 ; LAB D0364 +; 1742: is OPEN_PAREN_TKN + DB $2A,$A8 ; CB 168 + DB $3E,C0421 ; SKPNE C0421 +; 1743: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5C ; RET +; 1744: is OPEN_BRACKET_TKN + DB $50,C0420 ; SKIP C0420 +C0421: + DB $2A,$DB ; CB 219 + DB $3E,C0422 ; SKPNE C0422 +; 1745: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5C ; RET +; 1746: is DOT_TKN + DB $50,C0420 ; SKIP C0420 +C0422: + DB $2A,$AE ; CB 174 + DB $3E,C0423 ; SKPNE C0423 +; 1747: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5C ; RET +; 1748: is COLON_TKN + DB $50,C0420 ; SKIP C0420 +C0423: + DB $2A,$BA ; CB 186 + DB $3E,C0424 ; SKPNE C0424 +; 1749: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5C ; RET +; 1750: wend + DB $50,C0420 ; SKIP C0420 +C0424: +C0420: + DB $30 ; DROP +; 1751: return FALSE + DB $00 ; ZERO + DB $5C ; RET +; 1752: end +; 1753: def parse_value_11(rvalue) +C0426: ; parse_value_11() + ; rvalue = 2 +; 1754: byte cparams, deref, type, emit_val + ; cparams = 4 + ; deref = 5 + ; type = 6 + ; emit_val = 7 +; 1755: word optos, idptr, value + ; optos = 8 + ; idptr = 10 + ; value = 12 +; 1756: byte elem_type, elem_size + ; elem_type = 14 + ; elem_size = 15 +; 1757: word elem_offset + ; elem_offset = 16 +; 1758: +; 1759: deref = rvalue + JSR _INTERP + DB $58,$12,$01 ; ENTER 18,1 + DB $66,$02 ; LLW 2 + DB $74,$05 ; SLB 5 +; 1760: optos = opsp + DB $6A,D0362 ; LAW D0362 + DB $76,$08 ; SLW 8 +; 1761: type = 0 + DB $00 ; ZERO + DB $74,$06 ; SLB 6 +; 1762: emit_val = 0 + DB $00 ; ZERO + DB $74,$07 ; SLB 7 +; 1763: value = 0 + DB $00 ; ZERO + DB $76,$0C ; SLW 12 +; 1764: +; 1765: ; +; 1766: ; Parse pre-ops +; 1767: ; +; 1768: while !parse_term_01() +C0428: + DB $54,C0377 ; CALL C0377 + DB $20 ; NOT + DB $4C,C0429 ; SKPFLS C0429 +; 1769: when token + DB $68,D0364 ; LAB D0364 +; 1770: is ADD_TKN + DB $2A,$AB ; CB 171 + DB $3E,C0431 ; SKPNE C0431 +; 1771: is BPTR_TKN + DB $50,C0430 ; SKIP C0430 +C0431: + DB $2A,$DE ; CB 222 + DB $3E,C0432 ; SKPNE C0432 +; 1772: if deref + DB $64,$05 ; LLB 5 + DB $4C,C0433 ; SKPFLS C0433 +; 1773: drop push_op_21(token, 0) + DB $68,D0364 ; LAB D0364 + DB $00 ; ZERO + DB $54,C0309 ; CALL C0309 + DB $30 ; DROP +; 1774: else + DB $50,C0434 ; SKIP C0434 +C0433: +; 1775: type = type ? BPTR_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$20 ; CB 32 + DB $16 ; IOR + DB $74,$06 ; SLB 6 +; 1776: deref = deref + 1 + DB $64,$05 ; LLB 5 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $74,$05 ; SLB 5 +; 1777: fin +C0434: +; 1778: is WPTR_TKN + DB $50,C0430 ; SKIP C0430 +C0432: + DB $2A,$AA ; CB 170 + DB $3E,C0435 ; SKPNE C0435 +; 1779: if deref + DB $64,$05 ; LLB 5 + DB $4C,C0436 ; SKPFLS C0436 +; 1780: drop push_op_21(token, 0) + DB $68,D0364 ; LAB D0364 + DB $00 ; ZERO + DB $54,C0309 ; CALL C0309 + DB $30 ; DROP +; 1781: else + DB $50,C0437 ; SKIP C0437 +C0436: +; 1782: type = type ? WPTR_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$40 ; CB 64 + DB $16 ; IOR + DB $74,$06 ; SLB 6 +; 1783: deref = deref + 1 + DB $64,$05 ; LLB 5 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $74,$05 ; SLB 5 +; 1784: fin +C0437: +; 1785: is AT_TKN + DB $50,C0430 ; SKIP C0430 +C0435: + DB $2A,$C0 ; CB 192 + DB $3E,C0438 ; SKPNE C0438 +; 1786: deref = deref - 1 + DB $64,$05 ; LLB 5 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $74,$05 ; SLB 5 +; 1787: is SUB_TKN + DB $50,C0430 ; SKIP C0430 +C0438: + DB $2A,$AD ; CB 173 + DB $3E,C0439 ; SKPNE C0439 +; 1788: drop push_op_21(token, 0) + DB $68,D0364 ; LAB D0364 + DB $00 ; ZERO + DB $54,C0309 ; CALL C0309 + DB $30 ; DROP +; 1789: is COMP_TKN + DB $50,C0430 ; SKIP C0430 +C0439: + DB $2A,$A3 ; CB 163 + DB $3E,C0440 ; SKPNE C0440 +; 1790: drop push_op_21(token, 0) + DB $68,D0364 ; LAB D0364 + DB $00 ; ZERO + DB $54,C0309 ; CALL C0309 + DB $30 ; DROP +; 1791: is LOGIC_NOT_TKN + DB $50,C0430 ; SKIP C0430 +C0440: + DB $2A,$A1 ; CB 161 + DB $3E,C0441 ; SKPNE C0441 +; 1792: drop push_op_21(token, 0) + DB $68,D0364 ; LAB D0364 + DB $00 ; ZERO + DB $54,C0309 ; CALL C0309 + DB $30 ; DROP +; 1793: otherwise + DB $50,C0430 ; SKIP C0430 +C0441: +; 1794: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 1795: wend +C0430: + DB $30 ; DROP +; 1796: loop + DB $50,C0428 ; SKIP C0428 +C0429: +; 1797: ; +; 1798: ; Determine terminal type +; 1799: ; +; 1800: when token + DB $68,D0364 ; LAB D0364 +; 1801: is INT_TKN + DB $2A,$C9 ; CB 201 + DB $3E,C0444 ; SKPNE C0444 +; 1802: type = type ? CONST_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$01 ; CB 1 + DB $16 ; IOR + DB $74,$06 ; SLB 6 +; 1803: value = constval + DB $6A,D0370 ; LAW D0370 + DB $76,$0C ; SLW 12 +; 1804: is CHR_TKN + DB $50,C0443 ; SKIP C0443 +C0444: + DB $2A,$C3 ; CB 195 + DB $3E,C0445 ; SKPNE C0445 +; 1805: type = type ? CONST_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$01 ; CB 1 + DB $16 ; IOR + DB $74,$06 ; SLB 6 +; 1806: value = constval + DB $6A,D0370 ; LAW D0370 + DB $76,$0C ; SLW 12 +; 1807: is ID_TKN + DB $50,C0443 ; SKIP C0443 +C0445: + DB $2A,$D6 ; CB 214 + DB $3E,C0446 ; SKPNE C0446 +; 1808: idptr = id_lookup_21(tknptr, tknlen) + DB $6A,D0368 ; LAW D0368 + DB $68,D0365 ; LAB D0365 + DB $54,C0337 ; CALL C0337 + DB $76,$0A ; SLW 10 +; 1809: if !idptr + DB $66,$0A ; LLW 10 + DB $20 ; NOT + DB $4C,C0447 ; SKPFLS C0447 +; 1810: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 1811: fin +C0447: +C0448: +; 1812: if !(idptr).idtype + DB $66,$0A ; LLW 10 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $60 ; LB + DB $20 ; NOT + DB $4C,C0449 ; SKPFLS C0449 +; 1813: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 1814: fin +C0449: +C0450: +; 1815: type = type ? (idptr).idtype + DB $64,$06 ; LLB 6 + DB $66,$0A ; LLW 10 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $60 ; LB + DB $16 ; IOR + DB $74,$06 ; SLB 6 +; 1816: value = (idptr):idval + DB $66,$0A ; LLW 10 + DB $62 ; LW + DB $76,$0C ; SLW 12 +; 1817: is CLOSE_PAREN_TKN + DB $50,C0443 ; SKIP C0443 +C0446: + DB $2A,$A9 ; CB 169 + DB $3E,C0451 ; SKPNE C0451 +; 1818: type = type ? WORD_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$04 ; CB 4 + DB $16 ; IOR + DB $74,$06 ; SLB 6 +; 1819: emit_val = 1 + DB $2A,$01 ; CB 1 + DB $74,$07 ; SLB 7 +; 1820: otherwise + DB $50,C0443 ; SKIP C0443 +C0451: +; 1821: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 1822: wend +C0443: + DB $30 ; DROP +; 1823: ; +; 1824: ; Constant optimizations +; 1825: ; +; 1826: if type & CONST_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$01 ; CB 1 + DB $14 ; BAND + DB $4C,C0453 ; SKPFLS C0453 +; 1827: cparams = TRUE + DB $2C,$FF,$FF ; CW -1 + DB $74,$04 ; SLB 4 +; 1828: while optos < opsp and cparams +C0455: + DB $66,$08 ; LLW 8 + DB $6A,D0362 ; LAW D0362 + DB $46 ; ISLT + DB $64,$04 ; LLB 4 + DB $24 ; LAND + DB $4C,C0456 ; SKPFLS C0456 +; 1829: when tos_op_01() + DB $54,C0317 ; CALL C0317 +; 1830: is NEG_TKN + DB $2A,$AD ; CB 173 + DB $3E,C0458 ; SKPNE C0458 +; 1831: drop pop_op_01() + DB $54,C0313 ; CALL C0313 + DB $30 ; DROP +; 1832: value = -value + DB $66,$0C ; LLW 12 + DB $10 ; NEG + DB $76,$0C ; SLW 12 +; 1833: is COMP_TKN + DB $50,C0457 ; SKIP C0457 +C0458: + DB $2A,$A3 ; CB 163 + DB $3E,C0459 ; SKPNE C0459 +; 1834: drop pop_op_01() + DB $54,C0313 ; CALL C0313 + DB $30 ; DROP +; 1835: value = #value + DB $66,$0C ; LLW 12 + DB $12 ; COMP + DB $76,$0C ; SLW 12 +; 1836: is LOGIC_NOT_TKN + DB $50,C0457 ; SKIP C0457 +C0459: + DB $2A,$A1 ; CB 161 + DB $3E,C0460 ; SKPNE C0460 +; 1837: drop pop_op_01() + DB $54,C0313 ; CALL C0313 + DB $30 ; DROP +; 1838: value = !value + DB $66,$0C ; LLW 12 + DB $20 ; NOT + DB $76,$0C ; SLW 12 +; 1839: otherwise + DB $50,C0457 ; SKIP C0457 +C0460: +; 1840: cparams = FALSE + DB $00 ; ZERO + DB $74,$04 ; SLB 4 +; 1841: wend +C0457: + DB $30 ; DROP +; 1842: loop + DB $50,C0455 ; SKIP C0455 +C0456: +; 1843: fin +C0453: +C0454: +; 1844: ; +; 1845: ; Parse post-ops +; 1846: ; +; 1847: drop scan_01() + DB $54,C0248 ; CALL C0248 + DB $30 ; DROP +; 1848: while ispostop_01() +C0462: + DB $54,C0418 ; CALL C0418 + DB $4C,C0463 ; SKPFLS C0463 +; 1849: if token == OPEN_BRACKET_TKN + DB $68,D0364 ; LAB D0364 + DB $2A,$DB ; CB 219 + DB $40 ; ISEQ + DB $4C,C0464 ; SKPFLS C0464 +; 1850: ; +; 1851: ; Array +; 1852: ; +; 1853: if !emit_val + DB $64,$07 ; LLB 7 + DB $20 ; NOT + DB $4C,C0466 ; SKPFLS C0466 +; 1854: if type & ADDR_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$0E ; CB 14 + DB $14 ; BAND + DB $4C,C0468 ; SKPFLS C0468 +; 1855: if type & LOCAL_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$10 ; CB 16 + DB $14 ; BAND + DB $4C,C0470 ; SKPFLS C0470 +; 1856: emit_localaddr_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0152 ; CALL C0152 +; 1857: else + DB $50,C0471 ; SKIP C0471 +C0470: +; 1858: emit_globaladdr_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0154 ; CALL C0154 +; 1859: fin +C0471: +; 1860: elsif type & CONST_TYPE + DB $50,C0469 ; SKIP C0469 +C0468: + DB $64,$06 ; LLB 6 + DB $2A,$01 ; CB 1 + DB $14 ; BAND + DB $4C,C0472 ; SKPFLS C0472 +; 1861: emit_const_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0105 ; CALL C0105 +; 1862: fin +C0472: +C0469: +; 1863: emit_val = 1 + DB $2A,$01 ; CB 1 + DB $74,$07 ; SLB 7 +; 1864: fin ; !emit_val +C0466: +C0467: +; 1865: if type & PTR_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$60 ; CB 96 + DB $14 ; BAND + DB $4C,C0473 ; SKPFLS C0473 +; 1866: emit_lw() + DB $54,C0112 ; CALL C0112 +; 1867: fin +C0473: +C0474: +; 1868: if !parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $20 ; NOT + DB $4C,C0475 ; SKPFLS C0475 +; 1869: return 0 + DB $00 ; ZERO + DB $5A ; LEAVE +; 1870: fin +C0475: +C0476: +; 1871: if token <> CLOSE_BRACKET_TKN + DB $68,D0364 ; LAB D0364 + DB $2A,$DD ; CB 221 + DB $42 ; ISNE + DB $4C,C0477 ; SKPFLS C0477 +; 1872: return parse_err_11(@no_close_bracket) + DB $26,D0686 ; LA D0686 + DB $54,C0058 ; CALL C0058 + DB $5A ; LEAVE +; 1873: fin +C0477: +C0478: +; 1874: if type & WORD_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$04 ; CB 4 + DB $14 ; BAND + DB $4C,C0479 ; SKPFLS C0479 +; 1875: type = WPTR_TYPE + DB $2A,$40 ; CB 64 + DB $74,$06 ; SLB 6 +; 1876: emit_indexword() + DB $54,C0158 ; CALL C0158 +; 1877: else + DB $50,C0480 ; SKIP C0480 +C0479: +; 1878: type = BPTR_TYPE + DB $2A,$20 ; CB 32 + DB $74,$06 ; SLB 6 +; 1879: emit_indexbyte() + DB $54,C0156 ; CALL C0156 +; 1880: fin +C0480: +; 1881: drop scan_01() + DB $54,C0248 ; CALL C0248 + DB $30 ; DROP +; 1882: elsif token == DOT_TKN or token == COLON_TKN + DB $50,C0465 ; SKIP C0465 +C0464: + DB $68,D0364 ; LAB D0364 + DB $2A,$AE ; CB 174 + DB $40 ; ISEQ + DB $68,D0364 ; LAB D0364 + DB $2A,$BA ; CB 186 + DB $40 ; ISEQ + DB $22 ; LOR + DB $4C,C0481 ; SKPFLS C0481 +; 1883: ; +; 1884: ; Dot and Colon +; 1885: ; +; 1886: if token == DOT_TKN + DB $68,D0364 ; LAB D0364 + DB $2A,$AE ; CB 174 + DB $40 ; ISEQ + DB $4C,C0482 ; SKPFLS C0482 +; 1887: elem_type = BPTR_TYPE + DB $2A,$20 ; CB 32 + DB $74,$0E ; SLB 14 +; 1888: else + DB $50,C0483 ; SKIP C0483 +C0482: +; 1889: elem_type = WPTR_TYPE + DB $2A,$40 ; CB 64 + DB $74,$0E ; SLB 14 +; 1890: fin +C0483: +; 1891: if parse_constval_21(@elem_offset, @elem_size) + DB $28,$10 ; LLA 16 + DB $28,$0F ; LLA 15 + DB $54,C0390 ; CALL C0390 + DB $4C,C0484 ; SKPFLS C0484 +; 1892: ; +; 1893: ; Constant structure offset +; 1894: ; +; 1895: if !emit_val + DB $64,$07 ; LLB 7 + DB $20 ; NOT + DB $4C,C0486 ; SKPFLS C0486 +; 1896: if type & VAR_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$06 ; CB 6 + DB $14 ; BAND + DB $4C,C0488 ; SKPFLS C0488 +; 1897: if type & LOCAL_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$10 ; CB 16 + DB $14 ; BAND + DB $4C,C0490 ; SKPFLS C0490 +; 1898: emit_localaddr_10(value + elem_offset) + DB $66,$0C ; LLW 12 + DB $66,$10 ; LLW 16 + DB $02 ; ADD + DB $54,C0152 ; CALL C0152 +; 1899: else + DB $50,C0491 ; SKIP C0491 +C0490: +; 1900: ; emit_globaladdr_10(value + elem_offset) +; 1901: emit_globaladdr_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0154 ; CALL C0154 +; 1902: emit_const_10(elem_offset) + DB $66,$10 ; LLW 16 + DB $54,C0105 ; CALL C0105 +; 1903: drop emit_binaryop_11(ADD_TKN) + DB $2A,$AB ; CB 171 + DB $54,C0171 ; CALL C0171 + DB $30 ; DROP +; 1904: fin +C0491: +; 1905: elsif type & CONST_TYPE + DB $50,C0489 ; SKIP C0489 +C0488: + DB $64,$06 ; LLB 6 + DB $2A,$01 ; CB 1 + DB $14 ; BAND + DB $4C,C0492 ; SKPFLS C0492 +; 1906: value = value + elem_offset + DB $66,$0C ; LLW 12 + DB $66,$10 ; LLW 16 + DB $02 ; ADD + DB $76,$0C ; SLW 12 +; 1907: emit_const_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0105 ; CALL C0105 +; 1908: else ; FUNC_TYPE + DB $50,C0489 ; SKIP C0489 +C0492: +; 1909: emit_globaladdr_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0154 ; CALL C0154 +; 1910: emit_const_10(elem_offset) + DB $66,$10 ; LLW 16 + DB $54,C0105 ; CALL C0105 +; 1911: drop emit_binaryop_11(ADD_TKN) + DB $2A,$AB ; CB 171 + DB $54,C0171 ; CALL C0171 + DB $30 ; DROP +; 1912: fin +C0489: +; 1913: emit_val = 1 + DB $2A,$01 ; CB 1 + DB $74,$07 ; SLB 7 +; 1914: else + DB $50,C0487 ; SKIP C0487 +C0486: +; 1915: if elem_offset <> 0 + DB $66,$10 ; LLW 16 + DB $00 ; ZERO + DB $42 ; ISNE + DB $4C,C0493 ; SKPFLS C0493 +; 1916: emit_const_10(elem_offset) + DB $66,$10 ; LLW 16 + DB $54,C0105 ; CALL C0105 +; 1917: drop emit_binaryop_11(ADD_TKN) + DB $2A,$AB ; CB 171 + DB $54,C0171 ; CALL C0171 + DB $30 ; DROP +; 1918: fin +C0493: +C0494: +; 1919: fin ; !emit_val +C0487: +; 1920: drop scan_01() + DB $54,C0248 ; CALL C0248 + DB $30 ; DROP +; 1921: elsif token == OPEN_BRACKET_TKN + DB $50,C0485 ; SKIP C0485 +C0484: + DB $68,D0364 ; LAB D0364 + DB $2A,$DB ; CB 219 + DB $40 ; ISEQ + DB $4C,C0495 ; SKPFLS C0495 +; 1922: ; +; 1923: ; Array of arrays +; 1924: ; +; 1925: if !emit_val + DB $64,$07 ; LLB 7 + DB $20 ; NOT + DB $4C,C0496 ; SKPFLS C0496 +; 1926: if type & ADDR_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$0E ; CB 14 + DB $14 ; BAND + DB $4C,C0498 ; SKPFLS C0498 +; 1927: if type & LOCAL_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$10 ; CB 16 + DB $14 ; BAND + DB $4C,C0500 ; SKPFLS C0500 +; 1928: emit_localaddr_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0152 ; CALL C0152 +; 1929: else + DB $50,C0501 ; SKIP C0501 +C0500: +; 1930: emit_globaladdr_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0154 ; CALL C0154 +; 1931: fin +C0501: +; 1932: elsif type & CONST_TYPE + DB $50,C0499 ; SKIP C0499 +C0498: + DB $64,$06 ; LLB 6 + DB $2A,$01 ; CB 1 + DB $14 ; BAND + DB $4C,C0502 ; SKPFLS C0502 +; 1933: emit_const_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0105 ; CALL C0105 +; 1934: fin +C0502: +C0499: +; 1935: emit_val = 1 + DB $2A,$01 ; CB 1 + DB $74,$07 ; SLB 7 +; 1936: fin ; !emit_val +C0496: +C0497: +; 1937: repeat +C0504: +; 1938: if emit_val > 1 + DB $64,$07 ; LLB 7 + DB $2A,$01 ; CB 1 + DB $44 ; ISGT + DB $4C,C0505 ; SKPFLS C0505 +; 1939: emit_indexword() + DB $54,C0158 ; CALL C0158 +; 1940: emit_lw() + DB $54,C0112 ; CALL C0112 +; 1941: fin +C0505: +C0506: +; 1942: emit_val = emit_val + 1 + DB $64,$07 ; LLB 7 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $74,$07 ; SLB 7 +; 1943: if !parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $20 ; NOT + DB $4C,C0507 ; SKPFLS C0507 +; 1944: return parse_err_11(@bad_expr) + DB $26,D0499 ; LA D0499 + DB $54,C0058 ; CALL C0058 + DB $5A ; LEAVE +; 1945: fin +C0507: +C0508: +; 1946: if token <> CLOSE_BRACKET_TKN + DB $68,D0364 ; LAB D0364 + DB $2A,$DD ; CB 221 + DB $42 ; ISNE + DB $4C,C0509 ; SKPFLS C0509 +; 1947: return parse_err_11(@no_close_bracket) + DB $26,D0686 ; LA D0686 + DB $54,C0058 ; CALL C0058 + DB $5A ; LEAVE +; 1948: fin +C0509: +C0510: +; 1949: until scan_01() <> OPEN_BRACKET_TKN + DB $54,C0248 ; CALL C0248 + DB $2A,$DB ; CB 219 + DB $42 ; ISNE + DB $4C,C0504 ; SKPFLS C0504 +C0503: +; 1950: if elem_type & WPTR_TYPE + DB $64,$0E ; LLB 14 + DB $2A,$40 ; CB 64 + DB $14 ; BAND + DB $4C,C0511 ; SKPFLS C0511 +; 1951: emit_indexword() + DB $54,C0158 ; CALL C0158 +; 1952: else + DB $50,C0512 ; SKIP C0512 +C0511: +; 1953: emit_indexbyte() + DB $54,C0156 ; CALL C0156 +; 1954: fin +C0512: +; 1955: else + DB $50,C0485 ; SKIP C0485 +C0495: +; 1956: return parse_err_11(@bad_offset) + DB $26,D0438 ; LA D0438 + DB $54,C0058 ; CALL C0058 + DB $5A ; LEAVE +; 1957: fin +C0485: +; 1958: type = elem_type + DB $64,$0E ; LLB 14 + DB $74,$06 ; SLB 6 +; 1959: elsif token == OPEN_PAREN_TKN + DB $50,C0465 ; SKIP C0465 +C0481: + DB $68,D0364 ; LAB D0364 + DB $2A,$A8 ; CB 168 + DB $40 ; ISEQ + DB $4C,C0513 ; SKPFLS C0513 +; 1960: ; +; 1961: ; Function call +; 1962: ; +; 1963: if !emit_val and type & VAR_TYPE + DB $64,$07 ; LLB 7 + DB $20 ; NOT + DB $64,$06 ; LLB 6 + DB $2A,$06 ; CB 6 + DB $14 ; BAND + DB $24 ; LAND + DB $4C,C0514 ; SKPFLS C0514 +; 1964: if type & LOCAL_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$10 ; CB 16 + DB $14 ; BAND + DB $4C,C0516 ; SKPFLS C0516 +; 1965: emit_localaddr_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0152 ; CALL C0152 +; 1966: else + DB $50,C0517 ; SKIP C0517 +C0516: +; 1967: emit_globaladdr_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0154 ; CALL C0154 +; 1968: fin +C0517: +; 1969: fin +C0514: +C0515: +; 1970: if !(type & FUNC_CONST_TYPE) + DB $64,$06 ; LLB 6 + DB $2A,$09 ; CB 9 + DB $14 ; BAND + DB $20 ; NOT + DB $4C,C0518 ; SKPFLS C0518 +; 1971: emit_push() + DB $54,C0146 ; CALL C0146 +; 1972: fin +C0518: +C0519: +; 1973: drop parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $30 ; DROP +; 1974: if token <> CLOSE_PAREN_TKN + DB $68,D0364 ; LAB D0364 + DB $2A,$A9 ; CB 169 + DB $42 ; ISNE + DB $4C,C0520 ; SKPFLS C0520 +; 1975: return parse_err_11(@no_close_paren) + DB $26,D0664 ; LA D0664 + DB $54,C0058 ; CALL C0058 + DB $5A ; LEAVE +; 1976: fin +C0520: +C0521: +; 1977: if type & FUNC_CONST_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$09 ; CB 9 + DB $14 ; BAND + DB $4C,C0522 ; SKPFLS C0522 +; 1978: emit_call_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0142 ; CALL C0142 +; 1979: else + DB $50,C0523 ; SKIP C0523 +C0522: +; 1980: emit_pull() + DB $54,C0148 ; CALL C0148 +; 1981: emit_ical() + DB $54,C0144 ; CALL C0144 +; 1982: fin +C0523: +; 1983: emit_val = 1 + DB $2A,$01 ; CB 1 + DB $74,$07 ; SLB 7 +; 1984: type = WORD_TYPE + DB $2A,$04 ; CB 4 + DB $74,$06 ; SLB 6 +; 1985: drop scan_01() + DB $54,C0248 ; CALL C0248 + DB $30 ; DROP +; 1986: fin +C0513: +C0465: +; 1987: loop + DB $50,C0462 ; SKIP C0462 +C0463: +; 1988: if emit_val + DB $64,$07 ; LLB 7 + DB $4C,C0524 ; SKPFLS C0524 +; 1989: if rvalue + DB $66,$02 ; LLW 2 + DB $4C,C0526 ; SKPFLS C0526 +; 1990: if deref and type & PTR_TYPE + DB $64,$05 ; LLB 5 + DB $64,$06 ; LLB 6 + DB $2A,$60 ; CB 96 + DB $14 ; BAND + DB $24 ; LAND + DB $4C,C0528 ; SKPFLS C0528 +; 1991: if type & BPTR_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$20 ; CB 32 + DB $14 ; BAND + DB $4C,C0530 ; SKPFLS C0530 +; 1992: emit_lb() + DB $54,C0110 ; CALL C0110 +; 1993: else + DB $50,C0531 ; SKIP C0531 +C0530: +; 1994: emit_lw() + DB $54,C0112 ; CALL C0112 +; 1995: fin +C0531: +; 1996: fin +C0528: +C0529: +; 1997: fin +C0526: +C0527: +; 1998: else ; emit_val + DB $50,C0525 ; SKIP C0525 +C0524: +; 1999: if type & CONST_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$01 ; CB 1 + DB $14 ; BAND + DB $4C,C0532 ; SKPFLS C0532 +; 2000: emit_const_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0105 ; CALL C0105 +; 2001: elsif deref + DB $50,C0533 ; SKIP C0533 +C0532: + DB $64,$05 ; LLB 5 + DB $4C,C0534 ; SKPFLS C0534 +; 2002: if type & FUNC_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$08 ; CB 8 + DB $14 ; BAND + DB $4C,C0535 ; SKPFLS C0535 +; 2003: emit_call_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0142 ; CALL C0142 +; 2004: elsif type & VAR_TYPE + DB $50,C0536 ; SKIP C0536 +C0535: + DB $64,$06 ; LLB 6 + DB $2A,$06 ; CB 6 + DB $14 ; BAND + DB $4C,C0537 ; SKPFLS C0537 +; 2005: if type & LOCAL_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$10 ; CB 16 + DB $14 ; BAND + DB $4C,C0538 ; SKPFLS C0538 +; 2006: if type & BYTE_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C0540 ; SKPFLS C0540 +; 2007: emit_llb_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0114 ; CALL C0114 +; 2008: else + DB $50,C0541 ; SKIP C0541 +C0540: +; 2009: emit_llw_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0116 ; CALL C0116 +; 2010: fin +C0541: +; 2011: else + DB $50,C0539 ; SKIP C0539 +C0538: +; 2012: if type & BYTE_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C0542 ; SKPFLS C0542 +; 2013: emit_lab_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0118 ; CALL C0118 +; 2014: else + DB $50,C0543 ; SKIP C0543 +C0542: +; 2015: emit_law_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0120 ; CALL C0120 +; 2016: fin +C0543: +; 2017: fin +C0539: +; 2018: elsif type & PTR_TYPE + DB $50,C0536 ; SKIP C0536 +C0537: + DB $64,$06 ; LLB 6 + DB $2A,$60 ; CB 96 + DB $14 ; BAND + DB $4C,C0544 ; SKPFLS C0544 +; 2019: if type & BPTR_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$20 ; CB 32 + DB $14 ; BAND + DB $4C,C0545 ; SKPFLS C0545 +; 2020: emit_lb() + DB $54,C0110 ; CALL C0110 +; 2021: else + DB $50,C0546 ; SKIP C0546 +C0545: +; 2022: emit_lw() + DB $54,C0112 ; CALL C0112 +; 2023: fin +C0546: +; 2024: fin +C0544: +C0536: +; 2025: else + DB $50,C0533 ; SKIP C0533 +C0534: +; 2026: if type & LOCAL_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$10 ; CB 16 + DB $14 ; BAND + DB $4C,C0547 ; SKPFLS C0547 +; 2027: emit_localaddr_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0152 ; CALL C0152 +; 2028: else + DB $50,C0548 ; SKIP C0548 +C0547: +; 2029: emit_globaladdr_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0154 ; CALL C0154 +; 2030: fin +C0548: +; 2031: fin +C0533: +; 2032: fin ; emit_val +C0525: +; 2033: while optos < opsp +C0549: + DB $66,$08 ; LLW 8 + DB $6A,D0362 ; LAW D0362 + DB $46 ; ISLT + DB $4C,C0550 ; SKPFLS C0550 +; 2034: if !emit_unaryop_11(pop_op_01()) + DB $54,C0313 ; CALL C0313 + DB $54,C0160 ; CALL C0160 + DB $20 ; NOT + DB $4C,C0551 ; SKPFLS C0551 +; 2035: return parse_err_11(@bad_op) + DB $26,D0472 ; LA D0472 + DB $54,C0058 ; CALL C0058 + DB $5A ; LEAVE +; 2036: fin +C0551: +C0552: +; 2037: loop + DB $50,C0549 ; SKIP C0549 +C0550: +; 2038: return type + DB $64,$06 ; LLB 6 + DB $5A ; LEAVE +; 2039: end +; 2040: def parse_constexpr_21(valptr, sizeptr) +C0553: ; parse_constexpr_21() + ; valptr = 2 + ; sizeptr = 4 +; 2041: byte type, size1, size2 + ; type = 6 + ; size1 = 7 + ; size2 = 8 +; 2042: word val1, val2 + ; val1 = 9 + ; val2 = 11 +; 2043: +; 2044: type = parse_constval_21(@val1, @size1) + JSR _INTERP + DB $58,$0D,$02 ; ENTER 13,2 + DB $28,$09 ; LLA 9 + DB $28,$07 ; LLA 7 + DB $54,C0390 ; CALL C0390 + DB $74,$06 ; SLB 6 +; 2045: if !type + DB $64,$06 ; LLB 6 + DB $20 ; NOT + DB $4C,C0555 ; SKPFLS C0555 +; 2046: return 0 + DB $00 ; ZERO + DB $5A ; LEAVE +; 2047: fin +C0555: +C0556: +; 2048: size2 = 0 + DB $00 ; ZERO + DB $74,$08 ; SLB 8 +; 2049: when scan_01() + DB $54,C0248 ; CALL C0248 +; 2050: is ADD_TKN + DB $2A,$AB ; CB 171 + DB $3E,C0558 ; SKPNE C0558 +; 2051: type = parse_constval_21(@val2, @size2) + DB $28,$0B ; LLA 11 + DB $28,$08 ; LLA 8 + DB $54,C0390 ; CALL C0390 + DB $74,$06 ; SLB 6 +; 2052: if !type + DB $64,$06 ; LLB 6 + DB $20 ; NOT + DB $4C,C0559 ; SKPFLS C0559 +; 2053: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2054: fin +C0559: +C0560: +; 2055: *valptr = val1 + val2 + DB $66,$02 ; LLW 2 + DB $66,$09 ; LLW 9 + DB $66,$0B ; LLW 11 + DB $02 ; ADD + DB $72 ; SW +; 2056: is SUB_TKN + DB $50,C0557 ; SKIP C0557 +C0558: + DB $2A,$AD ; CB 173 + DB $3E,C0561 ; SKPNE C0561 +; 2057: type = parse_constval_21(@val2, @size2) + DB $28,$0B ; LLA 11 + DB $28,$08 ; LLA 8 + DB $54,C0390 ; CALL C0390 + DB $74,$06 ; SLB 6 +; 2058: if !type + DB $64,$06 ; LLB 6 + DB $20 ; NOT + DB $4C,C0562 ; SKPFLS C0562 +; 2059: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2060: fin +C0562: +C0563: +; 2061: *valptr = val1 - val2 + DB $66,$02 ; LLW 2 + DB $66,$09 ; LLW 9 + DB $66,$0B ; LLW 11 + DB $04 ; SUB + DB $72 ; SW +; 2062: is MUL_TKN + DB $50,C0557 ; SKIP C0557 +C0561: + DB $2A,$AA ; CB 170 + DB $3E,C0564 ; SKPNE C0564 +; 2063: type = parse_constval_21(@val2, @size2) + DB $28,$0B ; LLA 11 + DB $28,$08 ; LLA 8 + DB $54,C0390 ; CALL C0390 + DB $74,$06 ; SLB 6 +; 2064: if !type + DB $64,$06 ; LLB 6 + DB $20 ; NOT + DB $4C,C0565 ; SKPFLS C0565 +; 2065: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2066: fin +C0565: +C0566: +; 2067: *valptr = val1 * val2 + DB $66,$02 ; LLW 2 + DB $66,$09 ; LLW 9 + DB $66,$0B ; LLW 11 + DB $06 ; MUL + DB $72 ; SW +; 2068: is DIV_TKN + DB $50,C0557 ; SKIP C0557 +C0564: + DB $2A,$AF ; CB 175 + DB $3E,C0567 ; SKPNE C0567 +; 2069: type = parse_constval_21(@val2, @size2) + DB $28,$0B ; LLA 11 + DB $28,$08 ; LLA 8 + DB $54,C0390 ; CALL C0390 + DB $74,$06 ; SLB 6 +; 2070: if !type + DB $64,$06 ; LLB 6 + DB $20 ; NOT + DB $4C,C0568 ; SKPFLS C0568 +; 2071: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2072: fin +C0568: +C0569: +; 2073: *valptr = val1 + val2 + DB $66,$02 ; LLW 2 + DB $66,$09 ; LLW 9 + DB $66,$0B ; LLW 11 + DB $02 ; ADD + DB $72 ; SW +; 2074: is MOD_TKN + DB $50,C0557 ; SKIP C0557 +C0567: + DB $2A,$A5 ; CB 165 + DB $3E,C0570 ; SKPNE C0570 +; 2075: type = parse_constval_21(@val2, @size2) + DB $28,$0B ; LLA 11 + DB $28,$08 ; LLA 8 + DB $54,C0390 ; CALL C0390 + DB $74,$06 ; SLB 6 +; 2076: if !type + DB $64,$06 ; LLB 6 + DB $20 ; NOT + DB $4C,C0571 ; SKPFLS C0571 +; 2077: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2078: fin +C0571: +C0572: +; 2079: *valptr = val1 % val2 + DB $66,$02 ; LLW 2 + DB $66,$09 ; LLW 9 + DB $66,$0B ; LLW 11 + DB $0A ; DIV,MOD + DB $72 ; SW +; 2080: drop + DB $30 ; DROP +; 2081: is AND_TKN + DB $50,C0557 ; SKIP C0557 +C0570: + DB $2A,$A6 ; CB 166 + DB $3E,C0573 ; SKPNE C0573 +; 2082: type = parse_constval_21(@val2, @size2) + DB $28,$0B ; LLA 11 + DB $28,$08 ; LLA 8 + DB $54,C0390 ; CALL C0390 + DB $74,$06 ; SLB 6 +; 2083: if !type + DB $64,$06 ; LLB 6 + DB $20 ; NOT + DB $4C,C0574 ; SKPFLS C0574 +; 2084: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2085: fin +C0574: +C0575: +; 2086: *valptr = val1 & val2 + DB $66,$02 ; LLW 2 + DB $66,$09 ; LLW 9 + DB $66,$0B ; LLW 11 + DB $14 ; BAND + DB $72 ; SW +; 2087: is OR_TKN + DB $50,C0557 ; SKIP C0557 +C0573: + DB $2A,$BF ; CB 191 + DB $3E,C0576 ; SKPNE C0576 +; 2088: type = parse_constval_21(@val2, @size2) + DB $28,$0B ; LLA 11 + DB $28,$08 ; LLA 8 + DB $54,C0390 ; CALL C0390 + DB $74,$06 ; SLB 6 +; 2089: if !type + DB $64,$06 ; LLB 6 + DB $20 ; NOT + DB $4C,C0577 ; SKPFLS C0577 +; 2090: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2091: fin +C0577: +C0578: +; 2092: *valptr = val1 ? val2 + DB $66,$02 ; LLW 2 + DB $66,$09 ; LLW 9 + DB $66,$0B ; LLW 11 + DB $16 ; IOR + DB $72 ; SW +; 2093: is EOR_TKN + DB $50,C0557 ; SKIP C0557 +C0576: + DB $2A,$DE ; CB 222 + DB $3E,C0579 ; SKPNE C0579 +; 2094: type = parse_constval_21(@val2, @size2) + DB $28,$0B ; LLA 11 + DB $28,$08 ; LLA 8 + DB $54,C0390 ; CALL C0390 + DB $74,$06 ; SLB 6 +; 2095: if !type + DB $64,$06 ; LLB 6 + DB $20 ; NOT + DB $4C,C0580 ; SKPFLS C0580 +; 2096: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2097: fin +C0580: +C0581: +; 2098: *valptr = val1 ^ val2 + DB $66,$02 ; LLW 2 + DB $66,$09 ; LLW 9 + DB $66,$0B ; LLW 11 + DB $18 ; XOR + DB $72 ; SW +; 2099: otherwise + DB $50,C0557 ; SKIP C0557 +C0579: +; 2100: *valptr = val1 + DB $66,$02 ; LLW 2 + DB $66,$09 ; LLW 9 + DB $72 ; SW +; 2101: wend +C0557: + DB $30 ; DROP +; 2102: if size1 > size2 + DB $64,$07 ; LLB 7 + DB $64,$08 ; LLB 8 + DB $44 ; ISGT + DB $4C,C0583 ; SKPFLS C0583 +; 2103: ^sizeptr = size1 + DB $66,$04 ; LLW 4 + DB $64,$07 ; LLB 7 + DB $70 ; SB +; 2104: else + DB $50,C0584 ; SKIP C0584 +C0583: +; 2105: ^sizeptr = size2 + DB $66,$04 ; LLW 4 + DB $64,$08 ; LLB 8 + DB $70 ; SB +; 2106: fin +C0584: +; 2107: return type + DB $64,$06 ; LLB 6 + DB $5A ; LEAVE +; 2108: end +; 2109: def parse_expr_01 +C0000: ; parse_expr_01() +; 2110: byte prevmatch, matchop, i + ; prevmatch = 2 + ; matchop = 3 + ; i = 4 +; 2111: word optos + ; optos = 5 +; 2112: +; 2113: matchop = 0 + JSR _INTERP + DB $58,$07,$00 ; ENTER 7,0 + DB $00 ; ZERO + DB $74,$03 ; SLB 3 +; 2114: optos = opsp + DB $6A,D0362 ; LAW D0362 + DB $76,$05 ; SLW 5 +; 2115: repeat +C0587: +; 2116: prevmatch = matchop + DB $64,$03 ; LLB 3 + DB $74,$02 ; SLB 2 +; 2117: matchop = 0 + DB $00 ; ZERO + DB $74,$03 ; SLB 3 +; 2118: if parse_value_11(1) + DB $2A,$01 ; CB 1 + DB $54,C0426 ; CALL C0426 + DB $4C,C0588 ; SKPFLS C0588 +; 2119: matchop = 1 + DB $2A,$01 ; CB 1 + DB $74,$03 ; SLB 3 +; 2120: for i = 0 to bops_tblsz + DB $00 ; ZERO +C0591: + DB $6C,$04 ; DLB 4 + DB $2A,$12 ; CB 18 + DB $3A,C0590 ; SKPGT C0590 + DB $0C ; INCR +; 2121: if token == bops_tbl[i] + DB $68,D0364 ; LAB D0364 + DB $26,D0292 ; LA D0292 + DB $64,$04 ; LLB 4 + DB $02 ; IDXB + DB $60 ; LB + DB $40 ; ISEQ + DB $4C,C0592 ; SKPFLS C0592 +; 2122: matchop = 2 + DB $2A,$02 ; CB 2 + DB $74,$03 ; SLB 3 +; 2123: if bops_prec[i] >= tos_op_prec_11(optos) + DB $26,D0311 ; LA D0311 + DB $64,$04 ; LLB 4 + DB $02 ; IDXB + DB $60 ; LB + DB $66,$05 ; LLW 5 + DB $54,C0321 ; CALL C0321 + DB $48 ; ISGE + DB $4C,C0594 ; SKPFLS C0594 +; 2124: if !emit_binaryop_11(pop_op_01()) + DB $54,C0313 ; CALL C0313 + DB $54,C0171 ; CALL C0171 + DB $20 ; NOT + DB $4C,C0596 ; SKPFLS C0596 +; 2125: return parse_err_11(@bad_op) + DB $30 ; DROP + DB $26,D0472 ; LA D0472 + DB $54,C0058 ; CALL C0058 + DB $5A ; LEAVE +; 2126: fin +C0596: +C0597: +; 2127: fin +C0594: +C0595: +; 2128: drop push_op_21(token, bops_prec[i]) + DB $68,D0364 ; LAB D0364 + DB $26,D0311 ; LA D0311 + DB $64,$04 ; LLB 4 + DB $02 ; IDXB + DB $60 ; LB + DB $54,C0309 ; CALL C0309 + DB $30 ; DROP +; 2129: break + DB $50,C0590 ; SKIP C0590 +; 2130: fin +C0592: +C0593: +; 2131: next + DB $50,C0591 ; SKIP C0591 +C0590: + DB $30 ; DROP +; 2132: fin +C0588: +C0589: +; 2133: until matchop <> 2 + DB $64,$03 ; LLB 3 + DB $2A,$02 ; CB 2 + DB $42 ; ISNE + DB $4C,C0587 ; SKPFLS C0587 +C0586: +; 2134: if matchop == 0 and prevmatch == 2 + DB $64,$03 ; LLB 3 + DB $00 ; ZERO + DB $40 ; ISEQ + DB $64,$02 ; LLB 2 + DB $2A,$02 ; CB 2 + DB $40 ; ISEQ + DB $24 ; LAND + DB $4C,C0598 ; SKPFLS C0598 +; 2135: return parse_err_11(@missing_op) + DB $26,D0710 ; LA D0710 + DB $54,C0058 ; CALL C0058 + DB $5A ; LEAVE +; 2136: fin +C0598: +C0599: +; 2137: while optos < opsp +C0600: + DB $66,$05 ; LLW 5 + DB $6A,D0362 ; LAW D0362 + DB $46 ; ISLT + DB $4C,C0601 ; SKPFLS C0601 +; 2138: if !emit_binaryop_11(pop_op_01()) + DB $54,C0313 ; CALL C0313 + DB $54,C0171 ; CALL C0171 + DB $20 ; NOT + DB $4C,C0602 ; SKPFLS C0602 +; 2139: return parse_err_11(@bad_op) + DB $26,D0472 ; LA D0472 + DB $54,C0058 ; CALL C0058 + DB $5A ; LEAVE +; 2140: fin +C0602: +C0603: +; 2141: loop + DB $50,C0600 ; SKIP C0600 +C0601: +; 2142: return matchop or prevmatch + DB $64,$03 ; LLB 3 + DB $64,$02 ; LLB 2 + DB $22 ; LOR + DB $5A ; LEAVE +; 2143: end +; 2144: def parse_setlist_21(addr, type) +C0604: ; parse_setlist_21() + ; addr = 2 + ; type = 4 +; 2145: word nexttype, nextaddr, idptr, saveptr + ; nexttype = 6 + ; nextaddr = 8 + ; idptr = 10 + ; saveptr = 12 +; 2146: +; 2147: if !(type & VAR_TYPE) + JSR _INTERP + DB $58,$0E,$02 ; ENTER 14,2 + DB $66,$04 ; LLW 4 + DB $2A,$06 ; CB 6 + DB $14 ; BAND + DB $20 ; NOT + DB $4C,C0606 ; SKPFLS C0606 +; 2148: emit_push() + DB $54,C0146 ; CALL C0146 +; 2149: fin +C0606: +C0607: +; 2150: nexttype = 0 + DB $00 ; ZERO + DB $76,$06 ; SLW 6 +; 2151: nextaddr = 0 + DB $00 ; ZERO + DB $76,$08 ; SLW 8 +; 2152: if scan_01() == ID_TKN + DB $54,C0248 ; CALL C0248 + DB $2A,$D6 ; CB 214 + DB $40 ; ISEQ + DB $4C,C0608 ; SKPFLS C0608 +; 2153: idptr = id_lookup_21(tknptr, tknlen) + DB $6A,D0368 ; LAW D0368 + DB $68,D0365 ; LAB D0365 + DB $54,C0337 ; CALL C0337 + DB $76,$0A ; SLW 10 +; 2154: if !idptr + DB $66,$0A ; LLW 10 + DB $20 ; NOT + DB $4C,C0610 ; SKPFLS C0610 +; 2155: return FALSE + DB $00 ; ZERO + DB $5A ; LEAVE +; 2156: fin +C0610: +C0611: +; 2157: nexttype = (idptr).idtype + DB $66,$0A ; LLW 10 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $60 ; LB + DB $76,$06 ; SLW 6 +; 2158: if type & VAR_TYPE + DB $66,$04 ; LLW 4 + DB $2A,$06 ; CB 6 + DB $14 ; BAND + DB $4C,C0612 ; SKPFLS C0612 +; 2159: nextaddr = (idptr):idval + DB $66,$0A ; LLW 10 + DB $62 ; LW + DB $76,$08 ; SLW 8 +; 2160: fin +C0612: +C0613: +; 2161: fin +C0608: +C0609: +; 2162: saveptr = tknptr + DB $6A,D0368 ; LAW D0368 + DB $76,$0C ; SLW 12 +; 2163: drop scan_01() + DB $54,C0248 ; CALL C0248 + DB $30 ; DROP +; 2164: if nexttype & VAR_TYPE and token == SET_TKN + DB $66,$06 ; LLW 6 + DB $2A,$06 ; CB 6 + DB $14 ; BAND + DB $68,D0364 ; LAB D0364 + DB $2A,$BD ; CB 189 + DB $40 ; ISEQ + DB $24 ; LAND + DB $4C,C0614 ; SKPFLS C0614 +; 2165: drop parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $30 ; DROP +; 2166: if type & LOCAL_TYPE + DB $66,$04 ; LLW 4 + DB $2A,$10 ; CB 16 + DB $14 ; BAND + DB $4C,C0616 ; SKPFLS C0616 +; 2167: if type & BYTE_TYPE + DB $66,$04 ; LLW 4 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C0618 ; SKPFLS C0618 +; 2168: emit_slb_10(nextaddr) + DB $66,$08 ; LLW 8 + DB $54,C0126 ; CALL C0126 +; 2169: else + DB $50,C0619 ; SKIP C0619 +C0618: +; 2170: emit_slw_10(nextaddr) + DB $66,$08 ; LLW 8 + DB $54,C0128 ; CALL C0128 +; 2171: fin +C0619: +; 2172: else + DB $50,C0617 ; SKIP C0617 +C0616: +; 2173: if type & BYTE_TYPE + DB $66,$04 ; LLW 4 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C0620 ; SKPFLS C0620 +; 2174: emit_sab_10(nextaddr) + DB $66,$08 ; LLW 8 + DB $54,C0134 ; CALL C0134 +; 2175: else + DB $50,C0621 ; SKIP C0621 +C0620: +; 2176: emit_saw_10(nextaddr) + DB $66,$08 ; LLW 8 + DB $54,C0136 ; CALL C0136 +; 2177: fin +C0621: +; 2178: fin +C0617: +; 2179: elsif nexttype & VAR_TYPE and token == SETLIST_TKN + DB $50,C0615 ; SKIP C0615 +C0614: + DB $66,$06 ; LLW 6 + DB $2A,$06 ; CB 6 + DB $14 ; BAND + DB $68,D0364 ; LAB D0364 + DB $2A,$B9 ; CB 185 + DB $40 ; ISEQ + DB $24 ; LAND + DB $4C,C0622 ; SKPFLS C0622 +; 2180: if !parse_setlist_21(nextaddr, nexttype) + DB $66,$08 ; LLW 8 + DB $66,$06 ; LLW 6 + DB $54,C0604 ; CALL C0604 + DB $20 ; NOT + DB $4C,C0623 ; SKPFLS C0623 +; 2181: return FALSE + DB $00 ; ZERO + DB $5A ; LEAVE +; 2182: fin +C0623: +C0624: +; 2183: else + DB $50,C0615 ; SKIP C0615 +C0622: +; 2184: tknptr = saveptr + DB $66,$0C ; LLW 12 + DB $7A,D0368 ; SAW D0368 +; 2185: rewind_10(tknptr) + DB $6A,D0368 ; LAW D0368 + DB $54,C0301 ; CALL C0301 +; 2186: nexttype = parse_value_11(0) + DB $00 ; ZERO + DB $54,C0426 ; CALL C0426 + DB $76,$06 ; SLW 6 +; 2187: if nexttype <> 0 + DB $66,$06 ; LLW 6 + DB $00 ; ZERO + DB $42 ; ISNE + DB $4C,C0625 ; SKPFLS C0625 +; 2188: if token == SET_TKN + DB $68,D0364 ; LAB D0364 + DB $2A,$BD ; CB 189 + DB $40 ; ISEQ + DB $4C,C0627 ; SKPFLS C0627 +; 2189: emit_push() + DB $54,C0146 ; CALL C0146 +; 2190: drop parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $30 ; DROP +; 2191: emit_pull() + DB $54,C0148 ; CALL C0148 +; 2192: emit_swap() + DB $54,C0216 ; CALL C0216 +; 2193: if nexttype & (BYTE_TYPE ? BPTR_TYPE) + DB $66,$06 ; LLW 6 + DB $2A,$02 ; CB 2 + DB $2A,$20 ; CB 32 + DB $16 ; IOR + DB $14 ; BAND + DB $4C,C0629 ; SKPFLS C0629 +; 2194: emit_sb() + DB $54,C0122 ; CALL C0122 +; 2195: else + DB $50,C0630 ; SKIP C0630 +C0629: +; 2196: emit_sw() + DB $54,C0124 ; CALL C0124 +; 2197: fin +C0630: +; 2198: fin +C0627: +C0628: +; 2199: elsif token == SETLIST_TKN + DB $50,C0626 ; SKIP C0626 +C0625: + DB $68,D0364 ; LAB D0364 + DB $2A,$B9 ; CB 185 + DB $40 ; ISEQ + DB $4C,C0631 ; SKPFLS C0631 +; 2200: if !parse_setlist_21(0, nexttype) + DB $00 ; ZERO + DB $66,$06 ; LLW 6 + DB $54,C0604 ; CALL C0604 + DB $20 ; NOT + DB $4C,C0632 ; SKPFLS C0632 +; 2201: return FALSE + DB $00 ; ZERO + DB $5A ; LEAVE +; 2202: fin +C0632: +C0633: +; 2203: else + DB $50,C0626 ; SKIP C0626 +C0631: +; 2204: return parse_err_11(@bad_syntax) + DB $26,D0514 ; LA D0514 + DB $54,C0058 ; CALL C0058 + DB $5A ; LEAVE +; 2205: fin +C0626: +; 2206: fin +C0615: +; 2207: if type & VAR_TYPE + DB $66,$04 ; LLW 4 + DB $2A,$06 ; CB 6 + DB $14 ; BAND + DB $4C,C0634 ; SKPFLS C0634 +; 2208: if type & LOCAL_TYPE + DB $66,$04 ; LLW 4 + DB $2A,$10 ; CB 16 + DB $14 ; BAND + DB $4C,C0636 ; SKPFLS C0636 +; 2209: if type & BYTE_TYPE + DB $66,$04 ; LLW 4 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C0638 ; SKPFLS C0638 +; 2210: emit_slb_10(addr) + DB $66,$02 ; LLW 2 + DB $54,C0126 ; CALL C0126 +; 2211: else + DB $50,C0639 ; SKIP C0639 +C0638: +; 2212: emit_slw_10(addr) + DB $66,$02 ; LLW 2 + DB $54,C0128 ; CALL C0128 +; 2213: fin +C0639: +; 2214: else + DB $50,C0637 ; SKIP C0637 +C0636: +; 2215: if type & BYTE_TYPE + DB $66,$04 ; LLW 4 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C0640 ; SKPFLS C0640 +; 2216: emit_sab_10(addr) + DB $66,$02 ; LLW 2 + DB $54,C0134 ; CALL C0134 +; 2217: else + DB $50,C0641 ; SKIP C0641 +C0640: +; 2218: emit_saw_10(addr) + DB $66,$02 ; LLW 2 + DB $54,C0136 ; CALL C0136 +; 2219: fin +C0641: +; 2220: fin +C0637: +; 2221: else + DB $50,C0635 ; SKIP C0635 +C0634: +; 2222: emit_pull() + DB $54,C0148 ; CALL C0148 +; 2223: emit_swap() + DB $54,C0216 ; CALL C0216 +; 2224: if type & (BYTE_TYPE ? BPTR_TYPE) + DB $66,$04 ; LLW 4 + DB $2A,$02 ; CB 2 + DB $2A,$20 ; CB 32 + DB $16 ; IOR + DB $14 ; BAND + DB $4C,C0642 ; SKPFLS C0642 +; 2225: emit_sb() + DB $54,C0122 ; CALL C0122 +; 2226: else + DB $50,C0643 ; SKIP C0643 +C0642: +; 2227: emit_sw() + DB $54,C0124 ; CALL C0124 +; 2228: fin +C0643: +; 2229: fin +C0635: +; 2230: return TRUE + DB $2C,$FF,$FF ; CW -1 + DB $5A ; LEAVE +; 2231: end +; 2232: def parse_stmnt_01 +C0644: ; parse_stmnt_01() +; 2233: byte type, i + ; type = 2 + ; i = 3 +; 2234: word tag_prevbrk, tag_else, tag_endif, tag_while, tag_wend + ; tag_prevbrk = 4 + ; tag_else = 6 + ; tag_endif = 8 + ; tag_while = 10 + ; tag_wend = 12 +; 2235: word tag_repeat, tag_for, tag_choice, idptr, saveptr, addr, stepdir + ; tag_repeat = 14 + ; tag_for = 16 + ; tag_choice = 18 + ; idptr = 20 + ; saveptr = 22 + ; addr = 24 + ; stepdir = 26 +; 2236: +; 2237: if token <> END_TKN and token <> DONE_TKN + JSR _INTERP + DB $58,$1C,$00 ; ENTER 28,0 + DB $68,D0364 ; LAB D0364 + DB $2A,$87 ; CB 135 + DB $42 ; ISNE + DB $68,D0364 ; LAB D0364 + DB $2A,$98 ; CB 152 + DB $42 ; ISNE + DB $24 ; LAND + DB $4C,C0646 ; SKPFLS C0646 +; 2238: prevstmnt = token + DB $68,D0364 ; LAB D0364 + DB $78,D0904 ; SAB D0904 +; 2239: fin +C0646: +C0647: +; 2240: when token + DB $68,D0364 ; LAB D0364 +; 2241: is IF_TKN + DB $2A,$83 ; CB 131 + DB $3E,C0649 ; SKPNE C0649 +; 2242: drop parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $30 ; DROP +; 2243: tag_else = ctag_new_01() + DB $54,C0068 ; CALL C0068 + DB $76,$06 ; SLW 6 +; 2244: tag_endif = ctag_new_01() + DB $54,C0068 ; CALL C0068 + DB $76,$08 ; SLW 8 +; 2245: emit_brfls_10(tag_else) + DB $66,$06 ; LLW 6 + DB $54,C0204 ; CALL C0204 +; 2246: drop scan_01() + DB $54,C0248 ; CALL C0248 + DB $30 ; DROP +; 2247: repeat +C0651: +; 2248: while parse_stmnt_01() +C0652: + DB $54,C0644 ; CALL C0644 + DB $4C,C0653 ; SKPFLS C0653 +; 2249: drop nextln_01() + DB $54,C0303 ; CALL C0303 + DB $30 ; DROP +; 2250: loop + DB $50,C0652 ; SKIP C0652 +C0653: +; 2251: if token <> ELSEIF_TKN + DB $68,D0364 ; LAB D0364 + DB $2A,$84 ; CB 132 + DB $42 ; ISNE + DB $4C,C0654 ; SKPFLS C0654 +; 2252: break + DB $50,C0650 ; SKIP C0650 +; 2253: fin +C0654: +C0655: +; 2254: emit_jump_10(tag_endif) + DB $66,$08 ; LLW 8 + DB $54,C0212 ; CALL C0212 +; 2255: emit_codetag_10(tag_else) + DB $66,$06 ; LLW 6 + DB $54,C0084 ; CALL C0084 +; 2256: if !parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $20 ; NOT + DB $4C,C0656 ; SKPFLS C0656 +; 2257: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2258: fin +C0656: +C0657: +; 2259: tag_else = ctag_new_01() + DB $54,C0068 ; CALL C0068 + DB $76,$06 ; SLW 6 +; 2260: emit_brfls_10(tag_else) + DB $66,$06 ; LLW 6 + DB $54,C0204 ; CALL C0204 +; 2261: until FALSE + DB $00 ; ZERO + DB $4C,C0651 ; SKPFLS C0651 +C0650: +; 2262: if token == ELSE_TKN + DB $68,D0364 ; LAB D0364 + DB $2A,$85 ; CB 133 + DB $40 ; ISEQ + DB $4C,C0658 ; SKPFLS C0658 +; 2263: emit_jump_10(tag_endif) + DB $66,$08 ; LLW 8 + DB $54,C0212 ; CALL C0212 +; 2264: emit_codetag_10(tag_else) + DB $66,$06 ; LLW 6 + DB $54,C0084 ; CALL C0084 +; 2265: drop scan_01() + DB $54,C0248 ; CALL C0248 + DB $30 ; DROP +; 2266: while parse_stmnt_01() +C0660: + DB $54,C0644 ; CALL C0644 + DB $4C,C0661 ; SKPFLS C0661 +; 2267: drop nextln_01() + DB $54,C0303 ; CALL C0303 + DB $30 ; DROP +; 2268: loop + DB $50,C0660 ; SKIP C0660 +C0661: +; 2269: emit_codetag_10(tag_endif) + DB $66,$08 ; LLW 8 + DB $54,C0084 ; CALL C0084 +; 2270: else + DB $50,C0659 ; SKIP C0659 +C0658: +; 2271: emit_codetag_10(tag_else) + DB $66,$06 ; LLW 6 + DB $54,C0084 ; CALL C0084 +; 2272: emit_codetag_10(tag_endif) + DB $66,$08 ; LLW 8 + DB $54,C0084 ; CALL C0084 +; 2273: fin +C0659: +; 2274: if token <> FIN_TKN + DB $68,D0364 ; LAB D0364 + DB $2A,$86 ; CB 134 + DB $42 ; ISNE + DB $4C,C0662 ; SKPFLS C0662 +; 2275: return parse_err_11(@no_fin) + DB $30 ; DROP + DB $26,D0726 ; LA D0726 + DB $54,C0058 ; CALL C0058 + DB $5A ; LEAVE +; 2276: fin +C0662: +C0663: +; 2277: is FOR_TKN + DB $50,C0648 ; SKIP C0648 +C0649: + DB $2A,$8E ; CB 142 + DB $3E,C0664 ; SKPNE C0664 +; 2278: stack_loop = stack_loop + 1 + DB $68,D0903 ; LAB D0903 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $78,D0903 ; SAB D0903 +; 2279: tag_for = ctag_new_01() + DB $54,C0068 ; CALL C0068 + DB $76,$10 ; SLW 16 +; 2280: tag_prevbrk = break_tag + DB $6A,D0907 ; LAW D0907 + DB $76,$04 ; SLW 4 +; 2281: break_tag = ctag_new_01() + DB $54,C0068 ; CALL C0068 + DB $7A,D0907 ; SAW D0907 +; 2282: if scan_01() <> ID_TKN + DB $54,C0248 ; CALL C0248 + DB $2A,$D6 ; CB 214 + DB $42 ; ISNE + DB $4C,C0665 ; SKPFLS C0665 +; 2283: return parse_err_11(@bad_stmnt) + DB $30 ; DROP + DB $26,D0486 ; LA D0486 + DB $54,C0058 ; CALL C0058 + DB $5A ; LEAVE +; 2284: fin +C0665: +C0666: +; 2285: idptr = id_lookup_21(tknptr, tknlen) + DB $6A,D0368 ; LAW D0368 + DB $68,D0365 ; LAB D0365 + DB $54,C0337 ; CALL C0337 + DB $76,$14 ; SLW 20 +; 2286: if idptr + DB $66,$14 ; LLW 20 + DB $4C,C0667 ; SKPFLS C0667 +; 2287: type = (idptr).idtype + DB $66,$14 ; LLW 20 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $60 ; LB + DB $74,$02 ; SLB 2 +; 2288: addr = (idptr):idval + DB $66,$14 ; LLW 20 + DB $62 ; LW + DB $76,$18 ; SLW 24 +; 2289: else + DB $50,C0668 ; SKIP C0668 +C0667: +; 2290: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2291: fin +C0668: +; 2292: if scan_01() <> SET_TKN + DB $54,C0248 ; CALL C0248 + DB $2A,$BD ; CB 189 + DB $42 ; ISNE + DB $4C,C0669 ; SKPFLS C0669 +; 2293: return parse_err_11(@bad_stmnt) + DB $30 ; DROP + DB $26,D0486 ; LA D0486 + DB $54,C0058 ; CALL C0058 + DB $5A ; LEAVE +; 2294: fin +C0669: +C0670: +; 2295: if !parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $20 ; NOT + DB $4C,C0671 ; SKPFLS C0671 +; 2296: return parse_err_11(@bad_stmnt) + DB $30 ; DROP + DB $26,D0486 ; LA D0486 + DB $54,C0058 ; CALL C0058 + DB $5A ; LEAVE +; 2297: fin +C0671: +C0672: +; 2298: emit_codetag_10(tag_for) + DB $66,$10 ; LLW 16 + DB $54,C0084 ; CALL C0084 +; 2299: if type & LOCAL_TYPE + DB $64,$02 ; LLB 2 + DB $2A,$10 ; CB 16 + DB $14 ; BAND + DB $4C,C0673 ; SKPFLS C0673 +; 2300: if type & BYTE_TYPE + DB $64,$02 ; LLB 2 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C0675 ; SKPFLS C0675 +; 2301: emit_dlb_10(addr) + DB $66,$18 ; LLW 24 + DB $54,C0130 ; CALL C0130 +; 2302: else + DB $50,C0676 ; SKIP C0676 +C0675: +; 2303: emit_dlw_10(addr) + DB $66,$18 ; LLW 24 + DB $54,C0132 ; CALL C0132 +; 2304: fin +C0676: +; 2305: else + DB $50,C0674 ; SKIP C0674 +C0673: +; 2306: if type & BYTE_TYPE + DB $64,$02 ; LLB 2 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C0677 ; SKPFLS C0677 +; 2307: emit_dab_10(addr) + DB $66,$18 ; LLW 24 + DB $54,C0138 ; CALL C0138 +; 2308: else + DB $50,C0678 ; SKIP C0678 +C0677: +; 2309: emit_daw_10(addr) + DB $66,$18 ; LLW 24 + DB $54,C0140 ; CALL C0140 +; 2310: fin +C0678: +; 2311: fin +C0674: +; 2312: stepdir = 1 + DB $2A,$01 ; CB 1 + DB $76,$1A ; SLW 26 +; 2313: if token == TO_TKN + DB $68,D0364 ; LAB D0364 + DB $2A,$8F ; CB 143 + DB $40 ; ISEQ + DB $4C,C0679 ; SKPFLS C0679 +; 2314: drop parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $30 ; DROP +; 2315: elsif token == DOWNTO_TKN + DB $50,C0680 ; SKIP C0680 +C0679: + DB $68,D0364 ; LAB D0364 + DB $2A,$90 ; CB 144 + DB $40 ; ISEQ + DB $4C,C0681 ; SKPFLS C0681 +; 2316: drop parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $30 ; DROP +; 2317: stepdir = -1 + DB $2C,$FF,$FF ; CW -1 + DB $76,$1A ; SLW 26 +; 2318: fin +C0681: +C0680: +; 2319: if stepdir > 0 + DB $66,$1A ; LLW 26 + DB $00 ; ZERO + DB $44 ; ISGT + DB $4C,C0682 ; SKPFLS C0682 +; 2320: emit_brgt_10(break_tag) + DB $6A,D0907 ; LAW D0907 + DB $54,C0206 ; CALL C0206 +; 2321: else + DB $50,C0683 ; SKIP C0683 +C0682: +; 2322: emit_brlt_10(break_tag) + DB $6A,D0907 ; LAW D0907 + DB $54,C0208 ; CALL C0208 +; 2323: fin +C0683: +; 2324: if token == STEP_TKN + DB $68,D0364 ; LAB D0364 + DB $2A,$91 ; CB 145 + DB $40 ; ISEQ + DB $4C,C0684 ; SKPFLS C0684 +; 2325: drop parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $30 ; DROP +; 2326: if stepdir > 0 + DB $66,$1A ; LLW 26 + DB $00 ; ZERO + DB $44 ; ISGT + DB $4C,C0686 ; SKPFLS C0686 +; 2327: drop emit_binaryop_11(ADD_TKN) + DB $2A,$AB ; CB 171 + DB $54,C0171 ; CALL C0171 + DB $30 ; DROP +; 2328: else + DB $50,C0687 ; SKIP C0687 +C0686: +; 2329: drop emit_binaryop_11(SUB_TKN) + DB $2A,$AD ; CB 173 + DB $54,C0171 ; CALL C0171 + DB $30 ; DROP +; 2330: fin +C0687: +; 2331: else + DB $50,C0685 ; SKIP C0685 +C0684: +; 2332: if stepdir > 0 + DB $66,$1A ; LLW 26 + DB $00 ; ZERO + DB $44 ; ISGT + DB $4C,C0688 ; SKPFLS C0688 +; 2333: drop emit_unaryop_11(INC_TKN) + DB $2A,$C1 ; CB 193 + DB $54,C0160 ; CALL C0160 + DB $30 ; DROP +; 2334: else + DB $50,C0689 ; SKIP C0689 +C0688: +; 2335: drop emit_unaryop_11(DEC_TKN) + DB $2A,$C4 ; CB 196 + DB $54,C0160 ; CALL C0160 + DB $30 ; DROP +; 2336: fin +C0689: +; 2337: fin +C0685: +; 2338: while parse_stmnt_01() +C0690: + DB $54,C0644 ; CALL C0644 + DB $4C,C0691 ; SKPFLS C0691 +; 2339: drop nextln_01() + DB $54,C0303 ; CALL C0303 + DB $30 ; DROP +; 2340: loop + DB $50,C0690 ; SKIP C0690 +C0691: +; 2341: if token <> NEXT_TKN + DB $68,D0364 ; LAB D0364 + DB $2A,$92 ; CB 146 + DB $42 ; ISNE + DB $4C,C0692 ; SKPFLS C0692 +; 2342: return parse_err_11(@bad_stmnt) + DB $30 ; DROP + DB $26,D0486 ; LA D0486 + DB $54,C0058 ; CALL C0058 + DB $5A ; LEAVE +; 2343: fin +C0692: +C0693: +; 2344: emit_jump_10(tag_for) + DB $66,$10 ; LLW 16 + DB $54,C0212 ; CALL C0212 +; 2345: emit_codetag_10(break_tag) + DB $6A,D0907 ; LAW D0907 + DB $54,C0084 ; CALL C0084 +; 2346: emit_drop() + DB $54,C0214 ; CALL C0214 +; 2347: break_tag = tag_prevbrk + DB $66,$04 ; LLW 4 + DB $7A,D0907 ; SAW D0907 +; 2348: stack_loop = stack_loop - 1 + DB $68,D0903 ; LAB D0903 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $78,D0903 ; SAB D0903 +; 2349: is WHILE_TKN + DB $50,C0648 ; SKIP C0648 +C0664: + DB $2A,$88 ; CB 136 + DB $3E,C0694 ; SKPNE C0694 +; 2350: tag_while = ctag_new_01() + DB $54,C0068 ; CALL C0068 + DB $76,$0A ; SLW 10 +; 2351: tag_wend = ctag_new_01() + DB $54,C0068 ; CALL C0068 + DB $76,$0C ; SLW 12 +; 2352: tag_prevbrk = break_tag + DB $6A,D0907 ; LAW D0907 + DB $76,$04 ; SLW 4 +; 2353: break_tag = tag_wend + DB $66,$0C ; LLW 12 + DB $7A,D0907 ; SAW D0907 +; 2354: emit_codetag_10(tag_while) + DB $66,$0A ; LLW 10 + DB $54,C0084 ; CALL C0084 +; 2355: drop parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $30 ; DROP +; 2356: emit_brfls_10(tag_wend) + DB $66,$0C ; LLW 12 + DB $54,C0204 ; CALL C0204 +; 2357: while parse_stmnt_01() +C0695: + DB $54,C0644 ; CALL C0644 + DB $4C,C0696 ; SKPFLS C0696 +; 2358: drop nextln_01() + DB $54,C0303 ; CALL C0303 + DB $30 ; DROP +; 2359: loop + DB $50,C0695 ; SKIP C0695 +C0696: +; 2360: if token <> LOOP_TKN + DB $68,D0364 ; LAB D0364 + DB $2A,$89 ; CB 137 + DB $42 ; ISNE + DB $4C,C0697 ; SKPFLS C0697 +; 2361: return parse_err_11(@no_loop) + DB $30 ; DROP + DB $26,D0738 ; LA D0738 + DB $54,C0058 ; CALL C0058 + DB $5A ; LEAVE +; 2362: fin +C0697: +C0698: +; 2363: emit_jump_10(tag_while) + DB $66,$0A ; LLW 10 + DB $54,C0212 ; CALL C0212 +; 2364: emit_codetag_10(tag_wend) + DB $66,$0C ; LLW 12 + DB $54,C0084 ; CALL C0084 +; 2365: break_tag = tag_prevbrk + DB $66,$04 ; LLW 4 + DB $7A,D0907 ; SAW D0907 +; 2366: is REPEAT_TKN + DB $50,C0648 ; SKIP C0648 +C0694: + DB $2A,$93 ; CB 147 + DB $3E,C0699 ; SKPNE C0699 +; 2367: tag_repeat = ctag_new_01() + DB $54,C0068 ; CALL C0068 + DB $76,$0E ; SLW 14 +; 2368: tag_prevbrk = break_tag + DB $6A,D0907 ; LAW D0907 + DB $76,$04 ; SLW 4 +; 2369: break_tag = ctag_new_01() + DB $54,C0068 ; CALL C0068 + DB $7A,D0907 ; SAW D0907 +; 2370: emit_codetag_10(tag_repeat) + DB $66,$0E ; LLW 14 + DB $54,C0084 ; CALL C0084 +; 2371: drop scan_01() + DB $54,C0248 ; CALL C0248 + DB $30 ; DROP +; 2372: while parse_stmnt_01() +C0700: + DB $54,C0644 ; CALL C0644 + DB $4C,C0701 ; SKPFLS C0701 +; 2373: drop nextln_01() + DB $54,C0303 ; CALL C0303 + DB $30 ; DROP +; 2374: loop + DB $50,C0700 ; SKIP C0700 +C0701: +; 2375: if token <> UNTIL_TKN + DB $68,D0364 ; LAB D0364 + DB $2A,$94 ; CB 148 + DB $42 ; ISNE + DB $4C,C0702 ; SKPFLS C0702 +; 2376: return parse_err_11(@no_until) + DB $30 ; DROP + DB $26,D0751 ; LA D0751 + DB $54,C0058 ; CALL C0058 + DB $5A ; LEAVE +; 2377: fin +C0702: +C0703: +; 2378: drop parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $30 ; DROP +; 2379: emit_brfls_10(tag_repeat) + DB $66,$0E ; LLW 14 + DB $54,C0204 ; CALL C0204 +; 2380: emit_codetag_10(break_tag) + DB $6A,D0907 ; LAW D0907 + DB $54,C0084 ; CALL C0084 +; 2381: break_tag = tag_prevbrk + DB $66,$04 ; LLW 4 + DB $7A,D0907 ; SAW D0907 +; 2382: is CASE_TKN + DB $50,C0648 ; SKIP C0648 +C0699: + DB $2A,$8A ; CB 138 + DB $3E,C0704 ; SKPNE C0704 +; 2383: stack_loop = stack_loop + 1 + DB $68,D0903 ; LAB D0903 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $78,D0903 ; SAB D0903 +; 2384: tag_choice = ctag_new_01() + DB $54,C0068 ; CALL C0068 + DB $76,$12 ; SLW 18 +; 2385: tag_prevbrk = break_tag + DB $6A,D0907 ; LAW D0907 + DB $76,$04 ; SLW 4 +; 2386: break_tag = ctag_new_01() + DB $54,C0068 ; CALL C0068 + DB $7A,D0907 ; SAW D0907 +; 2387: drop parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $30 ; DROP +; 2388: drop nextln_01() + DB $54,C0303 ; CALL C0303 + DB $30 ; DROP +; 2389: while token <> ENDCASE_TKN +C0705: + DB $68,D0364 ; LAB D0364 + DB $2A,$8D ; CB 141 + DB $42 ; ISNE + DB $4C,C0706 ; SKPFLS C0706 +; 2390: when token + DB $68,D0364 ; LAB D0364 +; 2391: is OF_TKN + DB $2A,$8B ; CB 139 + DB $3E,C0708 ; SKPNE C0708 +; 2392: if !parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $20 ; NOT + DB $4C,C0709 ; SKPFLS C0709 +; 2393: return parse_err_11(@bad_stmnt) + DB $30 ; DROP + DB $30 ; DROP + DB $26,D0486 ; LA D0486 + DB $54,C0058 ; CALL C0058 + DB $5A ; LEAVE +; 2394: fin +C0709: +C0710: +; 2395: emit_brne_10(tag_choice) + DB $66,$12 ; LLW 18 + DB $54,C0210 ; CALL C0210 +; 2396: while parse_stmnt_01() +C0711: + DB $54,C0644 ; CALL C0644 + DB $4C,C0712 ; SKPFLS C0712 +; 2397: drop nextln_01() + DB $54,C0303 ; CALL C0303 + DB $30 ; DROP +; 2398: loop + DB $50,C0711 ; SKIP C0711 +C0712: +; 2399: emit_jump_10(break_tag) + DB $6A,D0907 ; LAW D0907 + DB $54,C0212 ; CALL C0212 +; 2400: emit_codetag_10(tag_choice) + DB $66,$12 ; LLW 18 + DB $54,C0084 ; CALL C0084 +; 2401: tag_choice = ctag_new_01() + DB $54,C0068 ; CALL C0068 + DB $76,$12 ; SLW 18 +; 2402: is DEFAULT_TKN + DB $50,C0707 ; SKIP C0707 +C0708: + DB $2A,$8C ; CB 140 + DB $3E,C0713 ; SKPNE C0713 +; 2403: drop scan_01() + DB $54,C0248 ; CALL C0248 + DB $30 ; DROP +; 2404: while parse_stmnt_01() +C0714: + DB $54,C0644 ; CALL C0644 + DB $4C,C0715 ; SKPFLS C0715 +; 2405: drop nextln_01() + DB $54,C0303 ; CALL C0303 + DB $30 ; DROP +; 2406: loop + DB $50,C0714 ; SKIP C0714 +C0715: +; 2407: if token <> ENDCASE_TKN + DB $68,D0364 ; LAB D0364 + DB $2A,$8D ; CB 141 + DB $42 ; ISNE + DB $4C,C0716 ; SKPFLS C0716 +; 2408: return parse_err_11(@bad_stmnt) + DB $30 ; DROP + DB $30 ; DROP + DB $26,D0486 ; LA D0486 + DB $54,C0058 ; CALL C0058 + DB $5A ; LEAVE +; 2409: fin +C0716: +C0717: +; 2410: otherwise + DB $50,C0707 ; SKIP C0707 +C0713: +; 2411: return parse_err_11(@bad_stmnt) + DB $30 ; DROP + DB $30 ; DROP + DB $26,D0486 ; LA D0486 + DB $54,C0058 ; CALL C0058 + DB $5A ; LEAVE +; 2412: wend +C0707: + DB $30 ; DROP +; 2413: loop + DB $50,C0705 ; SKIP C0705 +C0706: +; 2414: emit_codetag_10(break_tag) + DB $6A,D0907 ; LAW D0907 + DB $54,C0084 ; CALL C0084 +; 2415: emit_drop() + DB $54,C0214 ; CALL C0214 +; 2416: break_tag = tag_prevbrk + DB $66,$04 ; LLW 4 + DB $7A,D0907 ; SAW D0907 +; 2417: stack_loop = stack_loop - 1 + DB $68,D0903 ; LAB D0903 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $78,D0903 ; SAB D0903 +; 2418: is BREAK_TKN + DB $50,C0648 ; SKIP C0648 +C0704: + DB $2A,$9A ; CB 154 + DB $3E,C0719 ; SKPNE C0719 +; 2419: if break_tag + DB $6A,D0907 ; LAW D0907 + DB $4C,C0720 ; SKPFLS C0720 +; 2420: emit_jump_10(break_tag) + DB $6A,D0907 ; LAW D0907 + DB $54,C0212 ; CALL C0212 +; 2421: else + DB $50,C0721 ; SKIP C0721 +C0720: +; 2422: return parse_err_11(@bad_stmnt) + DB $30 ; DROP + DB $26,D0486 ; LA D0486 + DB $54,C0058 ; CALL C0058 + DB $5A ; LEAVE +; 2423: fin +C0721: +; 2424: is RETURN_TKN + DB $50,C0648 ; SKIP C0648 +C0719: + DB $2A,$99 ; CB 153 + DB $3E,C0722 ; SKPNE C0722 +; 2425: if infunc + DB $68,D0902 ; LAB D0902 + DB $4C,C0723 ; SKPFLS C0723 +; 2426: for i = 1 to stack_loop + DB $2A,$01 ; CB 1 +C0726: + DB $6C,$03 ; DLB 3 + DB $68,D0903 ; LAB D0903 + DB $3A,C0725 ; SKPGT C0725 + DB $0C ; INCR +; 2427: emit_drop() + DB $54,C0214 ; CALL C0214 +; 2428: next + DB $50,C0726 ; SKIP C0726 +C0725: + DB $30 ; DROP +; 2429: drop parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $30 ; DROP +; 2430: emit_leave_10(framesize) + DB $6A,D0016 ; LAW D0016 + DB $54,C0218 ; CALL C0218 +; 2431: else + DB $50,C0724 ; SKIP C0724 +C0723: +; 2432: return parse_err_11(@bad_stmnt) + DB $30 ; DROP + DB $26,D0486 ; LA D0486 + DB $54,C0058 ; CALL C0058 + DB $5A ; LEAVE +; 2433: fin +C0724: +; 2434: is EXIT_TKN + DB $50,C0648 ; SKIP C0648 +C0722: + DB $2A,$9C ; CB 156 + DB $3E,C0727 ; SKPNE C0727 +; 2435: drop parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $30 ; DROP +; 2436: emit_exit() + DB $54,C0228 ; CALL C0228 +; 2437: is DROP_TKN + DB $50,C0648 ; SKIP C0648 +C0727: + DB $2A,$97 ; CB 151 + DB $3E,C0728 ; SKPNE C0728 +; 2438: drop parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $30 ; DROP +; 2439: emit_drop() + DB $54,C0214 ; CALL C0214 +; 2440: is ELSE_TKN + DB $50,C0648 ; SKIP C0648 +C0728: + DB $2A,$85 ; CB 133 + DB $3E,C0729 ; SKPNE C0729 +; 2441: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2442: is ELSEIF_TKN + DB $50,C0648 ; SKIP C0648 +C0729: + DB $2A,$84 ; CB 132 + DB $3E,C0730 ; SKPNE C0730 +; 2443: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2444: is FIN_TKN + DB $50,C0648 ; SKIP C0648 +C0730: + DB $2A,$86 ; CB 134 + DB $3E,C0731 ; SKPNE C0731 +; 2445: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2446: is LOOP_TKN + DB $50,C0648 ; SKIP C0648 +C0731: + DB $2A,$89 ; CB 137 + DB $3E,C0732 ; SKPNE C0732 +; 2447: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2448: is UNTIL_TKN + DB $50,C0648 ; SKIP C0648 +C0732: + DB $2A,$94 ; CB 148 + DB $3E,C0733 ; SKPNE C0733 +; 2449: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2450: is NEXT_TKN + DB $50,C0648 ; SKIP C0648 +C0733: + DB $2A,$92 ; CB 146 + DB $3E,C0734 ; SKPNE C0734 +; 2451: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2452: is OF_TKN + DB $50,C0648 ; SKIP C0648 +C0734: + DB $2A,$8B ; CB 139 + DB $3E,C0735 ; SKPNE C0735 +; 2453: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2454: is DEFAULT_TKN + DB $50,C0648 ; SKIP C0648 +C0735: + DB $2A,$8C ; CB 140 + DB $3E,C0736 ; SKPNE C0736 +; 2455: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2456: is ENDCASE_TKN + DB $50,C0648 ; SKIP C0648 +C0736: + DB $2A,$8D ; CB 141 + DB $3E,C0737 ; SKPNE C0737 +; 2457: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2458: is END_TKN + DB $50,C0648 ; SKIP C0648 +C0737: + DB $2A,$87 ; CB 135 + DB $3E,C0738 ; SKPNE C0738 +; 2459: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2460: is DONE_TKN + DB $50,C0648 ; SKIP C0648 +C0738: + DB $2A,$98 ; CB 152 + DB $3E,C0739 ; SKPNE C0739 +; 2461: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2462: is IFUNC_TKN + DB $50,C0648 ; SKIP C0648 +C0739: +Bad ID type +START: ; JSR INTERP +Bad ID type + DB $5C ; RET diff --git a/plasma2/plasma2.cfg b/plasma2/plasma2.cfg new file mode 100755 index 0000000..e084284 --- /dev/null +++ b/plasma2/plasma2.cfg @@ -0,0 +1,10 @@ +MEMORY { + RAM: start = $2000, size = $6000, file = %O; +} +SEGMENTS { + CODE: load = RAM, type = rw; + DATA: load = RAM, type = rw; + BSS: load = RAM, type = rw; +} + + diff --git a/plasma2/plasma2.pla b/plasma2/plasma2.pla new file mode 100755 index 0000000..e4088c0 --- /dev/null +++ b/plasma2/plasma2.pla @@ -0,0 +1,2553 @@ +; +; Global constants +; +const FALSE = 0 +const TRUE = 1 +; +; Tokens +; +const ID_TKN = $D6 ; V +const CHR_TKN = $C3 ; C +const INT_TKN = $C9 ; I +const STR_TKN = $D3 ; S +const EOL_TKN = $02 +const Eis_TKN = $01 +const ERR_TKN = $00 +; +; Binary operand operators +; +const SET_TKN = $BD ; = +const ADD_TKN = $AB ; + +const SUB_TKN = $AD ; - +const MUL_TKN = $AA ; * +const DIV_TKN = $AF ; / +const MOD_TKN = $A5 ; % +const OR_TKN = $BF ; ? +const EOR_TKN = $DE ; ^ +const AND_TKN = $A6 ; & +const SHR_TKN = $D2 ; R +const SHL_TKN = $CC ; L +const GT_TKN = $BE ; > +const GE_TKN = $C8 ; H +const LT_TKN = $BC ; < +const LE_TKN = $C2 ; B +const NE_TKN = $D5 ; U +const EQ_TKN = $C5 ; E +const LOGIC_AND_TKN = $CE ; N +const LOGIC_OR_TKN = $CF ; O +; +; Unary operand operators +; +const AT_TKN = $C0 ; @ +const DOT_TKN = $AE ; . +const COLON_TKN = $BA ; : +const NEG_TKN = $AD ; - +const COMP_TKN = $A3 ; # +const LOGIC_NOT_TKN = $A1 ; ! +const BPTR_TKN = $DE ; ^ +const WPTR_TKN = $AA ; * +const INC_TKN = $C1 ; A +const DEC_TKN = $C4 ; D +; +; Enclosure tokens +; +const OPEN_PAREN_TKN = $A8 ; ( +const CLOSE_PAREN_TKN = $A9 ; ) +const OPEN_BRACKET_TKN = $DB ; [ +const CLOSE_BRACKET_TKN = $DD ; ] +; +; Misc. tokens +; +const COMMA_TKN = $AC ; , +const COMMENT_TKN = $BB ; ; +; +; Keyword tokens +; +const CONST_TKN = $80 +const BYTE_TKN = $81 +const WORD_TKN = $82 +const IF_TKN = $83 +const ELSEIF_TKN = $84 +const ELSE_TKN = $85 +const FIN_TKN = $86 +const END_TKN = $87 +const WHILE_TKN = $88 +const LOOP_TKN = $89 +const when_TKN = $8A +const is_TKN = $8B +const DEFAULT_TKN = $8C +const ENDwhen_TKN = $8D +const FOR_TKN = $8E +const TO_TKN = $8F +const DOWNTO_TKN = $90 +const STEP_TKN = $91 +const NEXT_TKN = $92 +const REPEAT_TKN = $93 +const UNTIL_TKN = $94 +const IFUNC_TKN = $95 +const TFUNC_TKN = $96 +const NFUNC_TKN = $97 +const DONE_TKN = $98 +const RETURN_TKN = $99 +const BREAK_TKN = $9A +const START_TKN = $9B +const EXIT_TKN = $9C +const EVAL_TKN = $9D +const FUNC_TKN = $9E +; +; Types +; +const CONST_TYPE = $01 +const BYTE_TYPE = $02 +const WORD_TYPE = $04 +const VAR_TYPE = $06 ; (WORD_TYPE | BYTE_TYPE) +const FUNC_TYPE = $08 +const FUNC_CONST_TYPE = $09 +const ADDR_TYPE = $0E ; (VAR_TYPE | FUNC_TYPE) +const LOCAL_TYPE = $10 +const BPTR_TYPE = $20 +const WPTR_TYPE = $40 +const PTR_TYPE = $60 ; (BPTR_TYPE | WPTR_TYPE) +const XBYTE_TYPE = $22 ; (BPTR_TYPE | BYTE_TYPE) +const XWORD_TYPE = $44 ; (WPTR_TYPE | WORD_TYPE) +const STR_TYPE = $80 +; +; Keywords +; +byte keywrds[] +byte = "IF", IF_TKN +byte = "TO", TO_TKN +byte = "IS", is_TKN +byte = "OR", LOGIC_OR_TKN +byte = "FOR", FOR_TKN +byte = "FIN", FIN_TKN +byte = "DEF", IFUNC_TKN +byte = "END", END_TKN +byte = "AND", LOGIC_AND_TKN +byte = "NOT", LOGIC_NOT_TKN +byte = "BYTE", BYTE_TKN +byte = "WORD", WORD_TKN +byte = "DEFT", TFUNC_TKN +byte = "DEFN", NFUNC_TKN +byte = "ELSE", ELSE_TKN +byte = "NEXT", NEXT_TKN +byte = "WHEN", when_TKN +byte = "LOOP", LOOP_TKN +byte = "FUNC", FUNC_TKN +byte = "STEP", STEP_TKN +byte = "EXIT", EXIT_TKN +byte = "DONE", DONE_TKN +byte = "WEND", ENDwhen_TKN +byte = "CONST", CONST_TKN +byte = "ELSIF", ELSEIF_TKN +byte = "WHILE", WHILE_TKN +byte = "UNTIL", UNTIL_TKN +byte = "BREAK", BREAK_TKN +byte = "OTHER", DEFAULT_TKN +byte = "DOWNTO",DOWNTO_TKN +byte = "REPEAT",REPEAT_TKN +byte = "RETURN",RETURN_TKN +byte = $FF +; +; Mathematical ops +; +const bops_tblsz = 18 +byte bops_tbl[] ; Highest precedence +byte = MUL_TKN, DIV_TKN, MOD_TKN +byte = ADD_TKN, SUB_TKN +byte = SHR_TKN, SHL_TKN +byte = AND_TKN +byte = EOR_TKN +byte = OR_TKN +byte = GT_TKN, GE_TKN, LT_TKN, LE_TKN +byte = EQ_TKN, NE_TKN +byte = LOGIC_AND_TKN +byte = LOGIC_OR_TKN + ; Lowest precedence +byte bops_prec[] ; Highest precedence +byte = 1, 1, 1 +byte = 2, 2 +byte = 3, 3 +byte = 4 +byte = 5 +byte = 6 +byte = 7, 7, 7, 7 +byte = 8, 8 +byte = 9 +byte = 10 + ; Lowest precedence +byte opstack[16] +byte precstack[16] +word opsp = -1 +; +; Symbol table variables +; +const idglobal_tblsz = 2048 +const idlocal_tblsz = 512 +const idglobal_tbl = $1600 +const idlocal_tbl = $1E00 +const ctag_max = 512 +const ctag_value = $1000 +const ctag_flags = $1400 +const idval = 0 +const idtype = 2 +const idname = 3 +const idrecsz = 4 +word globals = 0 +word datasize = 0 +word lastglobal +byte locals = 0 +word framesize = 0 +word lastlocal +const resolved = 1 +const is_ctag = $8000 +const mask_ctag = $7FFF +word codetag = -1 +; +; Code generation buffers and variables +; +const codebuff = $7000 +const codebuffsz = $4000 +byte lastop = $FF +word codeptr, entrypoint = 0 +; +; Scanner variables +; +const inbuff = $0200 +const instr = $01FF +byte token, tknlen +byte parserrpos, parserr = 0 +word scanptr, tknptr, parserrln +word constval +word lineno = 0 +; +; Compiler output messages +; +byte entrypt_str[] = "START: " +byte comp_ok_msg[] = "COMPILATION COMPLETE" +byte dup_id[] = "DUPLICATE IDENTIFIER" +byte undecl_id[] = "UNDECLARED IDENTIFIER" +byte bad_cnst[] = "BAD CONSTANT" +byte bad_isfset[] = "BAD STRUCT isFSET" +byte bad_decl[] = "BAD DECLARATION" +byte bad_op[] = "BAD OPERATION" +byte bad_stmnt[] = "BAD STATMENT" +byte bad_expr[] = "BAD EXPRESSION" +byte bad_syntax[] = "BAD SYNTAX" +byte estk_overflw[] = "EVAL STACK OVERFLOW" +byte estk_underflw[] = "EVAL STACK UNDERFLOW" +byte local_overflw[] = "LOCAL FRAME OVERFLOW" +byte global_sym_overflw[] = "GLOBAL SYMBOL TABLE OVERFLOW" +byte local_sym_overflw[] = "LOCAL SYMBOL TABLE OVERFLOW" +byte ctag_full[] = "CODE LABEL OVERFLOW" +byte no_close_paren[] = "MISSING CLOSING PAREN" +byte no_close_bracket[] = "MISSING CLOSING BRACKET" +byte missing_op[] = "MISSING OPERAND" +byte no_fin[] = "MISSING FIN" +byte no_loop[] = "MISSING LOOP" +byte no_until[] = "MISSING UNTIL" +byte no_done[] = "MISSING DONE" +byte no_local_init[] = "NO INITIALIZED LOCALS" +; +; Runtime functions +; +byte runtime0[] = "romcall" +byte RUNTIME0[] = "ROMCALL" +byte runtime1[] = "syscall" +byte RUNTIME1[] = "SYSCALL" +byte runtime2[] = "memset" +byte RUNTIME2[] = "MEMSET" +byte runtime3[] = "memcpy" +byte RUNTIME3[] = "MEMCPY" +byte runtime4[] = "cout" +byte RUNTIME4[] = "COUT" +byte runtime5[] = "cin" +byte RUNTIME5[] = "CIN" +byte runtime6[] = "prstr" +byte RUNTIME6[] = "PRSTR" +byte runtime7[] = "rdstr" +byte RUNTIME7[] = "RDSTR" +; +; Parser variables +; +byte infunc = 0 +byte stack_loop = 0 +byte prevstmnt = 0 +word retfunc_tag = 0 +word break_tag = 0 +func parse_expr +; +; File refs +; +const infile_buff = $0800 +const outfile_buff = $0C00 +byte inref, outref +; +; ProDOS error +; +byte perr +; +; Utility functions +; +; CALL 6502 ROUTINE +; ROMCALL(AREG, XREG, YREG, STATUS, ADDR) +; +asm romcall + PHP + LDA ESTKL,X + STA TMPL + LDA ESTKH,X + STA TMPH + INX + LDA ESTKL,X + PHA + INX + LDA ESTKL,X + TAY + INX + LDA ESTKL+1,X + PHA + LDA ESTKL,X + INX + STX ESP + TAX + PLA + PLP + JSR _IJMPTMP + PHP + STA REGVALS+0 + STX REGVALS+1 + STY REGVALS+2 + PLA + STA REGVALS+3 + LDX ESP + LDA #REGVALS + STA ESTKL,X + STY ESTKH,X + PLP + RTS +REGVALS: DS 4 +end +; +; CALL PRODOS +; SYSCALL(CMD, PARAMS) +; +asm syscall + LDA ESTKL,X + LDY ESTKH,X + STA PARAMS + STY PARAMS+1 + INX + LDA ESTKL,X + STA CMD + STX ESP + JSR $BF00 +CMD: DB 00 +PARAMS: DW 0000 + LDX ESP + STA ESTKL,X + LDY #$00 + STY ESTKH,X +end +; +; SET MEMORY TO VALUE +; MEMSET(VALUE, ADDR, SIZE) +; +asm memset + LDA ESTKL+1,X + STA DSTL + LDA ESTKH+1,X + STA DSTH + INC ESTKL,X + INC ESTKH,X +SETMEM: DEC ESTKL,X + BNE :+ + DEC ESTKH,X + BEQ MEMEXIT +: LDA ESTKL+2,X + STA (DST),Y + INY + BNE :+ + INC DSTH +: DEC ESTKL,X + BNE :+ + DEC ESTKH,X + BEQ MEMEXIT +: LDA ESTKH+2,X + STA (DST),Y + INY + BNE SETMEM + INC DSTH + BNE SETMEM +MEMEXIT: INX + INX + INX +end +; +; COPY MEMORY +; MEMCPY(SRCADDR, DSTADDR, SIZE) +; +asm memcpy + LDA ESTKL,X + BNE :+ + LDA ESTKH,X + BEQ MEMEXIT +: LDA ESTKL+1,X + STA DSTL + LDA ESTKH+1,X + STA DSTH + LDA ESTKL+2,X + STA SRCL + LDA ESTKH+2,X + STA SRCH + CMP DSTH + BCC REVCPY + BNE FORCPY + LDA SRCL + CMP DSTL + BCS FORCPY +REVCPY: ; REVERSE DIRECTION COPY +; CLC + LDA ESTKL,X + ADC DSTL + STA DSTL + LDA ESTKH,X + ADC DSTH + STA DSTH + CLC + LDA ESTKL,X + ADC SRCL + STA SRCL + LDA ESTKH,X + ADC SRCH + STA SRCH + INC ESTKH,X +REVCPYLP: + LDA DSTL + BNE :+ + DEC DSTH +: DEC DSTL + LDA SRCL + BNE :+ + DEC SRCH +: DEC SRCL + LDA (SRC),Y + STA (DST),Y + DEC ESTKL,X + BNE REVCPYLP + DEC ESTKH,X + BNE REVCPYLP + BEQ MEMEXIT +FORCPY: INC ESTKH,X +FORCPYLP: + LDA (SRC),Y + STA (DST),Y + INC DSTL + BNE :+ + INC DSTH +: INC SRCL + BNE :+ + INC SRCH +: DEC ESTKL,X + BNE FORCPYLP + DEC ESTKH,X + BNE FORCPYLP + BEQ MEMEXIT +end +; +; CHAR OUT +; COUT(CHAR) +; +asm cout + LDA ESTKL,X + INX + ORA #$80 + JSR $FDED +end +; +; CHAR IN +; RDKEY() +; +asm rdkey + JSR $FD0C + DEX + STA ESTKL,X + STY ESTKH,X +end +; +; PRINT STRING +; PRSTR(STR) +; +asm prstr + LDA ESTKL,X + STA SRCL + LDA ESTKH,X + STA SRCH + LDA (SRC),Y + STA ESTKL,X + BEQ :+ +_PRS1: INY + LDA (SRC),Y + ORA #$80 + JSR $FDED + TYA + CMP ESTKL,X + BNE _PRS1 +: INX +end +; +; READ STRING +; STR = RDSTR(PROMPTCHAR) +; +asm rdstr + LDA ESTKL,X + STA $33 + STX ESP + JSR $FD6A + STX $01FF + LDX ESP + LDY #$FF + STY ESTKL,X + LDY #$01 + STY ESTKH,X +end +; +; ProDOS routines +; +def open(path, buff) + byte parms[6] + + parms.0 = 3 + parms:1 = path + parms:3 = buff + perr = syscall($C8, @parms) + return parms.5 +end +def close(refnum) + byte parms[2] + + parms.0 = 1 + parms.1 = refnum + perr = syscall($CC, @parms) + return perr +end +def read(refnum, buff, len) + byte parms[8] + + parms.0 = 4 + parms.1 = refnum + parms:2 = buff + parms:4 = len + parms:6 = 0 + perr = syscall($CA, @parms) + return parms:6 +end +def write(refnum, buff, len) + byte parms[8] + + parms.0 = 4 + parms.1 = refnum + parms:2 = buff + parms:4 = len + parms:6 = 0 + perr = syscall($CB, @parms) + return parms:6 +end +def create(path, access, type, aux) + byte parms[12] + + parms.0 = 7 + parms:1 = path + parms.3 = access + parms.4 = type + parms:5 = aux + parms.7 = $1 + parms:8 = 0 + parms:10 = 0 + perr = syscall($C0, @parms) + return perr +end +def destroy(path) + byte parms[12] + + parms.0 = 1 + parms:1 = path + perr = syscall($C1, @parms) + return perr +end +def newline(refnum, emask, nlchar) + byte parms[4] + + parms.0 = 3 + parms.1 = refnum + parms.2 = emask + parms.3 = nlchar + perr = syscall($C9, @parms) + return perr +end +; +; Utility routines +; +def crout + cout($8D) +end +def prbyte(h) + cout('$') + return romcall(h, 0, 0, 0, $FDDA) +end +def prword(h) + cout('$') + return romcall(h >> 8, h, 0, 0, $F941) +end +def print(i) + byte numstr[7] + byte place, sign + + place = 6 + if i < 0 + sign = 1 + i = -i + else + sign = 0 + fin + while i >= 10 + numstr[place] = i % 10 + '0' + i = i / 10 + place = place - 1 + loop + numstr[place] = i + '0' + place = place - 1 + if sign + numstr[place] = '-' + place = place - 1 + fin + numstr[place] = 6 - place + return prstr(@numstr[place]) +end +def nametostr(namestr, len, strptr) + ^strptr = len + return memcpy(namestr, strptr + 1, len) +end +; +; Error handler +; +def parse_err(err) + if !parserr + parserr = TRUE + parserrln = lineno + parserrpos = tknptr - instr + print(lineno) + cout(':') + prstr(err) + crout + fin + return ERR_TKN +end +; +; Emit bytecode +; +def ctag_new + if codetag >= ctag_max + return parse_err(@ctag_full) + fin + codetag = codetag + 1 + ctag_value:[codetag] = 0 + ctag_flags.[codetag] = 0 + return codetag ? is_ctag +end +deft ctag_resolve(tag, addr) + word updtptr, nextptr + + tag = tag & mask_ctag + if ctag_flags.[tag] & resolved + return parse_err(@dup_id) + fin + updtptr = ctag_value:[tag] + while updtptr + ; + ; Update list is addresses needing resolution + ; + nextptr = *updtptr + *updtptr = addr + updtptr = nextptr + loop + ctag_value:[tag] = addr + ctag_flags.[tag] = ctag_flags.[tag] ? resolved +end +defn emit_byte(bval) + ^codeptr = bval + codeptr = codeptr + 1 +end +defn emit_word(wval) + *codeptr = wval + codeptr = codeptr + 2 +end +def emit_fill(size) + memset(0, codeptr, size) + codeptr = codeptr + size +end +def emit_codetag(tag) + return ctag_resolve(tag, codeptr) +end +deft emit_op(op) + lastop = op + return emit_byte(op) +end +def emit_tag(tag) + word updtptr + + if tag & is_ctag + tag = tag & mask_ctag + updtptr = ctag_value:[tag] + if !(ctag_flags.[tag] & resolved) + ; + ; Add to list is tags needing resolution + ; + ctag_value:[tag] = codeptr + fin + emit_word(updtptr) + else + emit_word(tag + codebuff) + fin +end +def emit_iddata(value, size, namestr) + return emit_fill(size) +end +def emit_data(vartype, consttype, constval, constsize) + byte i + word size, chrptr + + if consttype == 0 + size = constsize + emit_fill(constsize) + elsif consttype == STR_TYPE + size = constsize + chrptr = constval + constsize = constsize - 1 + emit_byte(constsize) + while constsize > 0 + emit_byte(^chrptr) + chrptr = chrptr + 1 + constsize = constsize - 1 + loop + else + if vartype == WORD_TYPE + size = 2 + emit_word(constval) + else + size = 1 + emit_byte(constval) + fin + fin + return size +end +def emit_const(cval) + if cval == 0 + emit_op($00) + elsif cval > 0 and cval < 256 + emit_op($2A) + emit_byte(cval) + else + emit_op($2C) + emit_word(cval) + fin +end +def emit_lb + return emit_op($60) +end +def emit_lw + return emit_op($62) +end +def emit_llb(index) + emit_op($64) + return emit_byte(index) +end +def emit_llw(index) + emit_op($66) + return emit_byte(index) +end +def emit_lab(tag) + emit_op($68) + return emit_tag(tag) +end +def emit_law(tag) + emit_op($6A) + return emit_tag(tag) +end +def emit_sb + return emit_op($70) +end +def emit_sw + return emit_op($72) +end +def emit_slb(index) + emit_op($74) + return emit_byte(index) +end +def emit_slw(index) + emit_op($76) + return emit_byte(index) +end +def emit_dlb(index) + emit_op($6C) + return emit_byte(index) +end +def emit_dlw(index) + emit_op($6E) + return emit_byte(index) +end +def emit_sab(tag) + emit_op($78) + return emit_tag(tag) +end +def emit_saw(tag) + emit_op($7A) + return emit_tag(tag) +end +def emit_dab(tag) + emit_op($7C) + return emit_tag(tag) +end +def emit_daw(tag) + emit_op($7E) + return emit_tag(tag) +end +def emit_call(tag, cparams) + emit_op($54) + return emit_tag(tag) +end +def emit_ical(cparams) + emit_op($56) + return emit_byte(cparams) +end +def emit_push + emit_op($34) +end +def emit_pull + ; + ; Skip if last op was push + ; + if lastop == $34 + codeptr = codeptr - 1 + lastop = $FF + else + emit_op($36) + fin +end +def emit_localaddr(index) + emit_op($28) + return emit_byte(index) +end +def emit_globaladdr(tag) + emit_op($26) + return emit_tag(tag) +end +def emit_indexbyte + return emit_op($2E) +end +def emit_indexword + return emit_op($1E) +end +def emit_unaryop(op) + when op + is NEG_TKN + emit_op($10) + is COMP_TKN + emit_op($12) + is LOGIC_NOT_TKN + emit_op($20) + is INC_TKN + emit_op($0C) + is DEC_TKN + emit_op($0E) + is BPTR_TKN + emit_op($60) + is WPTR_TKN + emit_op($62) + otherwise + return FALSE + wend + return TRUE +end +def emit_binaryop(op) + when op + is MUL_TKN + ; + ; Replace MUL 2 with SHL 1 + ; + if lastop == $2A and ^(codeptr - 1) == 2 ; CB 2 + codeptr = codeptr - 1 + emit_byte(1) ; CB 1 + emit_op($1A) ; SHL + else + emit_op($06) + fin + is DIV_TKN + ; + ; Replace DIV 2 with SHR 1 + ; + if lastop == $2A and ^(codeptr - 1) == 2 ; CB 2 + codeptr = codeptr - 1 + emit_byte(1) ; CB 1 + emit_op($1C) ; SHR + else + emit_op($08) + fin + is MOD_TKN + emit_op($0A) + is ADD_TKN + ; + ; Replace ADD 1 with INCR + ; + if lastop == $2A and ^(codeptr - 1) == 1 ; CB 1 + codeptr = codeptr - 2 + emit_op($0C) ; INC_OP + else + emit_op($02) + fin + is SUB_TKN + ; + ; Replace SUB 1 with DECR + ; + if lastop == $2A and ^(codeptr - 1) == 1 ; CB 1 + codeptr = codeptr - 2 + emit_op($0E) ; DEC_OP + else + emit_op($04) + fin + is SHL_TKN + emit_op($1A) + is SHR_TKN + emit_op($1C) + is AND_TKN + emit_op($14) + is OR_TKN + emit_op($16) + is EOR_TKN + emit_op($18) + is EQ_TKN + emit_op($40) + is NE_TKN + emit_op($42) + is GE_TKN + emit_op($48) + is LT_TKN + emit_op($46) + is GT_TKN + emit_op($44) + is LE_TKN + emit_op($4A) + is LOGIC_OR_TKN + emit_op($22) + is LOGIC_AND_TKN + emit_op($24) + otherwise + return FALSE + wend + return TRUE +end +def emit_brtru(tag) + emit_op($4E) + return emit_tag(tag) +end +def emit_brfls(tag) + emit_op($4C) + return emit_tag(tag) +end +def emit_brgt(tag) + emit_op($3A) + return emit_tag(tag) +end +def emit_brlt(tag) + emit_op($38) + return emit_tag(tag) +end +def emit_brne(tag) + emit_op($3E) + return emit_tag(tag) +end +def emit_jump(tag) + emit_op($50) + return emit_tag(tag) +end +def emit_drop + return emit_op($30) +end +def emit_leave(framesize) + if framesize > 2 + emit_op($5A) + else + emit_op($5C) + fin +end +def emit_enter(framesize, cparams) + emit_byte(emit_enter.[0]) + emit_byte(emit_enter.[1]) + emit_byte(emit_enter.[2]) + if framesize > 2 + emit_op($58) + emit_byte(framesize) + emit_byte(cparams) + fin +end +def emit_start + ; + ; Save address + ; + entrypoint = codeptr + emit_byte(emit_start.[0]) + emit_byte(emit_start.[1]) + return emit_op(emit_start.[2]) +end +def emit_exit + emit_op($00) + return emit_op($5C) +end +def optimization(opt) +end +def vsp_save +end +def vsp_restore +end +; +; Lexical anaylzer +; +;def toupper(c) +; if c >= 'a' +; if c <= 'z' +; return c - $20 +; fin +; fin +; return c +;end +asm toupper + LDA ESTKL,X + CMP #'a' + BCC :+ + CMP #'z'+1 + BCS :+ + SEC + SBC #$20 + STA ESTKL,X +: RTS +end +;defn isalpha(c) +; if c >= 'A' and c <= 'Z' +; return TRUE +; elsif c >= 'a' and c <= 'z' +; return TRUE +; elsif c == '_' +; return TRUE +; fin +; return FALSE +;end +asm isalpha + LDY #$00 + LDA ESTKL,X + CMP #'A' + BCC ISALRET + CMP #'Z'+1 + BCS :+ + DEY + BNE ISALRET +: CMP #'a' + BCC ISALRET + CMP #'z'+1 + BCS :+ + DEY + BNE ISALRET +: CMP #'_' + BNE ISALRET + DEY +ISALRET: + STY ESTKL,X + STY ESTKH,X + RTS +end +;defn isnum(c) +; if c >= '0' and c <= '9' +; return TRUE +; fin +; return FALSE +;end +asm isnum + LDY #$00 + LDA ESTKL,X + CMP #'0' + BCC :+ + CMP #'9'+1 + BCS :+ + DEY +: STY ESTKL,X + STY ESTKH,X + RTS +end +;defn isalphanum(c) +; if c >= 'A' and c <= 'Z' +; return TRUE +; elsif c >= '0' and c <= '9' +; return TRUE +; elsif c >= 'a' and c <= 'z' +; return TRUE +; elsif c == '_' +; return TRUE +; fin +; return FALSE +;end +asm isalphanum + LDY #$00 + LDA ESTKL,X + CMP #'0' + BCC ISANRET + CMP #'9'+1 + BCS :+ + DEY + BNE ISANRET +: CMP #'A' + BCC ISANRET + CMP #'Z'+1 + BCS :+ + DEY + BNE ISANRET +: CMP #'a' + BCC ISANRET + CMP #'z'+1 + BCS :+ + DEY + BNE ISANRET +: CMP #'_' + BNE ISANRET + DEY +ISANRET: + STY ESTKL,X + STY ESTKH,X + RTS +end +defn keymatch(chrptr, len) + byte i, keypos + + keypos = 0 + while keywrds[keypos] < len + keypos = keypos + keywrds[keypos] + 2 + loop + while keywrds[keypos] == len + for i = 1 to len + if toupper((chrptr).[i - 1]) <> keywrds[keypos + i] + break + fin + next + if i > len + return keywrds[keypos + keywrds[keypos] + 1] + fin + keypos = keypos + keywrds[keypos] + 2 + loop + return ID_TKN +end +defn skipspace + ; + ; Skip whitespace + ; + while ^scanptr and ^scanptr <= ' ' + scanptr = scanptr + 1 + loop + tknptr = scanptr + return !^scanptr or ^scanptr == ';' +end +deft scan + ; + ; Scan for token based on first character + ; + if skipspace + if token <> Eis_TKN + token = EOL_TKN + fin + elsif isalpha(^scanptr) + ; + ; ID, either variable name or reserved word + ; + repeat + scanptr = scanptr + 1 + until !isalphanum(^scanptr) + tknlen = scanptr - tknptr; + token = keymatch(tknptr, tknlen) + elsif isnum(^scanptr) + ; + ; Number constant + ; + token = INT_TKN + constval = 0 + repeat + constval = constval * 10 + ^scanptr - '0' + scanptr = scanptr + 1 + until !isnum(^scanptr) + elsif ^scanptr == '$' + ; + ; Hexadecimal constant + ; + token = INT_TKN; + constval = 0 + repeat + scanptr = scanptr + 1 + if ^scanptr >= '0' and ^scanptr <= '9' + constval = (constval << 4) + ^scanptr - '0' + elsif ^scanptr >= 'A' and ^scanptr <= 'F' + constval = (constval << 4) + ^scanptr - '7'; 'A'-10 + elsif ^scanptr >= 'a' and ^scanptr <= 'f' + constval = (constval << 4) + ^scanptr - 'W'; 'a'-10 + else + break; + fin + until !^scanptr + elsif ^scanptr == $27 ; ' + ; + ; Character constant + ; + token = CHR_TKN + if ^(scanptr + 1) <> $5C ; \ + constval = ^(scanptr + 1) + if ^(scanptr + 2) <> $27 ; ' + return parse_err(@bad_cnst) + fin + scanptr = scanptr + 3 + else + when ^(scanptr + 2) + is 'n' + constval = $0D + is 'r' + constval = $0A + is 't' + constval = $09 + otherwise + constval = ^(scanptr + 2) + wend + if ^(scanptr + 3) <> $27 ; ' + return parse_err(@bad_cnst) + fin + scanptr = scanptr + 4 + fin + elsif ^scanptr == '"' + ; + ; String constant + ; + token = STR_TKN + scanptr = scanptr + 1 + constval = scanptr + while ^scanptr and ^scanptr <> '"' + scanptr = scanptr + 1 + loop + if !^scanptr + return parse_err(@bad_cnst) + fin + scanptr = scanptr + 1 + else + ; + ; Potential two and three character tokens + ; + when ^scanptr + is '>' + if ^(scanptr + 1) == '>' + token = SHR_TKN + scanptr = scanptr + 2 + elsif ^(scanptr + 1) == '=' + token = GE_TKN + scanptr = scanptr + 2 + else + token = GT_TKN + scanptr = scanptr + 1 + fin + is '<' + if ^(scanptr + 1) == '<' + token = SHL_TKN + scanptr = scanptr + 2 + elsif ^(scanptr + 1) == '=' + token = LE_TKN + scanptr = scanptr + 2 + elsif ^(scanptr + 1) == '>' + token = NE_TKN + scanptr = scanptr + 2 + else + token = LT_TKN + scanptr = scanptr + 1 + fin + is '=' + if ^(scanptr + 1) == '=' + token = EQ_TKN + scanptr = scanptr + 2; + else + token = SET_TKN; + scanptr = scanptr + 1 + fin + otherwise + ; + ; Simple single character tokens + ; + token = ^scanptr ? $80 + scanptr = scanptr + 1 + wend + fin + tknlen = scanptr - tknptr + return token +end +def rewind(ptr) + scanptr = ptr +end +; +; Get next line is input +; +def nextln + byte i, chr + + scanptr = inbuff + ^$33 = $BA + ^instr = read(inref, inbuff, $80) + inbuff[^instr] = $00 + if ^instr + lineno = lineno + 1 + if !(lineno & $0F) + cout('.') + fin +; cout('>') +; prstr(instr) +; crout + scan + else + ^instr = 0 + ^inbuff = $00 + token = DONE_TKN + fin + return ^instr +end +; +; Alebraic op to stack op +; +def push_op(op, prec) + opsp = opsp + 1 + if opsp == 16 + return parse_err(@estk_overflw) + fin + opstack[opsp] = op + precstack[opsp] = prec +end +def pop_op + if opsp < 0 + return parse_err(@estk_underflw) + fin + opsp = opsp - 1 + return opstack[opsp + 1] +end +def tos_op + if opsp < 0 + return 0 + fin + return opstack[opsp] +end +def tos_op_prec(tos) + if opsp <= tos + return 100 + fin + return precstack[opsp] +end +; +; Symbol table +; +deft idmatch(nameptr, len, idptr, idcnt) + byte i + + while idcnt + if len == (idptr).idname + for i = 1 to len + if (nameptr).[i - 1] <> (idptr).idname.[i] + break + fin + next + if i > len + return idptr + fin + fin + idptr = idptr + (idptr).idname + idrecsz + idcnt = idcnt - 1 + loop + return 0 +end +def dumpsym(idptr, idcnt) + while idcnt + prword((idptr):idval) + cout(' ') + prbyte((idptr).idtype) + cout(' ') + prstr(@(idptr).idname) + cout('=') + if (idptr).idtype & ADDR_TYPE + if (idptr):idval & is_ctag + prword(ctag_value:[(idptr):idval & mask_ctag]) + else + prword((idptr):idval + codebuff) + fin + else + prword((idptr):idval) + fin + crout + idptr = idptr + (idptr).idname + idrecsz + idcnt = idcnt - 1 + loop +end +def id_lookup(nameptr, len) + word idptr + + idptr = idmatch(nameptr, len, idlocal_tbl, locals) + if idptr + return idptr + fin + idptr = idmatch(nameptr, len, idglobal_tbl, globals) + if idptr + return idptr + fin + return parse_err(@undecl_id) +end +def idglobal_lookup(nameptr, len) + return idmatch(nameptr, len, idglobal_tbl, globals) +end +def idlocal_add(namestr, len, type, size) + if idmatch(namestr, len, @idlocal_tbl, locals) + return parse_err(@dup_id) + fin + (lastlocal):idval = framesize + (lastlocal).idtype = type ? LOCAL_TYPE + nametostr(namestr, len, lastlocal + idname) + locals = locals + 1 + lastlocal = lastlocal + idrecsz + len + if lastlocal > idlocal_tbl + idlocal_tblsz + prstr(@local_sym_overflw) + exit + fin + framesize = framesize + size + if framesize > 255 + prstr(@local_overflw) + return FALSE + fin + return TRUE +end +def iddata_add(namestr, len, type, size) + if idmatch(namestr, len, idglobal_tbl, globals) + return parse_err(@dup_id) + fin + (lastglobal):idval = datasize + (lastglobal).idtype = type + nametostr(namestr, len, lastglobal + idname) + emit_iddata(datasize, size, lastglobal + idname) + globals = globals + 1 + lastglobal = lastglobal + idrecsz + len + if lastglobal > idglobal_tbl + idglobal_tblsz + prstr(@global_sym_overflw) + exit + fin + datasize = datasize + size + return TRUE +end +def iddata_size(type, varsize, initsize) + if varsize > initsize + datasize = datasize + emit_data(0, 0, 0, varsize - initsize) + else + datasize = datasize + initsize + fin +; if datasize <> codeptr - codebuff +; prstr(@emiterr) +; keyin() +; fin +end +def idglobal_add(namestr, len, type, value) + if idmatch(namestr, len, idglobal_tbl, globals) + return parse_err(@dup_id) + fin + (lastglobal):idval = value + (lastglobal).idtype = type + nametostr(namestr, len, lastglobal + idname) + globals = globals + 1 + lastglobal = lastglobal + idrecsz + len + if lastglobal > idglobal_tbl + idglobal_tblsz + prstr(@global_sym_overflw) + exit + fin + return TRUE +end +def idfunc_add(namestr, len, tag) + return idglobal_add(namestr, len, FUNC_TYPE, tag) +end +def idconst_add(namestr, len, value) + return idglobal_add(namestr, len, CONST_TYPE, value) +end +def idglobal_init + word ctag + + lineno = 0 + parserr = 0 + codeptr = codebuff + lastop = $FF + entrypoint = 0 + datasize = 0 + globals = 0 + lastglobal = idglobal_tbl + codetag = -1 + ctag = ctag_new + idfunc_add(@runtime0 + 1, runtime0, ctag) + idfunc_add(@RUNTIME0 + 1, RUNTIME0, ctag) + ctag_resolve(ctag, @romcall) + ctag = ctag_new + idfunc_add(@runtime1 + 1, runtime1, ctag) + idfunc_add(@RUNTIME1 + 1, RUNTIME1, ctag) + ctag_resolve(ctag, @syscall) + ctag = ctag_new + idfunc_add(@runtime2 + 1, runtime2, ctag) + idfunc_add(@RUNTIME2 + 1, RUNTIME2, ctag) + ctag_resolve(ctag, @memset) + ctag = ctag_new + idfunc_add(@runtime3 + 1, runtime3, ctag) + idfunc_add(@RUNTIME3 + 1, RUNTIME3, ctag) + ctag_resolve(ctag, @memcpy) + ctag = ctag_new + idfunc_add(@runtime4 + 1, runtime4, ctag) + idfunc_add(@RUNTIME4 + 1, RUNTIME4, ctag) + ctag_resolve(ctag, @cout) + ctag = ctag_new + idfunc_add(@runtime5 + 1, runtime5, ctag) + idfunc_add(@RUNTIME5 + 1, RUNTIME5, ctag) + ctag_resolve(ctag, @cin) + ctag = ctag_new + idfunc_add(@runtime6 + 1, runtime6, ctag) + idfunc_add(@RUNTIME6 + 1, RUNTIME6, ctag) + ctag_resolve(ctag, @prstr) + ctag = ctag_new + idfunc_add(@runtime7 + 1, runtime7, ctag) + idfunc_add(@RUNTIME7 + 1, RUNTIME7, ctag) + ctag_resolve(ctag, @rdstr) +end +def idlocal_init + locals = 0 + framesize = 2 + lastlocal = idlocal_tbl +end +; +; Parser +; +def parse_term + when scan + is ID_TKN + return TRUE + is INT_TKN + return TRUE + is CHR_TKN + return TRUE + is STR_TKN + return TRUE + is OPEN_PAREN_TKN + if !parse_expr + return FALSE + fin + if token <> CLOSE_PAREN_TKN + return parse_err(@no_close_paren) + fin + return TRUE + wend + return FALSE +end +def parse_constval(valptr, sizeptr) + byte mod, type + word idptr + + mod = 0 + type = 0 + *valptr = 0 + while !parse_term + when token + is SUB_TKN + mod = mod ? 1 + is COMP_TKN + mod = mod ? 2 + is LOGIC_NOT_TKN + mod = mod ? 4 + is AT_TKN + mod = mod ? 8 + otherwise + return 0 + wend + loop + when token + is STR_TKN + *valptr = constval + ^sizeptr = tknlen - 1 + type = STR_TYPE + if mod + return parse_err(@bad_op) + fin + is CHR_TKN + *valptr = constval + ^sizeptr = 1 + type = BYTE_TYPE + is INT_TKN + *valptr = constval + ^sizeptr = 2 + type = WORD_TYPE + is ID_TKN + ^sizeptr = 2 + idptr = id_lookup(tknptr, tknlen) + if !idptr + return parse_err(@bad_cnst) + fin + type = (idptr).idtype + *valptr = (idptr):idval + if type & VAR_TYPE and !(mod & 8) + return parse_err(@bad_cnst) + fin + otherwise + return parse_err(@bad_cnst) + wend + if mod & 1 + *valptr = -*valptr + fin + if mod & 2 + *valptr = #*valptr + fin + if mod & 4 + *valptr = !*valptr + fin + return type +end +deft ispostop + scan + when token + is OPEN_PAREN_TKN + return TRUE + is OPEN_BRACKET_TKN + return TRUE + is DOT_TKN + return TRUE + is COLON_TKN + return TRUE + wend + return FALSE +end +deft parse_value(rvalue) + byte cparams, deref, type, emit_val + word optos, idptr, value + byte elem_type, elem_size + word elem_isfset + + deref = rvalue + optos = opsp + type = 0 + emit_val = FALSE + value = 0 + + ; + ; Parse pre-ops + ; + while !parse_term + when token + is ADD_TKN + is BPTR_TKN + if deref + push_op(token, 0) + else + type = type ? BPTR_TYPE + deref = deref + 1 + fin + is WPTR_TKN + if deref + push_op(token, 0) + else + type = type ? WPTR_TYPE + deref = deref + 1 + fin + is AT_TKN + deref = deref - 1 + is SUB_TKN + push_op(token, 0) + is COMP_TKN + push_op(token, 0) + is LOGIC_NOT_TKN + push_op(token, 0) + otherwise + return 0 + wend + loop + ; + ; Determine terminal type + ; + when token + is INT_TKN + type = type ? CONST_TYPE + value = constval + is CHR_TKN + type = type ? CONST_TYPE + value = constval + is ID_TKN + idptr = id_lookup(tknptr, tknlen) + if !idptr + return 0 + fin + if !(idptr).idtype + return 0 + fin + type = type ? (idptr).idtype + value = (idptr):idval + is CLOSE_PAREN_TKN + type = type ? WORD_TYPE + emit_val = TRUE + otherwise + return 0 + wend + ; + ; Constant optimizations + ; + if type & CONST_TYPE + cparams = TRUE + while optos < opsp and cparams + when tos_op + is NEG_TKN + pop_op + value = -value + is COMP_TKN + pop_op + value = #value + is LOGIC_NOT_TKN + pop_op + value = !value + otherwise + cparams = FALSE + wend + loop + fin + ; + ; Parse post-ops + ; + while ispostop + if token == OPEN_BRACKET_TKN + ; + ; Array + ; + if !emit_val + if type & ADDR_TYPE + if type & LOCAL_TYPE + emit_localaddr(value) + else + emit_globaladdr(value) + fin + elsif type & CONST_TYPE + emit_const(value) + fin + emit_val = TRUE + fin ; !emit_val + if type & PTR_TYPE + emit_lw + fin + if !parse_expr + return 0 + fin + if token <> CLOSE_BRACKET_TKN + return parse_err(@no_close_bracket) + fin + if type & WORD_TYPE + type = WPTR_TYPE + emit_indexword + else + type = BPTR_TYPE + emit_indexbyte + fin + elsif token == DOT_TKN or token == COLON_TKN + ; + ; Dot and Colon + ; + if token == DOT_TKN + elem_type = BPTR_TYPE + else + elem_type = WPTR_TYPE + fin + if parse_constval(@elem_isfset, @elem_size) + ; + ; Constant structure isfset + ; + if !emit_val + if type & VAR_TYPE + if type & LOCAL_TYPE + emit_localaddr(value + elem_isfset) + else + ; emit_globaladdr(value + elem_isfset) + emit_globaladdr(value) + emit_const(elem_isfset) + emit_binaryop(ADD_TKN) + fin + elsif type & CONST_TYPE + value = value + elem_isfset + emit_const(value) + else ; FUNC_TYPE + emit_globaladdr(value) + emit_const(elem_isfset) + emit_binaryop(ADD_TKN) + fin + emit_val = TRUE + else + if elem_isfset <> 0 + emit_const(elem_isfset) + emit_binaryop(ADD_TKN) + fin + fin ; !emit_val + elsif token == OPEN_BRACKET_TKN + ; + ; Array is arrays + ; + if !emit_val + if type & ADDR_TYPE + if type & LOCAL_TYPE + emit_localaddr(value) + else + emit_globaladdr(value) + fin + elsif type & CONST_TYPE + emit_const(value) + fin + emit_val = TRUE + fin ; !emit_val + while parse_expr + if token <> COMMA_TKN + break + fin + emit_indexword + emit_lw + loop + if token <> CLOSE_BRACKET_TKN + return parse_err(@no_close_bracket) + fin + if elem_type & WPTR_TYPE + emit_indexword + else + emit_indexbyte + fin + else + return parse_err(@bad_isfset) + fin + type = elem_type + elsif token == OPEN_PAREN_TKN + ; + ; Function call + ; + if !emit_val and type & VAR_TYPE + if type & LOCAL_TYPE + emit_localaddr(value) + else + emit_globaladdr(value) + fin + fin + if !(type & FUNC_CONST_TYPE) + emit_push + fin + cparams = 0 + while parse_expr + cparams = cparams + 1 + if token <> COMMA_TKN + break + fin + loop + if token <> CLOSE_PAREN_TKN + return parse_err(@no_close_paren) + fin + if type & FUNC_CONST_TYPE + emit_call(value, cparams) + else + emit_pull + emit_ical(cparams) + fin + emit_val = TRUE + type = WORD_TYPE + fin + loop + if emit_val + if rvalue + if deref and type & PTR_TYPE + if type & BPTR_TYPE + emit_lb + else + emit_lw + fin + fin + fin + else ; emit_val + if type & CONST_TYPE + emit_const(value) + elsif deref + if type & FUNC_TYPE + emit_call(value, 0) + elsif type & VAR_TYPE + if type & LOCAL_TYPE + if type & BYTE_TYPE + emit_llb(value) + else + emit_llw(value) + fin + else + if type & BYTE_TYPE + emit_lab(value) + else + emit_law(value) + fin + fin + elsif type & PTR_TYPE + if type & BPTR_TYPE + emit_lb + else + emit_lw + fin + fin + else + if type & LOCAL_TYPE + emit_localaddr(value) + else + emit_globaladdr(value) + fin + fin + fin ; emit_val + while optos < opsp + if !emit_unaryop(pop_op) + return parse_err(@bad_op) + fin + loop + return type +end +def parse_constexpr(valptr, sizeptr) + byte type, size1, size2 + word val1, val2 + + type = parse_constval(@val1, @size1) + if !type + return 0 + fin + size2 = 0 + when scan + is ADD_TKN + type = parse_constval(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 + val2 + is SUB_TKN + type = parse_constval(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 - val2 + is MUL_TKN + type = parse_constval(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 * val2 + is DIV_TKN + type = parse_constval(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 + val2 + is MOD_TKN + type = parse_constval(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 % val2 + is AND_TKN + type = parse_constval(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 & val2 + is OR_TKN + type = parse_constval(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 ? val2 + is EOR_TKN + type = parse_constval(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 ^ val2 + otherwise + *valptr = val1 + wend + if size1 > size2 + ^sizeptr = size1 + else + ^sizeptr = size2 + fin + return type +end +deft parse_expr + byte prevmatch, matchop, i + word optos + + matchop = 0 + optos = opsp + repeat + prevmatch = matchop + matchop = 0 + if parse_value(1) + matchop = 1 + for i = 0 to bops_tblsz + if token == bops_tbl[i] + matchop = 2 + if bops_prec[i] >= tos_op_prec(optos) + if !emit_binaryop(pop_op) + return parse_err(@bad_op) + fin + fin + push_op(token, bops_prec[i]) + break + fin + next + fin + until matchop <> 2 + if matchop == 0 and prevmatch == 2 + return parse_err(@missing_op) + fin + while optos < opsp + if !emit_binaryop(pop_op) + return parse_err(@bad_op) + fin + loop + return matchop or prevmatch +end +def parse_stmnt + byte type, i + word tag_prevbrk, tag_else, tag_endif, tag_while, tag_wend + word tag_repeat, tag_for, tag_choice, idptr, saveptr, addr, stepdir + + if token <> END_TKN and token <> DONE_TKN + prevstmnt = token + fin + when token + is IF_TKN + if !parse_expr + return 0 + fin + tag_else = ctag_new + tag_endif = ctag_new + emit_brfls(tag_else) + scan + repeat + while parse_stmnt + nextln + loop + if token <> ELSEIF_TKN + break + fin + emit_jump(tag_endif) + emit_codetag(tag_else) + if !parse_expr + return 0 + fin + tag_else = ctag_new + emit_brfls(tag_else) + until FALSE + if token == ELSE_TKN + emit_jump(tag_endif) + emit_codetag(tag_else) + scan + while parse_stmnt + nextln + loop + emit_codetag(tag_endif) + else + emit_codetag(tag_else) + emit_codetag(tag_endif) + fin + if token <> FIN_TKN + return parse_err(@no_fin) + fin + is FOR_TKN + stack_loop = stack_loop + 1 + tag_for = ctag_new + tag_prevbrk = break_tag + break_tag = ctag_new + if scan <> ID_TKN + return parse_err(@bad_stmnt) + fin + idptr = id_lookup(tknptr, tknlen) + if idptr + type = (idptr).idtype + addr = (idptr):idval + else + return FALSE + fin + if scan <> SET_TKN + return parse_err(@bad_stmnt) + fin + if !parse_expr + return parse_err(@bad_stmnt) + fin + emit_codetag(tag_for) + if type & LOCAL_TYPE + if type & BYTE_TYPE + emit_dlb(addr) + else + emit_dlw(addr) + fin + else + if type & BYTE_TYPE + emit_dab(addr) + else + emit_daw(addr) + fin + fin + if token == TO_TKN + stepdir = 1 + elsif token == DOWNTO_TKN + stepdir = -1 + else + return parse_err(@bad_stmnt) + fin + if !parse_expr + return parse_err(@bad_stmnt) + fin + if stepdir > 0 + emit_brgt(break_tag) + else + emit_brlt(break_tag) + fin + if token == STEP_TKN + if !parse_expr + return parse_err(@bad_stmnt) + fin + if stepdir > 0 + emit_binaryop(ADD_TKN) + else + emit_binaryop(SUB_TKN) + fin + else + if stepdir > 0 + emit_unaryop(INC_TKN) + else + emit_unaryop(DEC_TKN) + fin + fin + while parse_stmnt + nextln + loop + if token <> NEXT_TKN + return parse_err(@bad_stmnt) + fin + emit_jump(tag_for) + emit_codetag(break_tag) + emit_drop + break_tag = tag_prevbrk + stack_loop = stack_loop - 1 + is WHILE_TKN + tag_while = ctag_new + tag_wend = ctag_new + tag_prevbrk = break_tag + break_tag = tag_wend + emit_codetag(tag_while) + if !parse_expr + return 0 + fin + emit_brfls(tag_wend) + while parse_stmnt + nextln + loop + if token <> LOOP_TKN + return parse_err(@no_loop) + fin + emit_jump(tag_while) + emit_codetag(tag_wend) + break_tag = tag_prevbrk + is REPEAT_TKN + tag_repeat = ctag_new + tag_prevbrk = break_tag + break_tag = ctag_new + emit_codetag(tag_repeat) + scan + while parse_stmnt + nextln + loop + if token <> UNTIL_TKN + return parse_err(@no_until) + fin + if !parse_expr + return 0 + fin + emit_brfls(tag_repeat) + emit_codetag(break_tag) + break_tag = tag_prevbrk + is when_TKN + stack_loop = stack_loop + 1 + tag_choice = ctag_new + tag_prevbrk = break_tag + break_tag = ctag_new + if !parse_expr + return parse_err(@bad_stmnt) + fin + nextln + while token <> ENDwhen_TKN + when token + is is_TKN + if !parse_expr + return parse_err(@bad_stmnt) + fin + emit_brne(tag_choice) + while parse_stmnt + nextln + loop + emit_jump(break_tag) + emit_codetag(tag_choice) + tag_choice = ctag_new + is DEFAULT_TKN + scan + while parse_stmnt + nextln + loop + if token <> ENDwhen_TKN + return parse_err(@bad_stmnt) + fin + otherwise + return parse_err(@bad_stmnt) + wend + loop + emit_codetag(break_tag) + emit_drop + break_tag = tag_prevbrk + stack_loop = stack_loop - 1 + is BREAK_TKN + if break_tag + emit_jump(break_tag) + else + return parse_err(@bad_stmnt) + fin + is RETURN_TKN + if infunc + for i = 1 to stack_loop + emit_drop + next + if !parse_expr + emit_const(0) + fin + emit_leave(framesize) + else + return parse_err(@bad_stmnt) + fin + is EXIT_TKN + if !parse_expr + emit_const(0) + fin + emit_exit + is ELSE_TKN + return FALSE + is ELSEIF_TKN + return FALSE + is FIN_TKN + return FALSE + is LOOP_TKN + return FALSE + is UNTIL_TKN + return FALSE + is NEXT_TKN + return FALSE + is is_TKN + return FALSE + is DEFAULT_TKN + return FALSE + is ENDwhen_TKN + return FALSE + is END_TKN + return FALSE + is DONE_TKN + return FALSE + is IFUNC_TKN + return FALSE + is TFUNC_TKN + return FALSE + is NFUNC_TKN + return FALSE + is Eis_TKN + return FALSE + is EOL_TKN + return TRUE + otherwise + if token == ID_TKN + saveptr = tknptr + idptr = id_lookup(tknptr, tknlen) + if !idptr + return FALSE + fin + type = (idptr).idtype + if type & ADDR_TYPE + addr = (idptr):idval + if scan == SET_TKN + if type & VAR_TYPE + if !parse_expr + return parse_err(@bad_expr) + fin + if type & LOCAL_TYPE + if type & BYTE_TYPE + emit_slb(addr) + else + emit_slw(addr) + fin + else + if type & BYTE_TYPE + emit_sab(addr) + else + emit_saw(addr) + fin + fin + return TRUE + fin + elsif token == EOL_TKN and type & FUNC_TYPE + emit_call(addr, 0) + emit_drop + return TRUE + fin + fin + tknptr = saveptr + fin + rewind(tknptr) + type = parse_value(0) + if type + if token == SET_TKN + if !parse_expr + return parse_err(@bad_expr) + fin + if type & XBYTE_TYPE + emit_sb + else + emit_sw + fin + else + if type & BPTR_TYPE + emit_lb + elsif type & WPTR_TYPE + emit_lw + fin + emit_drop + fin + else + return parse_err(@bad_syntax) + fin + wend + if scan <> EOL_TKN + return parse_err(@bad_syntax) + fin + return TRUE +end +def parse_var(type) + byte consttype, constsize, idlen + word idptr, constval, arraysize, size + + idlen = 0 + size = 1 + if scan == ID_TKN + idptr = tknptr + idlen = tknlen + if scan == OPEN_BRACKET_TKN + size = 0 + parse_constexpr(@size, @constsize) + if token <> CLOSE_BRACKET_TKN + return parse_err(@no_close_bracket) + fin + scan + fin + fin + if type == WORD_TYPE + size = size * 2 + fin + if token == SET_TKN + if infunc + return parse_err(@no_local_init) + fin + if idlen + iddata_add(idptr, idlen, type, 0) + fin + consttype = parse_constexpr(@constval, @constsize) + if consttype + arraysize = emit_data(type, consttype, constval, constsize) + while token == COMMA_TKN + consttype = parse_constexpr(@constval, @constsize) + if consttype + arraysize = arraysize + emit_data(type, consttype, constval, constsize) + else + return parse_err(@bad_decl) + fin + loop + if token <> EOL_TKN + return parse_err(@no_close_bracket) + fin + iddata_size(PTR_TYPE, size, arraysize); + else + return parse_err(@bad_decl) + fin + elsif idlen + if infunc + idlocal_add(idptr, idlen, type, size) + else + iddata_add(idptr, idlen, type, size) + fin + fin + return TRUE +end +def parse_vars + byte idlen, type, size + word value, idptr + + when token + is CONST_TKN + if scan <> ID_TKN + return parse_err(@bad_cnst) + fin + idptr = tknptr; + idlen = tknlen + if scan <> SET_TKN + return parse_err(@bad_cnst) + fin + if !parse_constexpr(@value, @size) + return parse_err(@bad_cnst) + fin + idconst_add(idptr, idlen, value) + is BYTE_TKN + type = BYTE_TYPE + repeat + if !parse_var(type) + return FALSE + fin + until token <> COMMA_TKN + is WORD_TKN + type = WORD_TYPE + repeat + if !parse_var(type) + return FALSE + fin + until token <> COMMA_TKN + is FUNC_TKN + repeat + if scan == ID_TKN + idfunc_add(tknptr, tknlen, ctag_new) + else + return parse_err(@bad_decl) + fin + until scan <> COMMA_TKN + is EOL_TKN + return TRUE + otherwise + return FALSE + wend + return TRUE +end +def parse_func + byte defopt, cfnparms + word func_tag, idptr + + if token == IFUNC_TKN or token == TFUNC_TKN or token == NFUNC_TKN + defopt = token - IFUNC_TKN + if scan <> ID_TKN + return parse_err(@bad_decl) + fin + cfnparms = 0 + infunc = TRUE + idptr = idglobal_lookup(tknptr, tknlen) + if idptr + func_tag = (idptr):idval + else + func_tag = ctag_new + idfunc_add(tknptr, tknlen, func_tag) + fin + emit_codetag(func_tag) + retfunc_tag = ctag_new + idlocal_init + if scan == OPEN_PAREN_TKN + repeat + if scan == ID_TKN + cfnparms = cfnparms + 1 + idlocal_add(tknptr, tknlen, WORD_TYPE, 2) + scan + fin + until token <> COMMA_TKN + if token <> CLOSE_PAREN_TKN + return parse_err(@bad_decl) + fin + scan + fin + while parse_vars + nextln + loop + emit_enter(framesize, cfnparms) + prevstmnt = 0 + while parse_stmnt + nextln + loop + infunc = FALSE + if token <> END_TKN + return parse_err(@bad_syntax) + fin + if scan <> EOL_TKN + return parse_err(@bad_syntax) + fin + if prevstmnt <> RETURN_TKN + emit_const(0) + emit_leave(framesize) + fin + return TRUE + elsif token == EOL_TKN + return TRUE + fin + return FALSE +end +def parse_module + entrypoint = 0 + idglobal_init + idlocal_init + if nextln + while parse_vars + nextln + loop + while parse_func + nextln + loop + if token <> DONE_TKN + emit_start + prevstmnt = 0 + while parse_stmnt + nextln + loop + if token <> DONE_TKN + parse_err(@no_done) + fin + if prevstmnt <> EXIT_TKN + emit_const(0) + emit_exit + fin + fin + ; dumpsym(idglobal_tbl, globals) + ; prstr(@entrypt_str) + ; prword(entrypoint) + ; crout + ; keyin() + return TRUE + fin + return FALSE +end +; +; PLASMA Compiler +; +inref = open(rdstr($BA), infile_buff) +if inref + newline(inref, $7F, $0D) + if parse_module + close(inref) + prstr(@comp_ok_msg) + (entrypoint)() + else + close(inref) + cin + fin +; crout +; dumpsym(@idglobal_tbl, globals) +; crout +fin +done diff --git a/plasma2/plc b/plasma2/plc new file mode 100755 index 0000000..fd8c9dc Binary files /dev/null and b/plasma2/plc differ diff --git a/plasma2/pled#ff0000 b/plasma2/pled#ff0000 new file mode 100755 index 0000000..68fa4a9 Binary files /dev/null and b/plasma2/pled#ff0000 differ diff --git a/plasma2/pled.pla b/plasma2/pled.pla new file mode 100755 index 0000000..a92619f --- /dev/null +++ b/plasma2/pled.pla @@ -0,0 +1,1476 @@ +; +; Global constants +; +const FALSE = 0 +const TRUE = !FALSE +; +; Hardware constants +; +const csw = $0036 +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 pushbttn1 = $C061 +const pushbttn2 = $C062 +const pushbttn3 = $C063 +const keyboard = $C000 +const keystrobe = $C010 +const keyenter = $8D +const keyspace = $A0 +const keyarrowup = $8B +const keyarrowdown = $8A +const keyarrowleft = $88 +const keyarrowright = $95 +const keyescape = $9B +const keyctrla = $81 +const keyctrlb = $82 +const keyctrlc = $83 +const keyctrld = $84 +const keyctrle = $85 +const keyctrli = $89 +const keyctrlk = $8B +const keyctrll = $8C +const keyctrln = $8E +const keyctrlo = $8F +const keyctrlp = $90 +const keyctrlq = $91 +const keyctrlr = $92 +const keyctrls = $93 +const keyctrlt = $94 +const keyctrlu = $95 +const keyctrlv = $96 +const keyctrlw = $97 +const keyctrlx = $98 +const keyctrlz = $9A +const keydelete = $FF +const getbuff = $01FF +const argbuff = $2006 +word txtscrn[] = $0400,$0480,$0500,$0580,$0600,$0680,$0700,$0780 +word = $0428,$04A8,$0528,$05A8,$0628,$06A8,$0728,$07A8 +word = $0450,$04D0,$0550,$05D0,$0650,$06D0,$0750,$07D0 +; +; Data and text buffer constants +; +const machid = $BF98 +const maxlines = 1500 +const maxfill = 1524 +const iobuffer = $0800 +const databuff = $0C00 +const strlinbuf = $1000 +const strheapmap = $1F00 +const strheapmsz = 224 ; $E0 = 28K is memory@16 bytes per bit map, 128 bytes per 8 bit map, 1K bytes per 8 byte map +const maxlnlen = 79 +const strheap = $4800 +const strheasz = $7000 +const pgjmp = 16 +const changed = 1 +const insmode = 2 +const showcurs = 4 +const uppercase = 8 +const shiftlock = 128 +; +; Editor variables +; +byte nullstr[] = "" +byte version[] = "PLASMA ][ EDITOR VERSION 0.8 " +byte errorstr[] = "ERROR: $" +byte okstr[] = "OK" +byte perr +byte outofmem[] = "OUT OF MEMORY!" +byte losechng[] = "LOSE CHANGES TO FILE (Y/N)?" +;byte emiterr[] = "EMIT CODE/DATA MISMATCH" +byte untitled[] = "UNTITLED" +byte txtfile[64] = "UNTITLED.PLA" +byte flags = 0 +byte flash = 0 +byte cursx, cursy, scrnleft, curscol, underchr, curschr +word cursrow, scrntop, cursptr +word numlines = 0 +word cutbuf = 0 +word keyin_01 +; +; Predeclared functions +; +func cmdmode +; +; Utility functions +; +; Defines for ASM routines +; +asm equates + TMP EQU $F0 + TMPL EQU TMP + TMPH EQU TMP+1 + SRC EQU TMP + SRCL EQU SRC + SRCH EQU SRC+1 + DST EQU SRC+2 + DSTL EQU DST + DSTH EQU DST+1 + ESP EQU DST+2 +end +; CALL 6502 ROUTINE +; ROMCALL(AREG, XREG, YREG, STATUS, ADDR) +; +asm romcall + PHP + LDA ESTKL,X + STA TMPL + LDA ESTKH,X + STA TMPH + INX + LDA ESTKL,X + PHA + INX + LDA ESTKL,X + TAY + INX + LDA ESTKL+1,X + PHA + LDA ESTKL,X + INX + STX ESP + TAX + PLA + BIT ROMIN + PLP + JSR JMPTMP + PHP + BIT LCBNK2 + STA REGVALS+0 + STX REGVALS+1 + STY REGVALS+2 + PLA + STA REGVALS+3 + LDX ESP + LDA #REGVALS + STA ESTKL,X + STY ESTKH,X + PLP + RTS +JMPTMP: JMP (TMP) +REGVALS: DS 4 +end +; +; CALL PRODOS +; SYSCALL(CMD, PARAMS) +; +asm syscall + LDA ESTKL,X + LDY ESTKH,X + STA PARAMS + STY PARAMS+1 + INX + LDA ESTKL,X + STA CMD + STX ESP + JSR $BF00 +CMD: DB 00 +PARAMS: DW 0000 + BIT LCBNK2 + LDX ESP + STA ESTKL,X + LDY #$00 + STY ESTKH,X +end +; +; SET MEMORY TO VALUE +; MEMSET(VALUE, ADDR, SIZE) +; +asm memset + LDY #$00 + LDA ESTKL+1,X + STA DSTL + LDA ESTKH+1,X + STA DSTH + INC ESTKL,X + INC ESTKH,X +SETMEM: DEC ESTKL,X + BNE :+ + DEC ESTKH,X + BEQ MEMEXIT +: LDA ESTKL+2,X + STA (DST),Y + INY + BNE :+ + INC DSTH +: DEC ESTKL,X + BNE :+ + DEC ESTKH,X + BEQ MEMEXIT +: LDA ESTKH+2,X + STA (DST),Y + INY + BNE SETMEM + INC DSTH + BNE SETMEM +MEMEXIT: INX + INX + INX +end +; +; COPY MEMORY +; MEMCPY(SRCADDR, DSTADDR, SIZE) +; +asm memcpy + LDY #$00 + LDA ESTKL,X + BNE :+ + LDA ESTKH,X + BEQ MEMEXIT +: LDA ESTKL+1,X + STA DSTL + LDA ESTKH+1,X + STA DSTH + LDA ESTKL+2,X + STA SRCL + LDA ESTKH+2,X + STA SRCH + CMP DSTH + BCC REVCPY + BNE FORCPY + LDA SRCL + CMP DSTL + BCS FORCPY +REVCPY: ; REVERSE DIRECTION COPY +; CLC + LDA ESTKL,X + ADC DSTL + STA DSTL + LDA ESTKH,X + ADC DSTH + STA DSTH + CLC + LDA ESTKL,X + ADC SRCL + STA SRCL + LDA ESTKH,X + ADC SRCH + STA SRCH + INC ESTKH,X +REVCPYLP: + LDA DSTL + BNE :+ + DEC DSTH +: DEC DSTL + LDA SRCL + BNE :+ + DEC SRCH +: DEC SRCL + LDA (SRC),Y + STA (DST),Y + DEC ESTKL,X + BNE REVCPYLP + DEC ESTKH,X + BNE REVCPYLP + BEQ MEMEXIT +FORCPY: INC ESTKH,X +FORCPYLP: + LDA (SRC),Y + STA (DST),Y + INC DSTL + BNE :+ + INC DSTH +: INC SRCL + BNE :+ + INC SRCH +: DEC ESTKL,X + BNE FORCPYLP + DEC ESTKH,X + BNE FORCPYLP + BEQ MEMEXIT +end +; +; CHAR OUT +; COUT(CHAR) +; +asm cout + LDA ESTKL,X + INX + ORA #$80 + BIT ROMIN + JSR $FDED + BIT LCBNK2 +end +; +; CHAR IN +; RDKEY() +; +asm cin + BIT ROMIN + STX ESP + JSR $FD0C + LDX ESP + BIT LCBNK2 + DEX + AND #$7F + STA ESTKL,X + LDY #$00 + STY ESTKH,X +end +; +; PRINT STRING +; PRSTR(STR) +; +asm prstr + LDY #$00 + LDA ESTKL,X + STA SRCL + LDA ESTKH,X + STA SRCH + BIT ROMIN + LDA (SRC),Y + STA ESTKL,X + BEQ :+ +_PRS1: INY + LDA (SRC),Y + ORA #$80 + JSR $FDED + TYA + CMP ESTKL,X + BNE _PRS1 +: INX + BIT LCBNK2 +end +; +; READ STRING +; STR = RDSTR(PROMPTCHAR) +; +asm rdstr + LDA ESTKL,X + STA $33 + STX ESP + BIT ROMIN + JSR $FD6A + BIT LCBNK2 + STX $01FF +: LDA $01FF,X + AND #$7F + STA $01FF,X + DEX + BPL :- + LDX ESP + LDA #$FF + STA ESTKL,X + LDA #$01 + STA ESTKH,X +end +; +; EXIT +; +asm exit + JSR $BF00 + DB $65 + DW EXITTBL +EXITTBL: + DB 4 + DB 0 +end +; +; ProDOS routines +; +def getpfx_11(path) + byte params[3] + + ^path = 0 + params.0 = 1 + params:1 = path + perr = syscall($C7, @params) + return path +end +def setpfx_11(path) + byte params[3] + + params.0 = 1 + params:1 = path + perr = syscall($C6, @params) + return path +end +def open_21(path, buff) + byte params[6] + + params.0 = 3 + params:1 = path + params:3 = buff + params.5 = 0 + perr = syscall($C8, @params) + return params.5 +end +def close_11(refnum) + byte params[2] + + params.0 = 1 + params.1 = refnum + perr = syscall($CC, @params) + return perr +end +def read_31(refnum, buff, len) + byte params[8] + + params.0 = 4 + params.1 = refnum + params:2 = buff + params:4 = len + params:6 = 0 + perr = syscall($CA, @params) + return params:6 +end +def write_31(refnum, buff, len) + byte params[8] + + params.0 = 4 + params.1 = refnum + params:2 = buff + params:4 = len + params:6 = 0 + perr = syscall($CB, @params) + return params:6 +end +def create_41(path, access, type, aux) + byte params[12] + + params.0 = 7 + params:1 = path + params.3 = access + params.4 = type + params:5 = aux + params.7 = $1 + params:8 = 0 + params:10 = 0 + perr = syscall($C0, @params) + return perr +end +def destroy_11(path) + byte params[12] + + params.0 = 1 + params:1 = path + perr = syscall($C1, @params) + return perr +end +def newline_31(refnum, emask, nlchar) + byte params[4] + + params.0 = 3 + params.1 = refnum + params.2 = emask + params.3 = nlchar + perr = syscall($C9, @params) + return perr +end + +;===================================== +; +; Editor +; +;===================================== + +def crout + cout($0D) +end +def bell + drop romcall(0, 0, 0, 0, $FBDD) +end +; +; Memory management routines +; +defopt strcpy_20(srcstr, dststr) + byte strlen + + strlen = ^srcstr + while (srcstr).[strlen] == $8D or (srcstr).[strlen] == $A0 + strlen = strlen - 1 + loop + ^dststr = strlen + memcpy(srcstr + 1, dststr + 1, strlen) +end +defopt heapaddr_21(ofst, mask) + word addr + + addr = (ofst << 7) + strheap + while !(mask & 1) + addr = addr + 16 + mask = mask >> 1 + loop + return addr +end +defopt sizemask_11(size) + if size <= 16 + return $01 + elsif size <= 32 + return $03 + elsif size <= 48 + return $07 + elsif size <= 64 + return $0F + elsif size <= 80 + return $1F + fin + return 0 +end +defopt heapalloc_11(size) + byte szmask, i + word mapmask + + szmask = sizemask_11(size) + for i = strheapmsz - 1 downto 0 + if strheapmap.[i] <> $FF + mapmask = szmask + repeat + if strheapmap.[i] & mapmask + mapmask = mapmask << 1 + else + strheapmap.[i] = strheapmap.[i] ? mapmask + return heapaddr_21(i, mapmask) + fin + until mapmask & $100 + fin + next + bell() + prstr(@outofmem) + return 0 +end +def freestr_10(strptr) + byte mask, ofst + + if strptr and strptr <> @nullstr + mask = sizemask_11(^strptr + 1) + ofst = (strptr - strheap) >> 4 + mask = mask << (ofst & $07) + ofst = ofst >> 3 + strheapmap.[ofst] = strheapmap.[ofst] & #mask + fin +end +def newstr_11(strptr) + byte strlen + word newptr + + strlen = ^strptr + while (strptr).[strlen] == $8D or (strptr).[strlen] == $A0 + strlen = strlen - 1 + loop + if strlen == 0 + return @nullstr + fin + newptr = heapalloc_11(strlen + 1) + if newptr + memcpy(strptr, newptr, strlen + 1) + ^newptr = strlen + return newptr + fin + return @nullstr +end +def inittxtbuf + word i + + memset(0, strheapmap, strheapmsz) + memset(@nullstr, strlinbuf, maxfill * 2) + numlines = 0 + cursrow = 0 + curscol = 0 + cursx = 0 + cursy = 0 + scrnleft = 0 + scrntop = 0 + cutbuf = 0 +end +; +; Case conversion/printing routines +; +def caseconv_11(chr) + if flags & uppercase + if chr & $E0 == $E0 + chr = chr - $E0 + fin + fin + return chr +end +def strupper_10(strptr) + byte i, chr + + for i = ^strptr downto 1 + chr = (strptr).[i] + if chr & $E0 == $E0 + (strptr).[i] = chr - $E0 + fin + next +end +def strlower_10(strptr) + byte i, chr + + for i = ^strptr downto 1 + chr = (strptr).[i] + if chr & $E0 == $00 + (strptr).[i] = chr + $E0 + fin + next +end +def txtupper + word i, strptr + + flags = flags ? uppercase + for i = numlines - 1 downto 0 + strupper_10(strlinbuf:[i]) + next +end +def txtlower + word i, strptr + + flags = flags & #uppercase + for i = numlines - 1 downto 0 + strlower_10(strlinbuf:[i]) + next +end +def prbyte_10(h) + cout('$') + drop romcall(h, 0, 0, 0, $FDDA) +end +def prword_10(h) + cout('$') + drop romcall(h >> 8, h, 0, 0, $F941) +end +def print_10(i) + byte numstr[7] + byte place, sign + + place = 6 + if i < 0 + sign = 1 + i = -i + else + sign = 0 + fin + while i >= 10 + i =, numstr[place] = i % 10 + '0' + place = place - 1 + loop + numstr[place] = i + '0' + place = place - 1 + if sign + numstr[place] = '-' + place = place - 1 + fin + numstr[place] = 6 - place + prstr(@numstr[place]) +end +def nametostr_30(namestr, len, strptr) + ^strptr = len + memcpy(namestr, strptr + 1, len) +end +;def toupper_11(c) +; if c >= 'a' +; if c <= 'z' +; return c - $20 +; fin +; fin +; return c +;end +asm toupper_11 + LDA ESTKL,X + AND #$7F + CMP #'a' + BCC :+ + CMP #'z'+1 + BCS :+ + SEC + SBC #$20 +: STA ESTKL,X +end +asm clrhibit_10(strptr) + LDY #$02 ; strptr + LDA (FRMP),Y + STA SRCL + INY + LDA (FRMP),Y + STA SRCH + LDY #$00 + LDA (SRC),Y + BEQ :+ + TAY +CLHILP: LDA (SRC),Y + AND #$7F + STA (SRC),Y + DEY + BNE CLHILP +: +end +asm sethibit_10(strptr) + LDY #$02 ; strptr + LDA (FRMP),Y + STA SRCL + INY + LDA (FRMP),Y + STA SRCH + LDY #$00 + LDA (SRC),Y + BEQ :+ + TAY +STHILP: LDA (SRC),Y + ORA #$80 + STA (SRC),Y + DEY + BNE STHILP +: +end +asm cpyln_20(srcstr, dststr) + LDY #$02 ; srcstr + LDA (FRMP),Y + STA SRCL + INY + LDA (FRMP),Y + STA SRCH + INY ; dststr + LDA (FRMP),Y + STA DSTL + INY + LDA (FRMP),Y + STA DSTH + LDY #$00 + LDA (SRC),Y + TAY + LDA #$00 + INY + STA (DST),Y + DEY + BEQ :++ +CPLNLP: LDA (SRC),Y + CMP #$20 + BCS :+ + ADC #$60 +: AND #$7F + STA (DST),Y + DEY + BNE CPLNLP + LDA (SRC),Y +: STA (DST),Y +end +; +; File routines +; +def readtxt_10(filename) + byte txtbuf[81], refnum, i, j + + refnum = open_21(filename, iobuffer) + if refnum + drop newline_31(refnum, $7F, $0D) + repeat + txtbuf = read_31(refnum, @txtbuf + 1, maxlnlen) + if txtbuf + sethibit_10(@txtbuf) + if flags & uppercase + strupper_10(@txtbuf) + fin + strlinbuf:[numlines] = newstr_11(@txtbuf) + numlines = numlines + 1 + fin + if !(numlines & $0F) + cout('.') + fin + until txtbuf == 0 or numlines == maxlines + drop close_11(refnum) + fin + if numlines == 0 + numlines = 1 + fin +end +def writetxt_10(filename) + byte txtbuf[81], refnum + byte j, chr + word i, strptr + + drop destroy_11(filename) + drop create_41(filename, $C3, $04, $00) ; full access, TXT file + refnum = open_21(filename, iobuffer) + if refnum == 0 + return + fin + for i = 0 to numlines - 1 + cpyln_20(strlinbuf:[i], @txtbuf) + txtbuf = txtbuf + 1 + txtbuf[txtbuf] = $0D + drop write_31(refnum, @txtbuf + 1, txtbuf) + if !(i & $0F) + cout('.') + fin + next + drop close_11(refnum) +end +; +; Screen routines +; +def clrscrn + drop romcall(0, 0, 0, 0, $FC58) +end +def drawrow_30(row, ofst, strptr) + byte numchars + word scrnptr + + scrnptr = txtscrn[row] + if ^strptr <= ofst + numchars = 0 + else + numchars = ^strptr - ofst + fin + if numchars >= 40 + numchars = 40 + else + memset($A0A0, scrnptr + numchars, 40 - numchars) + fin + memcpy(strptr + ofst + 1, scrnptr, numchars) +end +defopt drawscrn_20(toprow, ofst) + byte row, numchars + word strptr, scrnptr + + for row = 0 to 23 + strptr = strlinbuf:[toprow + row] + scrnptr = txtscrn[row] + if ^strptr <= ofst + numchars = 0 + else + numchars = ^strptr - ofst + fin + if numchars >= 40 + numchars = 40 + else + memset($A0A0, scrnptr + numchars, 40 - numchars) + fin + memcpy(strptr + ofst + 1, scrnptr, numchars) + next +end +def cursoff + if flags & showcurs + ^cursptr = underchr + flags = flags & #showcurs + fin +end +def curson + if !(flags & showcurs) + cursptr = txtscrn[cursy] + cursx + underchr = ^cursptr + ^cursptr = curschr + flags = flags ? showcurs + fin +end +def cursflash() + if flags & showcurs + if flash == 0 + ^cursptr = curschr + elsif flash == 128 + ^cursptr = underchr + fin + flash = flash + 1 + fin +end +def redraw + cursoff() + drawscrn_20(scrntop, scrnleft) + curson() +end +def curshome + cursoff() + cursrow = 0 + curscol = 0 + cursx = 0 + cursy = 0 + scrnleft = 0 + scrntop = 0 + drawscrn_20(scrntop, scrnleft) + curson() +end +def cursend + cursoff() + if numlines > 23 + cursrow = numlines - 1 + cursy = 23 + scrntop = cursrow - 23 + else + cursrow = numlines - 1 + cursy = numlines - 1 + scrntop = 0 + fin + curscol = 0 + cursx = 0 + scrnleft = 0 + drawscrn_20(scrntop, scrnleft) + curson() +end +def cursup + if cursrow > 0 + cursoff() + cursrow = cursrow - 1 + if cursy > 0 + cursy = cursy - 1 + else + scrntop = cursrow + drawscrn_20(scrntop, scrnleft) + fin + curson() + fin +end +def pgup + byte i + + for i = pgjmp downto 0 + cursup() + next +end +def cursdown + if cursrow < numlines - 1 + cursoff() + cursrow = cursrow + 1 + if cursy < 23 + cursy = cursy + 1 + else + scrntop = cursrow - 23 + drawscrn_20(scrntop, scrnleft) + fin + curson() + fin +end +def pgdown + byte i + + for i = pgjmp downto 0 + cursdown() + next +end +def cursleft + if curscol > 0 + cursoff() + curscol = curscol - 1 + if cursx > 0 + cursx = cursx - 1 + else + scrnleft = curscol + drawscrn_20(scrntop, scrnleft) + fin + curson() + fin +end +def pgleft + byte i + + for i = 7 downto 0 + cursleft() + next +end +def cursright + if curscol < 80 + cursoff() + curscol = curscol + 1 + if cursx < 39 + cursx = cursx + 1 + else + scrnleft = curscol - 39 + drawscrn_20(scrntop, scrnleft) + fin + curson() + fin +end +def pgright + byte i + + for i = 7 downto 0 + cursright() + next +end +; +; Keyboard routines +; +def keyin2e_01 + repeat + cursflash() + until ^keyboard >= 128 + return ^keystrobe +end +def keyin2_01 + byte key + + repeat + cursflash() + key = ^keyboard + if key == keyctrll + drop ^keystrobe + flags = flags ^ shiftlock + key = 0 + fin + until key >= 128 + drop ^keystrobe + if key == keyctrln + key = $DB ; [ + elsif key == keyctrlp + key = $DF ; _ + elsif key == keyctrlb + key = $DC ; \ + elsif key == keyarrowleft + if ^pushbttn3 < 128 + key = $FF + fin + elsif key >= $C0 and flags < shiftlock + if ^pushbttn3 < 128 + if key == $C0 + key = $D0 ; P + elsif key == $DD + key = $CD ; M + elsif key == $DE + key = $CE ; N + fin + else + key = key ? $E0 + fin + fin + return key +end +; +; Printer routines +; +def printtxt_10(slot) + byte txtbuf[80] + word i, scrncsw + + scrncsw = *(csw) + *(csw) = $C000 ? (slot << 8) + for i = 0 to numlines - 1 + cpyln_20(strlinbuf:[i], @txtbuf) + prstr(@txtbuf) + crout() + next + *(csw) = scrncsw +end +def openline_11(row) + if numlines < maxlines + memcpy(@strlinbuf:[row], @strlinbuf:[row + 1], (numlines - row) * 2) + strlinbuf:[row] = @nullstr + numlines = numlines + 1 + flags = flags ? changed + return 1 + fin + bell() + return 0 +end +def cutline + freestr_10(cutbuf) + cutbuf = strlinbuf:[cursrow] + memcpy(@strlinbuf:[cursrow + 1], @strlinbuf:[cursrow], (numlines - cursrow) * 2) + if numlines > 1 + numlines = numlines - 1 + fin + flags = flags ? changed + if cursrow == numlines + cursup() + fin + redraw() +end +def pasteline + if cutbuf and numlines < maxlines + memcpy(@strlinbuf:[cursrow], @strlinbuf:[cursrow + 1], (numlines - cursrow) * 2) + strlinbuf:[cursrow] = newstr_11(cutbuf) + numlines = numlines + 1 + flags = flags ? changed + redraw() + else + bell() + fin +end +def joinline + byte joinstr[80], joinlen + + if cursrow < numlines - 1 + strcpy_20(strlinbuf:[cursrow], @joinstr) + joinlen = joinstr + ^(strlinbuf:[cursrow + 1]) + if joinlen < 80 + memcpy(strlinbuf:[cursrow + 1] + 1, @joinstr + joinstr + 1, ^(strlinbuf:[cursrow + 1])) + joinstr = joinlen + freestr_10(strlinbuf:[cursrow]) + strlinbuf:[cursrow] = newstr_11(@joinstr) + freestr_10(strlinbuf:[cursrow + 1]) + numlines = numlines - 1 + memcpy(@strlinbuf:[cursrow + 2], @strlinbuf:[cursrow + 1], (numlines - cursrow) * 2) + flags = flags ? changed + redraw() + else + bell() + fin + fin +end +def splitline + byte splitstr[80], splitlen + + if openline_11(cursrow + 1) + if curscol + splitlen = ^(strlinbuf:[cursrow]) + if curscol < splitlen - 1 + memcpy(strlinbuf:[cursrow] + curscol + 1, @splitstr + 1, splitlen - curscol) + splitstr = splitlen - curscol + strlinbuf:[cursrow + 1] = newstr_11(@splitstr) + memcpy(strlinbuf:[cursrow] + 1, @splitstr + 1, curscol) + splitstr = curscol + freestr_10(strlinbuf:[cursrow]) + strlinbuf:[cursrow] = newstr_11(@splitstr) + fin + else + strlinbuf:[cursrow + 1] = strlinbuf:[cursrow] + strlinbuf:[cursrow] = @nullstr + fin + curscol = 0 + cursx = 0 + scrnleft = 0 + redraw() + cursdown() + fin +end +def editkey_11(key) + if key >= keyspace + return 1 + elsif key == keydelete + return 1 + elsif key == keyctrld + return 1 + elsif key == keyctrlr + return 1 + fin + return 0 +end +def editline_11(key) + byte editstr[80] + word undoline + + if (editkey_11(key)) + flags = flags ? changed + memset($A0A0, @editstr, 80) + strcpy_20(strlinbuf:[cursrow], @editstr) + undoline = strlinbuf:[cursrow] + strlinbuf:[cursrow] = @editstr + repeat + if key >= keyspace + if key == keydelete + if curscol > 0 + if curscol <= editstr + memcpy(@editstr[curscol + 1], @editstr[curscol], editstr - curscol) + editstr = editstr - 1 + fin + curscol = curscol - 1 + cursoff() + if cursx > 0 + cursx = cursx - 1 + drawrow_30(cursy, scrnleft, @editstr) + else + scrnleft = scrnleft - 1 + drawscrn_20(scrntop, scrnleft) + fin + curson() + fin + elsif curscol < maxlnlen + curscol = curscol + 1 + cursx = cursx + 1 + if flags & insmode + if editstr < maxlnlen or editstr.maxlnlen == $A0 + editstr = editstr + 1 + if curscol >= editstr + editstr = curscol + else + memcpy(@editstr[curscol], @editstr[curscol + 1], editstr - curscol) + fin + else + curscol = curscol - 1 + cursx = cursx - 1 + key = editstr[curscol] + bell() + fin + else + if curscol > editstr + editstr = curscol + fin + fin + editstr[curscol] = caseconv_11(key) + cursoff() + if cursx <= 39 + drawrow_30(cursy, scrnleft, @editstr) + else + scrnleft = scrnleft + 1 + cursx = 39 + drawscrn_20(scrntop, scrnleft) + fin + curson() + else + bell() + fin + elsif key == keyctrld + if curscol < editstr + memcpy(@editstr[curscol + 2], @editstr[curscol + 1], editstr - curscol) + editstr = editstr - 1 + cursoff() + drawrow_30(cursy, scrnleft, @editstr) + curson() + fin + elsif key == keyctrlr + strcpy_20(undoline, @editstr) + cursoff() + drawrow_30(cursy, scrnleft, @editstr) + curson() + fin + key = keyin_01() + until !editkey_11(key) + if editstr + strlinbuf:[cursrow] = newstr_11(@editstr) + else + strlinbuf:[cursrow] = @nullstr + fin + freestr_10(undoline) + fin + return key +end +def editmode + repeat + when editline_11(keyin_01()) + is keyarrowup + cursup() + is keyarrowdown + cursdown() + is keyarrowleft + cursleft() + is keyarrowright + cursright() + is keyctrlw + pgup() + is keyctrlz + pgdown() + is keyctrla + pgleft() + is keyctrls + pgright() + is keyctrlq + curshome() + is keyctrle + cursend() + is keyctrlx + cutline() + is keyctrlv + pasteline() + is keyctrlo + drop openline_11(cursrow) + redraw() + is keyenter + if flags & insmode + splitline() + else + drop openline_11(cursrow + 1) + cursdown() + redraw() + fin + is keyctrlt + joinline() + is keyctrli + if flags & insmode + flags = flags & #insmode + curschr = ' ' + else + flags = flags ? insmode + curschr = '+' + fin + is keyctrlc + if flags & uppercase + txtlower() + else + txtupper() + fin + redraw() + is keyescape + cursoff() + cmdmode() + redraw() + wend + until 0 +end +; +; Command mode +; +def prfiles_11(optpath) + byte path[64] + byte refnum + byte firstblk + byte entrylen, entriesblk + byte i, type, len + word entry, filecnt + + if ^optpath + strcpy_20(optpath, @path) + else + drop getpfx_11(@path) + prstr(@path) + crout() + fin + refnum = open_21(@path, iobuffer); + if perr + return perr + fin + firstblk = 1 + repeat + if read_31(refnum, databuff, 512) == 512 + entry = databuff + 4 + if firstblk + entrylen = databuff.$23 + entriesblk = databuff.$24 + filecnt = databuff:$25 + entry = entry + entrylen + fin + for i = firstblk to entriesblk + type = ^entry + if type <> 0 + len = type & $0F + ^entry = len + prstr(entry) + if type & $F0 == $D0 ; Is it a directory? + cout('/') + len = len + 1 + fin + for len = 20 - len downto 1 + cout(' ') + next + filecnt = filecnt - 1 + fin + entry = entry + entrylen + next + firstblk = 0 + else + filecnt = 0 + fin + until filecnt == 0 + drop close_11(refnum) + crout() + return 0 +end +def striplead_20(strptr, chr) + while ^strptr and ^(strptr + 1) == chr + memcpy(strptr + 2, strptr + 1, ^strptr) + ^strptr = ^strptr - 1 + loop +end +def parsecmd_11(strptr) + byte cmd + + cmd = 0 + striplead_20(strptr, ' ') + if ^strptr + cmd = ^(strptr + 1) + memcpy(strptr + 2, strptr + 1, ^strptr) + ^strptr = ^strptr - 1 + fin + if ^strptr + striplead_20(strptr, ' ') + fin + return cmd +end +def chkchng_01 + if flags & changed + prstr(@losechng) + if toupper_11(keyin_01()) == 'N' + crout() + return 0 + fin + crout() + fin + return 1 +end +def quit + if chkchng_01() + exit + fin +end +def cmdmode + byte slot + word cmdptr + + clrscrn(); + prstr(@version) + crout() + while 1 + prstr(@txtfile) + cmdptr = rdstr($BA) + when toupper_11(parsecmd_11(cmdptr)) + is 'A' + readtxt_10(cmdptr) + flags = flags ? changed + is 'R' + if chkchng_01() + inittxtbuf() + strcpy_20(cmdptr, @txtfile) + readtxt_10(@txtfile) + flags = flags & #changed + fin + is 'W' + if ^cmdptr + strcpy_20(cmdptr, @txtfile) + fin + writetxt_10(@txtfile) + if flags & changed + fin + flags = flags & #changed + is 'Q' + quit() + is 'C' + drop prfiles_11(cmdptr) + is 'P' + drop setpfx_11(cmdptr) + is 'H' + if ^cmdptr + slot = cmdptr.1 - '0' + else + slot = 1 + fin + printtxt_10(slot) + is 'E' + return + is 0 + return + is 'N' + if chkchng_01() + inittxtbuf() + numlines = 1 + strcpy_20(@untitled, @txtfile) + fin + otherwise + bell() + cout('?') + crout() + wend + if perr + prstr(@errorstr) + drop romcall(perr, 0, 0, 0, $FDDA) + else + prstr(@okstr) + fin + crout() + loop +end +; +; Init editor +; +if !(^machid & $80) + flags = uppercase ? shiftlock + keyin_01 = @keyin2_01 +else + keyin_01 = @keyin2e_01 +fin +inittxtbuf() +if ^argbuff + strcpy_20(argbuff, @txtfile) + prstr(@txtfile) + readtxt_10(@txtfile) +else + numlines = 1 +fin +curschr = '+' +flags = flags ? insmode +drawscrn_20(scrntop, scrnleft) +curson() +editmode() +done diff --git a/plasma2/pled.s b/plasma2/pled.s new file mode 100755 index 0000000..060e370 --- /dev/null +++ b/plasma2/pled.s @@ -0,0 +1,5450 @@ + .INCLUDE "plstub.s" +; 1: ; +; 2: ; Global constants +; 3: ; +; 4: const FALSE = 0 + ; FALSE = 0 +; 5: const TRUE = !FALSE + ; TRUE = -1 +; 6: ; +; 7: ; Hardware constants +; 8: ; +; 9: const csw = $0036 + ; csw = 54 +; 10: const speaker = $C030 + ; speaker = 49200 +; 11: const showgraphics = $C050 + ; showgraphics = 49232 +; 12: const showtext = $C051 + ; showtext = 49233 +; 13: const showfull = $C052 + ; showfull = 49234 +; 14: const showmix = $C053 + ; showmix = 49235 +; 15: const showpage1 = $C054 + ; showpage1 = 49236 +; 16: const showpage2 = $C055 + ; showpage2 = 49237 +; 17: const showlores = $C056 + ; showlores = 49238 +; 18: const showhires = $C057 + ; showhires = 49239 +; 19: const pushbttn1 = $C061 + ; pushbttn1 = 49249 +; 20: const pushbttn2 = $C062 + ; pushbttn2 = 49250 +; 21: const pushbttn3 = $C063 + ; pushbttn3 = 49251 +; 22: const keyboard = $C000 + ; keyboard = 49152 +; 23: const keystrobe = $C010 + ; keystrobe = 49168 +; 24: const keyenter = $8D + ; keyenter = 141 +; 25: const keyspace = $A0 + ; keyspace = 160 +; 26: const keyarrowup = $8B + ; keyarrowup = 139 +; 27: const keyarrowdown = $8A + ; keyarrowdown = 138 +; 28: const keyarrowleft = $88 + ; keyarrowleft = 136 +; 29: const keyarrowright = $95 + ; keyarrowright = 149 +; 30: const keyescape = $9B + ; keyescape = 155 +; 31: const keyctrla = $81 + ; keyctrla = 129 +; 32: const keyctrlb = $82 + ; keyctrlb = 130 +; 33: const keyctrlc = $83 + ; keyctrlc = 131 +; 34: const keyctrld = $84 + ; keyctrld = 132 +; 35: const keyctrle = $85 + ; keyctrle = 133 +; 36: const keyctrli = $89 + ; keyctrli = 137 +; 37: const keyctrlk = $8B + ; keyctrlk = 139 +; 38: const keyctrll = $8C + ; keyctrll = 140 +; 39: const keyctrln = $8E + ; keyctrln = 142 +; 40: const keyctrlo = $8F + ; keyctrlo = 143 +; 41: const keyctrlp = $90 + ; keyctrlp = 144 +; 42: const keyctrlq = $91 + ; keyctrlq = 145 +; 43: const keyctrlr = $92 + ; keyctrlr = 146 +; 44: const keyctrls = $93 + ; keyctrls = 147 +; 45: const keyctrlt = $94 + ; keyctrlt = 148 +; 46: const keyctrlu = $95 + ; keyctrlu = 149 +; 47: const keyctrlv = $96 + ; keyctrlv = 150 +; 48: const keyctrlw = $97 + ; keyctrlw = 151 +; 49: const keyctrlx = $98 + ; keyctrlx = 152 +; 50: const keyctrlz = $9A + ; keyctrlz = 154 +; 51: const keydelete = $FF + ; keydelete = 255 +; 52: const getbuff = $01FF + ; getbuff = 511 +; 53: const argbuff = $2006 + ; argbuff = 8198 +; 54: word txtscrn[] = $0400,$0480,$0500,$0580,$0600,$0680,$0700,$0780 +D0000: ; txtscrn + DW $0400 + DW $0480 + DW $0500 + DW $0580 + DW $0600 + DW $0680 + DW $0700 + DW $0780 +; 55: word = $0428,$04A8,$0528,$05A8,$0628,$06A8,$0728,$07A8 + DW $0428 + DW $04A8 + DW $0528 + DW $05A8 + DW $0628 + DW $06A8 + DW $0728 + DW $07A8 +; 56: word = $0450,$04D0,$0550,$05D0,$0650,$06D0,$0750,$07D0 + DW $0450 + DW $04D0 + DW $0550 + DW $05D0 + DW $0650 + DW $06D0 + DW $0750 + DW $07D0 +; 57: ; +; 58: ; Data and text buffer constants +; 59: ; +; 60: const machid = $BF98 + ; machid = 49048 +; 61: const maxlines = 1500 + ; maxlines = 1500 +; 62: const maxfill = 1524 + ; maxfill = 1524 +; 63: const iobuffer = $0800 + ; iobuffer = 2048 +; 64: const databuff = $0C00 + ; databuff = 3072 +; 65: const strlinbuf = $1000 + ; strlinbuf = 4096 +; 66: const strheapmap = $1F00 + ; strheapmap = 7936 +; 67: const strheapmsz = 224 ; $E0 = 28K is memory@16 bytes per bit map, 128 bytes per 8 bit map, 1K bytes per 8 byte map + ; strheapmsz = 224 +; 68: const maxlnlen = 79 + ; maxlnlen = 79 +; 69: const strheap = $4800 + ; strheap = 18432 +; 70: const strheasz = $7000 + ; strheasz = 28672 +; 71: const pgjmp = 16 + ; pgjmp = 16 +; 72: const changed = 1 + ; changed = 1 +; 73: const insmode = 2 + ; insmode = 2 +; 74: const showcurs = 4 + ; showcurs = 4 +; 75: const uppercase = 8 + ; uppercase = 8 +; 76: const shiftlock = 128 + ; shiftlock = 128 +; 77: ; +; 78: ; Editor variables +; 79: ; +; 80: byte nullstr[] = "" +D0048: ; nullstr + DB $00 +; 81: byte version[] = "PLASMA ][ EDITOR VERSION 0.8 " +D0049: ; version + DB $1D + DB $50,$4C,$41,$53,$4D,$41,$20,$5D + DB $5B,$20,$45,$44,$49,$54,$4F,$52 + DB $20,$56,$45,$52,$53,$49,$4F,$4E + DB $20,$30,$2E,$38,$20 +; 82: byte errorstr[] = "ERROR: $" +D0079: ; errorstr + DB $08 + DB $45,$52,$52,$4F,$52,$3A,$20,$24 +; 83: byte okstr[] = "OK" +D0088: ; okstr + DB $02 + DB $4F,$4B +; 84: byte perr +D0091: DS 1 ; perr +; 85: byte outofmem[] = "OUT OF MEMORY!" +D0092: ; outofmem + DB $0E + DB $4F,$55,$54,$20,$4F,$46,$20,$4D + DB $45,$4D,$4F,$52,$59,$21 +; 86: byte losechng[] = "LOSE CHANGES TO FILE (Y/N)?" +D0107: ; losechng + DB $1B + DB $4C,$4F,$53,$45,$20,$43,$48,$41 + DB $4E,$47,$45,$53,$20,$54,$4F,$20 + DB $46,$49,$4C,$45,$20,$28,$59,$2F + DB $4E,$29,$3F +; 87: ;byte emiterr[] = "EMIT CODE/DATA MISMATCH" +; 88: byte untitled[] = "UNTITLED" +D0135: ; untitled + DB $08 + DB $55,$4E,$54,$49,$54,$4C,$45,$44 +; 89: byte txtfile[64] = "UNTITLED.PLA" +D0144: ; txtfile + DB $0C + DB $55,$4E,$54,$49,$54,$4C,$45,$44 + DB $2E,$50,$4C,$41 + DS $33 +; 90: byte flags = 0 +D0195: ; flags + DB $00 +; 91: byte flash = 0 +D0196: ; flash + DB $00 +; 92: byte cursx, cursy, scrnleft, curscol, underchr, curschr +D0197: DS 1 ; cursx +D0198: DS 1 ; cursy +D0199: DS 1 ; scrnleft +D0200: DS 1 ; curscol +D0201: DS 1 ; underchr +D0202: DS 1 ; curschr +; 93: word cursrow, scrntop, cursptr +D0203: DS 2 ; cursrow +D0205: DS 2 ; scrntop +D0207: DS 2 ; cursptr +; 94: word numlines = 0 +D0209: ; numlines + DW $0000 +; 95: word cutbuf = 0 +D0211: ; cutbuf + DW $0000 +; 96: word keyin_01 +D0213: DS 2 ; keyin_01 +; 97: ; +; 98: ; Predeclared functions +; 99: ; +; 100: func cmdmode +; 101: ; +; 102: ; Utility functions +; 103: ; +; 104: ; Defines for ASM routines +; 105: ; +; 106: asm equates +C0001: ; equates() +; 107: TMP EQU $F0 + TMP EQU $F0 +; 108: TMPL EQU TMP + TMPL EQU TMP +; 109: TMPH EQU TMP+1 + TMPH EQU TMP+1 +; 110: SRC EQU TMP + SRC EQU TMP +; 111: SRCL EQU SRC + SRCL EQU SRC +; 112: SRCH EQU SRC+1 + SRCH EQU SRC+1 +; 113: DST EQU SRC+2 + DST EQU SRC+2 +; 114: DSTL EQU DST + DSTL EQU DST +; 115: DSTH EQU DST+1 + DSTH EQU DST+1 +; 116: ESP EQU DST+2 + ESP EQU DST+2 +; 117: end + RTS +; 118: ; CALL 6502 ROUTINE +; 119: ; ROMCALL(AREG, XREG, YREG, STATUS, ADDR) +; 120: ; +; 121: asm romcall +C0003: ; romcall() +; 122: PHP + PHP +; 123: LDA ESTKL,X + LDA ESTKL,X +; 124: STA TMPL + STA TMPL +; 125: LDA ESTKH,X + LDA ESTKH,X +; 126: STA TMPH + STA TMPH +; 127: INX + INX +; 128: LDA ESTKL,X + LDA ESTKL,X +; 129: PHA + PHA +; 130: INX + INX +; 131: LDA ESTKL,X + LDA ESTKL,X +; 132: TAY + TAY +; 133: INX + INX +; 134: LDA ESTKL+1,X + LDA ESTKL+1,X +; 135: PHA + PHA +; 136: LDA ESTKL,X + LDA ESTKL,X +; 137: INX + INX +; 138: STX ESP + STX ESP +; 139: TAX + TAX +; 140: PLA + PLA +; 141: BIT ROMIN + BIT ROMIN +; 142: PLP + PLP +; 143: JSR JMPTMP + JSR JMPTMP +; 144: PHP + PHP +; 145: BIT LCBNK2 + BIT LCBNK2 +; 146: STA REGVALS+0 + STA REGVALS+0 +; 147: STX REGVALS+1 + STX REGVALS+1 +; 148: STY REGVALS+2 + STY REGVALS+2 +; 149: PLA + PLA +; 150: STA REGVALS+3 + STA REGVALS+3 +; 151: LDX ESP + LDX ESP +; 152: LDA #REGVALS + LDY #>REGVALS +; 154: STA ESTKL,X + STA ESTKL,X +; 155: STY ESTKH,X + STY ESTKH,X +; 156: PLP + PLP +; 157: RTS + RTS +; 158: JMPTMP: JMP (TMP) +JMPTMP: JMP (TMP) +; 159: REGVALS: DS 4 +REGVALS: DS 4 +; 160: end + RTS +; 161: ; +; 162: ; CALL PRODOS +; 163: ; SYSCALL(CMD, PARAMS) +; 164: ; +; 165: asm syscall +C0005: ; syscall() +; 166: LDA ESTKL,X + LDA ESTKL,X +; 167: LDY ESTKH,X + LDY ESTKH,X +; 168: STA PARAMS + STA PARAMS +; 169: STY PARAMS+1 + STY PARAMS+1 +; 170: INX + INX +; 171: LDA ESTKL,X + LDA ESTKL,X +; 172: STA CMD + STA CMD +; 173: STX ESP + STX ESP +; 174: JSR $BF00 + JSR $BF00 +; 175: CMD: DB 00 +CMD: DB 00 +; 176: PARAMS: DW 0000 +PARAMS: DW 0000 +; 177: BIT LCBNK2 + BIT LCBNK2 +; 178: LDX ESP + LDX ESP +; 179: STA ESTKL,X + STA ESTKL,X +; 180: LDY #$00 + LDY #$00 +; 181: STY ESTKH,X + STY ESTKH,X +; 182: end + RTS +; 183: ; +; 184: ; SET MEMORY TO VALUE +; 185: ; MEMSET(VALUE, ADDR, SIZE) +; 186: ; +; 187: asm memset +C0007: ; memset() +; 188: LDY #$00 + LDY #$00 +; 189: LDA ESTKL+1,X + LDA ESTKL+1,X +; 190: STA DSTL + STA DSTL +; 191: LDA ESTKH+1,X + LDA ESTKH+1,X +; 192: STA DSTH + STA DSTH +; 193: INC ESTKL,X + INC ESTKL,X +; 194: INC ESTKH,X + INC ESTKH,X +; 195: SETMEM: DEC ESTKL,X +SETMEM: DEC ESTKL,X +; 196: BNE :+ + BNE :+ +; 197: DEC ESTKH,X + DEC ESTKH,X +; 198: BEQ MEMEXIT + BEQ MEMEXIT +; 199: : LDA ESTKL+2,X +: LDA ESTKL+2,X +; 200: STA (DST),Y + STA (DST),Y +; 201: INY + INY +; 202: BNE :+ + BNE :+ +; 203: INC DSTH + INC DSTH +; 204: : DEC ESTKL,X +: DEC ESTKL,X +; 205: BNE :+ + BNE :+ +; 206: DEC ESTKH,X + DEC ESTKH,X +; 207: BEQ MEMEXIT + BEQ MEMEXIT +; 208: : LDA ESTKH+2,X +: LDA ESTKH+2,X +; 209: STA (DST),Y + STA (DST),Y +; 210: INY + INY +; 211: BNE SETMEM + BNE SETMEM +; 212: INC DSTH + INC DSTH +; 213: BNE SETMEM + BNE SETMEM +; 214: MEMEXIT: INX +MEMEXIT: INX +; 215: INX + INX +; 216: INX + INX +; 217: end + RTS +; 218: ; +; 219: ; COPY MEMORY +; 220: ; MEMCPY(SRCADDR, DSTADDR, SIZE) +; 221: ; +; 222: asm memcpy +C0009: ; memcpy() +; 223: LDY #$00 + LDY #$00 +; 224: LDA ESTKL,X + LDA ESTKL,X +; 225: BNE :+ + BNE :+ +; 226: LDA ESTKH,X + LDA ESTKH,X +; 227: BEQ MEMEXIT + BEQ MEMEXIT +; 228: : LDA ESTKL+1,X +: LDA ESTKL+1,X +; 229: STA DSTL + STA DSTL +; 230: LDA ESTKH+1,X + LDA ESTKH+1,X +; 231: STA DSTH + STA DSTH +; 232: LDA ESTKL+2,X + LDA ESTKL+2,X +; 233: STA SRCL + STA SRCL +; 234: LDA ESTKH+2,X + LDA ESTKH+2,X +; 235: STA SRCH + STA SRCH +; 236: CMP DSTH + CMP DSTH +; 237: BCC REVCPY + BCC REVCPY +; 238: BNE FORCPY + BNE FORCPY +; 239: LDA SRCL + LDA SRCL +; 240: CMP DSTL + CMP DSTL +; 241: BCS FORCPY + BCS FORCPY +; 242: REVCPY: ; REVERSE DIRECTION COPY +REVCPY: ; REVERSE DIRECTION COPY +; 243: ; CLC +; 244: LDA ESTKL,X + LDA ESTKL,X +; 245: ADC DSTL + ADC DSTL +; 246: STA DSTL + STA DSTL +; 247: LDA ESTKH,X + LDA ESTKH,X +; 248: ADC DSTH + ADC DSTH +; 249: STA DSTH + STA DSTH +; 250: CLC + CLC +; 251: LDA ESTKL,X + LDA ESTKL,X +; 252: ADC SRCL + ADC SRCL +; 253: STA SRCL + STA SRCL +; 254: LDA ESTKH,X + LDA ESTKH,X +; 255: ADC SRCH + ADC SRCH +; 256: STA SRCH + STA SRCH +; 257: INC ESTKH,X + INC ESTKH,X +; 258: REVCPYLP: +REVCPYLP: +; 259: LDA DSTL + LDA DSTL +; 260: BNE :+ + BNE :+ +; 261: DEC DSTH + DEC DSTH +; 262: : DEC DSTL +: DEC DSTL +; 263: LDA SRCL + LDA SRCL +; 264: BNE :+ + BNE :+ +; 265: DEC SRCH + DEC SRCH +; 266: : DEC SRCL +: DEC SRCL +; 267: LDA (SRC),Y + LDA (SRC),Y +; 268: STA (DST),Y + STA (DST),Y +; 269: DEC ESTKL,X + DEC ESTKL,X +; 270: BNE REVCPYLP + BNE REVCPYLP +; 271: DEC ESTKH,X + DEC ESTKH,X +; 272: BNE REVCPYLP + BNE REVCPYLP +; 273: BEQ MEMEXIT + BEQ MEMEXIT +; 274: FORCPY: INC ESTKH,X +FORCPY: INC ESTKH,X +; 275: FORCPYLP: +FORCPYLP: +; 276: LDA (SRC),Y + LDA (SRC),Y +; 277: STA (DST),Y + STA (DST),Y +; 278: INC DSTL + INC DSTL +; 279: BNE :+ + BNE :+ +; 280: INC DSTH + INC DSTH +; 281: : INC SRCL +: INC SRCL +; 282: BNE :+ + BNE :+ +; 283: INC SRCH + INC SRCH +; 284: : DEC ESTKL,X +: DEC ESTKL,X +; 285: BNE FORCPYLP + BNE FORCPYLP +; 286: DEC ESTKH,X + DEC ESTKH,X +; 287: BNE FORCPYLP + BNE FORCPYLP +; 288: BEQ MEMEXIT + BEQ MEMEXIT +; 289: end + RTS +; 290: ; +; 291: ; CHAR OUT +; 292: ; COUT(CHAR) +; 293: ; +; 294: asm cout +C0011: ; cout() +; 295: LDA ESTKL,X + LDA ESTKL,X +; 296: INX + INX +; 297: ORA #$80 + ORA #$80 +; 298: BIT ROMIN + BIT ROMIN +; 299: JSR $FDED + JSR $FDED +; 300: BIT LCBNK2 + BIT LCBNK2 +; 301: end + RTS +; 302: ; +; 303: ; CHAR IN +; 304: ; RDKEY() +; 305: ; +; 306: asm cin +C0013: ; cin() +; 307: BIT ROMIN + BIT ROMIN +; 308: STX ESP + STX ESP +; 309: JSR $FD0C + JSR $FD0C +; 310: LDX ESP + LDX ESP +; 311: BIT LCBNK2 + BIT LCBNK2 +; 312: DEX + DEX +; 313: AND #$7F + AND #$7F +; 314: STA ESTKL,X + STA ESTKL,X +; 315: LDY #$00 + LDY #$00 +; 316: STY ESTKH,X + STY ESTKH,X +; 317: end + RTS +; 318: ; +; 319: ; PRINT STRING +; 320: ; PRSTR(STR) +; 321: ; +; 322: asm prstr +C0015: ; prstr() +; 323: LDY #$00 + LDY #$00 +; 324: LDA ESTKL,X + LDA ESTKL,X +; 325: STA SRCL + STA SRCL +; 326: LDA ESTKH,X + LDA ESTKH,X +; 327: STA SRCH + STA SRCH +; 328: BIT ROMIN + BIT ROMIN +; 329: LDA (SRC),Y + LDA (SRC),Y +; 330: STA ESTKL,X + STA ESTKL,X +; 331: BEQ :+ + BEQ :+ +; 332: _PRS1: INY +_PRS1: INY +; 333: LDA (SRC),Y + LDA (SRC),Y +; 334: ORA #$80 + ORA #$80 +; 335: JSR $FDED + JSR $FDED +; 336: TYA + TYA +; 337: CMP ESTKL,X + CMP ESTKL,X +; 338: BNE _PRS1 + BNE _PRS1 +; 339: : INX +: INX +; 340: BIT LCBNK2 + BIT LCBNK2 +; 341: end + RTS +; 342: ; +; 343: ; READ STRING +; 344: ; STR = RDSTR(PROMPTCHAR) +; 345: ; +; 346: asm rdstr +C0017: ; rdstr() +; 347: LDA ESTKL,X + LDA ESTKL,X +; 348: STA $33 + STA $33 +; 349: STX ESP + STX ESP +; 350: BIT ROMIN + BIT ROMIN +; 351: JSR $FD6A + JSR $FD6A +; 352: BIT LCBNK2 + BIT LCBNK2 +; 353: STX $01FF + STX $01FF +; 354: : LDA $01FF,X +: LDA $01FF,X +; 355: AND #$7F + AND #$7F +; 356: STA $01FF,X + STA $01FF,X +; 357: DEX + DEX +; 358: BPL :- + BPL :- +; 359: LDX ESP + LDX ESP +; 360: LDA #$FF + LDA #$FF +; 361: STA ESTKL,X + STA ESTKL,X +; 362: LDA #$01 + LDA #$01 +; 363: STA ESTKH,X + STA ESTKH,X +; 364: end + RTS +; 365: ; +; 366: ; EXIT +; 367: ; +; 368: asm exit +C0019: ; exit() +; 369: JSR $BF00 + JSR $BF00 +; 370: DB $65 + DB $65 +; 371: DW EXITTBL + DW EXITTBL +; 372: EXITTBL: +EXITTBL: +; 373: DB 4 + DB 4 +; 374: DB 0 + DB 0 +; 375: end + RTS +; 376: ; +; 377: ; ProDOS routines +; 378: ; +; 379: def getpfx_11(path) +C0021: ; getpfx_11() + ; path = 2 +; 380: byte params[3] + ; params = 4 +; 381: +; 382: ^path = 0 + JSR _INTERP + DB $58,$07,$01 ; ENTER 7,1 + DB $66,$02 ; LLW 2 + DB $00 ; ZERO + DB $70 ; SB +; 383: params.0 = 1 + DB $28,$04 ; LLA 4 + DB $2A,$01 ; CB 1 + DB $70 ; SB +; 384: params:1 = path + DB $28,$05 ; LLA 5 + DB $66,$02 ; LLW 2 + DB $72 ; SW +; 385: perr = syscall($C7, @params) + DB $2A,$C7 ; CB 199 + DB $28,$04 ; LLA 4 + DB $54,C0005 ; CALL C0005 + DB $78,D0091 ; SAB D0091 +; 386: return path + DB $66,$02 ; LLW 2 + DB $5A ; LEAVE +; 387: end +; 388: def setpfx_11(path) +C0023: ; setpfx_11() + ; path = 2 +; 389: byte params[3] + ; params = 4 +; 390: +; 391: params.0 = 1 + JSR _INTERP + DB $58,$07,$01 ; ENTER 7,1 + DB $28,$04 ; LLA 4 + DB $2A,$01 ; CB 1 + DB $70 ; SB +; 392: params:1 = path + DB $28,$05 ; LLA 5 + DB $66,$02 ; LLW 2 + DB $72 ; SW +; 393: perr = syscall($C6, @params) + DB $2A,$C6 ; CB 198 + DB $28,$04 ; LLA 4 + DB $54,C0005 ; CALL C0005 + DB $78,D0091 ; SAB D0091 +; 394: return path + DB $66,$02 ; LLW 2 + DB $5A ; LEAVE +; 395: end +; 396: def open_21(path, buff) +C0025: ; open_21() + ; path = 2 + ; buff = 4 +; 397: byte params[6] + ; params = 6 +; 398: +; 399: params.0 = 3 + JSR _INTERP + DB $58,$0C,$02 ; ENTER 12,2 + DB $28,$06 ; LLA 6 + DB $2A,$03 ; CB 3 + DB $70 ; SB +; 400: params:1 = path + DB $28,$07 ; LLA 7 + DB $66,$02 ; LLW 2 + DB $72 ; SW +; 401: params:3 = buff + DB $28,$09 ; LLA 9 + DB $66,$04 ; LLW 4 + DB $72 ; SW +; 402: params.5 = 0 + DB $28,$0B ; LLA 11 + DB $00 ; ZERO + DB $70 ; SB +; 403: perr = syscall($C8, @params) + DB $2A,$C8 ; CB 200 + DB $28,$06 ; LLA 6 + DB $54,C0005 ; CALL C0005 + DB $78,D0091 ; SAB D0091 +; 404: return params.5 + DB $28,$0B ; LLA 11 + DB $60 ; LB + DB $5A ; LEAVE +; 405: end +; 406: def close_11(refnum) +C0027: ; close_11() + ; refnum = 2 +; 407: byte params[2] + ; params = 4 +; 408: +; 409: params.0 = 1 + JSR _INTERP + DB $58,$06,$01 ; ENTER 6,1 + DB $28,$04 ; LLA 4 + DB $2A,$01 ; CB 1 + DB $70 ; SB +; 410: params.1 = refnum + DB $28,$05 ; LLA 5 + DB $66,$02 ; LLW 2 + DB $70 ; SB +; 411: perr = syscall($CC, @params) + DB $2A,$CC ; CB 204 + DB $28,$04 ; LLA 4 + DB $54,C0005 ; CALL C0005 + DB $78,D0091 ; SAB D0091 +; 412: return perr + DB $68,D0091 ; LAB D0091 + DB $5A ; LEAVE +; 413: end +; 414: def read_31(refnum, buff, len) +C0029: ; read_31() + ; refnum = 2 + ; buff = 4 + ; len = 6 +; 415: byte params[8] + ; params = 8 +; 416: +; 417: params.0 = 4 + JSR _INTERP + DB $58,$10,$03 ; ENTER 16,3 + DB $28,$08 ; LLA 8 + DB $2A,$04 ; CB 4 + DB $70 ; SB +; 418: params.1 = refnum + DB $28,$09 ; LLA 9 + DB $66,$02 ; LLW 2 + DB $70 ; SB +; 419: params:2 = buff + DB $28,$0A ; LLA 10 + DB $66,$04 ; LLW 4 + DB $72 ; SW +; 420: params:4 = len + DB $28,$0C ; LLA 12 + DB $66,$06 ; LLW 6 + DB $72 ; SW +; 421: params:6 = 0 + DB $28,$0E ; LLA 14 + DB $00 ; ZERO + DB $72 ; SW +; 422: perr = syscall($CA, @params) + DB $2A,$CA ; CB 202 + DB $28,$08 ; LLA 8 + DB $54,C0005 ; CALL C0005 + DB $78,D0091 ; SAB D0091 +; 423: return params:6 + DB $28,$0E ; LLA 14 + DB $62 ; LW + DB $5A ; LEAVE +; 424: end +; 425: def write_31(refnum, buff, len) +C0031: ; write_31() + ; refnum = 2 + ; buff = 4 + ; len = 6 +; 426: byte params[8] + ; params = 8 +; 427: +; 428: params.0 = 4 + JSR _INTERP + DB $58,$10,$03 ; ENTER 16,3 + DB $28,$08 ; LLA 8 + DB $2A,$04 ; CB 4 + DB $70 ; SB +; 429: params.1 = refnum + DB $28,$09 ; LLA 9 + DB $66,$02 ; LLW 2 + DB $70 ; SB +; 430: params:2 = buff + DB $28,$0A ; LLA 10 + DB $66,$04 ; LLW 4 + DB $72 ; SW +; 431: params:4 = len + DB $28,$0C ; LLA 12 + DB $66,$06 ; LLW 6 + DB $72 ; SW +; 432: params:6 = 0 + DB $28,$0E ; LLA 14 + DB $00 ; ZERO + DB $72 ; SW +; 433: perr = syscall($CB, @params) + DB $2A,$CB ; CB 203 + DB $28,$08 ; LLA 8 + DB $54,C0005 ; CALL C0005 + DB $78,D0091 ; SAB D0091 +; 434: return params:6 + DB $28,$0E ; LLA 14 + DB $62 ; LW + DB $5A ; LEAVE +; 435: end +; 436: def create_41(path, access, type, aux) +C0033: ; create_41() + ; path = 2 + ; access = 4 + ; type = 6 + ; aux = 8 +; 437: byte params[12] + ; params = 10 +; 438: +; 439: params.0 = 7 + JSR _INTERP + DB $58,$16,$04 ; ENTER 22,4 + DB $28,$0A ; LLA 10 + DB $2A,$07 ; CB 7 + DB $70 ; SB +; 440: params:1 = path + DB $28,$0B ; LLA 11 + DB $66,$02 ; LLW 2 + DB $72 ; SW +; 441: params.3 = access + DB $28,$0D ; LLA 13 + DB $66,$04 ; LLW 4 + DB $70 ; SB +; 442: params.4 = type + DB $28,$0E ; LLA 14 + DB $66,$06 ; LLW 6 + DB $70 ; SB +; 443: params:5 = aux + DB $28,$0F ; LLA 15 + DB $66,$08 ; LLW 8 + DB $72 ; SW +; 444: params.7 = $1 + DB $28,$11 ; LLA 17 + DB $2A,$01 ; CB 1 + DB $70 ; SB +; 445: params:8 = 0 + DB $28,$12 ; LLA 18 + DB $00 ; ZERO + DB $72 ; SW +; 446: params:10 = 0 + DB $28,$14 ; LLA 20 + DB $00 ; ZERO + DB $72 ; SW +; 447: perr = syscall($C0, @params) + DB $2A,$C0 ; CB 192 + DB $28,$0A ; LLA 10 + DB $54,C0005 ; CALL C0005 + DB $78,D0091 ; SAB D0091 +; 448: return perr + DB $68,D0091 ; LAB D0091 + DB $5A ; LEAVE +; 449: end +; 450: def destroy_11(path) +C0035: ; destroy_11() + ; path = 2 +; 451: byte params[12] + ; params = 4 +; 452: +; 453: params.0 = 1 + JSR _INTERP + DB $58,$10,$01 ; ENTER 16,1 + DB $28,$04 ; LLA 4 + DB $2A,$01 ; CB 1 + DB $70 ; SB +; 454: params:1 = path + DB $28,$05 ; LLA 5 + DB $66,$02 ; LLW 2 + DB $72 ; SW +; 455: perr = syscall($C1, @params) + DB $2A,$C1 ; CB 193 + DB $28,$04 ; LLA 4 + DB $54,C0005 ; CALL C0005 + DB $78,D0091 ; SAB D0091 +; 456: return perr + DB $68,D0091 ; LAB D0091 + DB $5A ; LEAVE +; 457: end +; 458: def newline_31(refnum, emask, nlchar) +C0037: ; newline_31() + ; refnum = 2 + ; emask = 4 + ; nlchar = 6 +; 459: byte params[4] + ; params = 8 +; 460: +; 461: params.0 = 3 + JSR _INTERP + DB $58,$0C,$03 ; ENTER 12,3 + DB $28,$08 ; LLA 8 + DB $2A,$03 ; CB 3 + DB $70 ; SB +; 462: params.1 = refnum + DB $28,$09 ; LLA 9 + DB $66,$02 ; LLW 2 + DB $70 ; SB +; 463: params.2 = emask + DB $28,$0A ; LLA 10 + DB $66,$04 ; LLW 4 + DB $70 ; SB +; 464: params.3 = nlchar + DB $28,$0B ; LLA 11 + DB $66,$06 ; LLW 6 + DB $70 ; SB +; 465: perr = syscall($C9, @params) + DB $2A,$C9 ; CB 201 + DB $28,$08 ; LLA 8 + DB $54,C0005 ; CALL C0005 + DB $78,D0091 ; SAB D0091 +; 466: return perr + DB $68,D0091 ; LAB D0091 + DB $5A ; LEAVE +; 467: end +; 468: +; 469: ;===================================== +; 470: ; +; 471: ; Editor +; 472: ; +; 473: ;===================================== +; 474: +; 475: def crout +C0039: ; crout() +; 476: cout($0D) + JSR _INTERP + DB $2A,$0D ; CB 13 + DB $54,C0011 ; CALL C0011 +; 477: end + DB $5C ; RET +; 478: def bell +C0041: ; bell() +; 479: drop romcall(0, 0, 0, 0, $FBDD) + JSR _INTERP + DB $00 ; ZERO + DB $00 ; ZERO + DB $00 ; ZERO + DB $00 ; ZERO + DB $2C,$DD,$FB ; CW 64477 + DB $54,C0003 ; CALL C0003 + DB $30 ; DROP +; 480: end + DB $5C ; RET +; 481: ; +; 482: ; Memory management routines +; 483: ; +; 484: defopt strcpy_20(srcstr, dststr) +C0043: ; strcpy_20() + ; srcstr = 2 + ; dststr = 4 +; 485: byte strlen + ; strlen = 6 +; 486: +; 487: strlen = ^srcstr + LDY #7 + LDA #2 + JSR ENTER + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR LB + LDY #$06 + LDA ESTKL,X + STA (FRMP),Y +; 488: while (srcstr).[strlen] == $8D or (srcstr).[strlen] == $A0 + INX +C0045: + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDA #$8D + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDA #$A0 + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + JSR LOR + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0046 +: +; 489: strlen = strlen - 1 + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR SUB + LDY #$06 + LDA ESTKL,X + STA (FRMP),Y +; 490: loop + INX + JMP C0045 +C0046: +; 491: ^dststr = strlen + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SB +; 492: memcpy(srcstr + 1, dststr + 1, strlen) + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR C0009 +; 493: end + JMP LEAVE +; 494: defopt heapaddr_21(ofst, mask) +C0047: ; heapaddr_21() + ; ofst = 2 + ; mask = 4 +; 495: word addr + ; addr = 6 +; 496: +; 497: addr = (ofst << 7) + strheap + LDY #8 + LDA #2 + JSR ENTER + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$07 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SHL + DEX + STY ESTKL,X + LDA #$48 + STA ESTKH,X + JSR ADD + LDY #$06 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 498: while !(mask & 1) + INX +C0049: + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR BAND + JSR NOT + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0050 +: +; 499: addr = addr + 16 + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$10 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + LDY #$06 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 500: mask = mask >> 1 + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SHR + LDY #$04 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 501: loop + INX + JMP C0049 +C0050: +; 502: return addr + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JMP LEAVE +; 503: end +; 504: defopt sizemask_11(size) +C0051: ; sizemask_11() + ; size = 2 +; 505: if size <= 16 + LDY #4 + LDA #1 + JSR ENTER + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$10 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ISLE + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0053 +: +; 506: return $01 + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JMP LEAVE +; 507: elsif size <= 32 + JMP C0054 +C0053: + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$20 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ISLE + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0055 +: +; 508: return $03 + DEX + LDA #$03 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JMP LEAVE +; 509: elsif size <= 48 + JMP C0054 +C0055: + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$30 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ISLE + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0056 +: +; 510: return $07 + DEX + LDA #$07 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JMP LEAVE +; 511: elsif size <= 64 + JMP C0054 +C0056: + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$40 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ISLE + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0057 +: +; 512: return $0F + DEX + LDA #$0F + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JMP LEAVE +; 513: elsif size <= 80 + JMP C0054 +C0057: + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$50 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ISLE + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0058 +: +; 514: return $1F + DEX + LDA #$1F + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JMP LEAVE +; 515: fin +C0058: +C0054: +; 516: return 0 + DEX + LDY #$00 + STY ESTKL,X + STY ESTKH,X + JMP LEAVE +; 517: end +; 518: defopt heapalloc_11(size) +C0059: ; heapalloc_11() + ; size = 2 +; 519: byte szmask, i + ; szmask = 4 + ; i = 5 +; 520: word mapmask + ; mapmask = 6 +; 521: +; 522: szmask = sizemask_11(size) + LDY #8 + LDA #1 + JSR ENTER + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JSR C0051 + LDY #$04 + LDA ESTKL,X + STA (FRMP),Y +; 523: for i = strheapmsz - 1 downto 0 + LDA #$E0 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR SUB +C0062: + LDY #$05 + LDA ESTKL,X + STA (FRMP),Y + DEX + LDY #$00 + STY ESTKL,X + STY ESTKH,X + INX + LDA ESTKL,X + CMP ESTKL-1,X + LDA ESTKH,X + SBC ESTKH-1,X + BPL :+ + JMP C0061 +: + LDA ESTKL,X + BNE :+ + DEC ESTKH,X +: DEC ESTKL,X +; 524: if strheapmap.[i] <> $FF + DEX + STY ESTKL,X + LDA #$1F + STA ESTKH,X + DEX + LDY #$05 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDA #$FF + STA ESTKL,X + STY ESTKH,X + JSR ISNE + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0063 +: +; 525: mapmask = szmask + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDY #$06 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 526: repeat + INX +C0066: +; 527: if strheapmap.[i] & mapmask + DEX + LDY #$00 + STY ESTKL,X + LDA #$1F + STA ESTKH,X + DEX + LDY #$05 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JSR BAND + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0067 +: +; 528: mapmask = mapmask << 1 + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SHL + LDY #$06 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 529: else + INX + JMP C0068 +C0067: +; 530: strheapmap.[i] = strheapmap.[i] ? mapmask + DEX + LDY #$00 + STY ESTKL,X + LDA #$1F + STA ESTKH,X + DEX + LDY #$05 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + DEX + STY ESTKL,X + LDA #$1F + STA ESTKH,X + DEX + LDY #$05 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JSR IOR + LDY #$00 + JSR SB +; 531: return heapaddr_21(i, mapmask) + LDY #$05 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JSR C0047 + JMP LEAVE +; 532: fin +C0068: +; 533: until mapmask & $100 + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$00 + STY ESTKL,X + LDA #$01 + STA ESTKH,X + JSR BAND + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0066 +: +C0065: +; 534: fin +C0063: +C0064: +; 535: next + JMP C0062 +C0061: +; 536: bell() + INX + JSR C0041 +; 537: prstr(@outofmem) + DEX + LDA #D0092 + STA ESTKH,X + JSR C0015 +; 538: return 0 + DEX + LDY #$00 + STY ESTKL,X + STY ESTKH,X + JMP LEAVE +; 539: end +; 540: def freestr_10(strptr) +C0069: ; freestr_10() + ; strptr = 2 +; 541: byte mask, ofst + ; mask = 4 + ; ofst = 5 +; 542: +; 543: if strptr and strptr <> @nullstr + JSR _INTERP + DB $58,$06,$01 ; ENTER 6,1 + DB $66,$02 ; LLW 2 + DB $66,$02 ; LLW 2 + DB $26,D0048 ; LA D0048 + DB $42 ; ISNE + DB $24 ; LAND + DB $4C,C0071 ; SKPFLS C0071 +; 544: mask = sizemask_11(^strptr + 1) + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $54,C0051 ; CALL C0051 + DB $74,$04 ; SLB 4 +; 545: ofst = (strptr - strheap) >> 4 + DB $66,$02 ; LLW 2 + DB $2C,$00,$48 ; CW 18432 + DB $04 ; SUB + DB $2A,$04 ; CB 4 + DB $1C ; SHR + DB $74,$05 ; SLB 5 +; 546: mask = mask << (ofst & $07) + DB $64,$04 ; LLB 4 + DB $64,$05 ; LLB 5 + DB $2A,$07 ; CB 7 + DB $14 ; BAND + DB $1A ; SHL + DB $74,$04 ; SLB 4 +; 547: ofst = ofst >> 3 + DB $64,$05 ; LLB 5 + DB $2A,$03 ; CB 3 + DB $1C ; SHR + DB $74,$05 ; SLB 5 +; 548: strheapmap.[ofst] = strheapmap.[ofst] & #mask + DB $2C,$00,$1F ; CW 7936 + DB $64,$05 ; LLB 5 + DB $02 ; IDXB + DB $2C,$00,$1F ; CW 7936 + DB $64,$05 ; LLB 5 + DB $02 ; IDXB + DB $60 ; LB + DB $64,$04 ; LLB 4 + DB $12 ; COMP + DB $14 ; BAND + DB $70 ; SB +; 549: fin +C0071: +C0072: +; 550: end + DB $5A ; LEAVE +; 551: def newstr_11(strptr) +C0073: ; newstr_11() + ; strptr = 2 +; 552: byte strlen + ; strlen = 4 +; 553: word newptr + ; newptr = 5 +; 554: +; 555: strlen = ^strptr + JSR _INTERP + DB $58,$07,$01 ; ENTER 7,1 + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $74,$04 ; SLB 4 +; 556: while (strptr).[strlen] == $8D or (strptr).[strlen] == $A0 +C0075: + DB $66,$02 ; LLW 2 + DB $64,$04 ; LLB 4 + DB $02 ; IDXB + DB $60 ; LB + DB $2A,$8D ; CB 141 + DB $40 ; ISEQ + DB $66,$02 ; LLW 2 + DB $64,$04 ; LLB 4 + DB $02 ; IDXB + DB $60 ; LB + DB $2A,$A0 ; CB 160 + DB $40 ; ISEQ + DB $22 ; LOR + DB $4C,C0076 ; SKPFLS C0076 +; 557: strlen = strlen - 1 + DB $64,$04 ; LLB 4 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $74,$04 ; SLB 4 +; 558: loop + DB $50,C0075 ; SKIP C0075 +C0076: +; 559: if strlen == 0 + DB $64,$04 ; LLB 4 + DB $00 ; ZERO + DB $40 ; ISEQ + DB $4C,C0077 ; SKPFLS C0077 +; 560: return @nullstr + DB $26,D0048 ; LA D0048 + DB $5A ; LEAVE +; 561: fin +C0077: +C0078: +; 562: newptr = heapalloc_11(strlen + 1) + DB $64,$04 ; LLB 4 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $54,C0059 ; CALL C0059 + DB $76,$05 ; SLW 5 +; 563: if newptr + DB $66,$05 ; LLW 5 + DB $4C,C0079 ; SKPFLS C0079 +; 564: memcpy(strptr, newptr, strlen + 1) + DB $66,$02 ; LLW 2 + DB $66,$05 ; LLW 5 + DB $64,$04 ; LLB 4 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $54,C0009 ; CALL C0009 +; 565: ^newptr = strlen + DB $66,$05 ; LLW 5 + DB $64,$04 ; LLB 4 + DB $70 ; SB +; 566: return newptr + DB $66,$05 ; LLW 5 + DB $5A ; LEAVE +; 567: fin +C0079: +C0080: +; 568: return @nullstr + DB $26,D0048 ; LA D0048 + DB $5A ; LEAVE +; 569: end +; 570: def inittxtbuf +C0081: ; inittxtbuf() +; 571: word i + ; i = 2 +; 572: +; 573: memset(0, strheapmap, strheapmsz) + JSR _INTERP + DB $58,$04,$00 ; ENTER 4,0 + DB $00 ; ZERO + DB $2C,$00,$1F ; CW 7936 + DB $2A,$E0 ; CB 224 + DB $54,C0007 ; CALL C0007 +; 574: memset(@nullstr, strlinbuf, maxfill * 2) + DB $26,D0048 ; LA D0048 + DB $2C,$00,$10 ; CW 4096 + DB $2C,$F4,$05 ; CW 1524 + DB $2A,$02 ; CB 2 + DB $06 ; MUL + DB $54,C0007 ; CALL C0007 +; 575: numlines = 0 + DB $00 ; ZERO + DB $7A,D0209 ; SAW D0209 +; 576: cursrow = 0 + DB $00 ; ZERO + DB $7A,D0203 ; SAW D0203 +; 577: curscol = 0 + DB $00 ; ZERO + DB $78,D0200 ; SAB D0200 +; 578: cursx = 0 + DB $00 ; ZERO + DB $78,D0197 ; SAB D0197 +; 579: cursy = 0 + DB $00 ; ZERO + DB $78,D0198 ; SAB D0198 +; 580: scrnleft = 0 + DB $00 ; ZERO + DB $78,D0199 ; SAB D0199 +; 581: scrntop = 0 + DB $00 ; ZERO + DB $7A,D0205 ; SAW D0205 +; 582: cutbuf = 0 + DB $00 ; ZERO + DB $7A,D0211 ; SAW D0211 +; 583: end + DB $5A ; LEAVE +; 584: ; +; 585: ; Case conversion/printing routines +; 586: ; +; 587: def caseconv_11(chr) +C0083: ; caseconv_11() + ; chr = 2 +; 588: if flags & uppercase + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $68,D0195 ; LAB D0195 + DB $2A,$08 ; CB 8 + DB $14 ; BAND + DB $4C,C0085 ; SKPFLS C0085 +; 589: if chr & $E0 == $E0 + DB $66,$02 ; LLW 2 + DB $2A,$E0 ; CB 224 + DB $14 ; BAND + DB $2A,$E0 ; CB 224 + DB $40 ; ISEQ + DB $4C,C0087 ; SKPFLS C0087 +; 590: chr = chr - $E0 + DB $66,$02 ; LLW 2 + DB $2A,$E0 ; CB 224 + DB $04 ; SUB + DB $76,$02 ; SLW 2 +; 591: fin +C0087: +C0088: +; 592: fin +C0085: +C0086: +; 593: return chr + DB $66,$02 ; LLW 2 + DB $5A ; LEAVE +; 594: end +; 595: def strupper_10(strptr) +C0089: ; strupper_10() + ; strptr = 2 +; 596: byte i, chr + ; i = 4 + ; chr = 5 +; 597: +; 598: for i = ^strptr downto 1 + JSR _INTERP + DB $58,$06,$01 ; ENTER 6,1 + DB $66,$02 ; LLW 2 + DB $60 ; LB +C0092: + DB $6C,$04 ; DLB 4 + DB $2A,$01 ; CB 1 + DB $38,C0091 ; SKPLT C0091 + DB $0E ; DECR +; 599: chr = (strptr).[i] + DB $66,$02 ; LLW 2 + DB $64,$04 ; LLB 4 + DB $02 ; IDXB + DB $60 ; LB + DB $74,$05 ; SLB 5 +; 600: if chr & $E0 == $E0 + DB $64,$05 ; LLB 5 + DB $2A,$E0 ; CB 224 + DB $14 ; BAND + DB $2A,$E0 ; CB 224 + DB $40 ; ISEQ + DB $4C,C0093 ; SKPFLS C0093 +; 601: (strptr).[i] = chr - $E0 + DB $66,$02 ; LLW 2 + DB $64,$04 ; LLB 4 + DB $02 ; IDXB + DB $64,$05 ; LLB 5 + DB $2A,$E0 ; CB 224 + DB $04 ; SUB + DB $70 ; SB +; 602: fin +C0093: +C0094: +; 603: next + DB $50,C0092 ; SKIP C0092 +C0091: + DB $30 ; DROP +; 604: end + DB $5A ; LEAVE +; 605: def strlower_10(strptr) +C0095: ; strlower_10() + ; strptr = 2 +; 606: byte i, chr + ; i = 4 + ; chr = 5 +; 607: +; 608: for i = ^strptr downto 1 + JSR _INTERP + DB $58,$06,$01 ; ENTER 6,1 + DB $66,$02 ; LLW 2 + DB $60 ; LB +C0098: + DB $6C,$04 ; DLB 4 + DB $2A,$01 ; CB 1 + DB $38,C0097 ; SKPLT C0097 + DB $0E ; DECR +; 609: chr = (strptr).[i] + DB $66,$02 ; LLW 2 + DB $64,$04 ; LLB 4 + DB $02 ; IDXB + DB $60 ; LB + DB $74,$05 ; SLB 5 +; 610: if chr & $E0 == $00 + DB $64,$05 ; LLB 5 + DB $2A,$E0 ; CB 224 + DB $14 ; BAND + DB $00 ; ZERO + DB $40 ; ISEQ + DB $4C,C0099 ; SKPFLS C0099 +; 611: (strptr).[i] = chr + $E0 + DB $66,$02 ; LLW 2 + DB $64,$04 ; LLB 4 + DB $02 ; IDXB + DB $64,$05 ; LLB 5 + DB $2A,$E0 ; CB 224 + DB $02 ; ADD + DB $70 ; SB +; 612: fin +C0099: +C0100: +; 613: next + DB $50,C0098 ; SKIP C0098 +C0097: + DB $30 ; DROP +; 614: end + DB $5A ; LEAVE +; 615: def txtupper +C0101: ; txtupper() +; 616: word i, strptr + ; i = 2 + ; strptr = 4 +; 617: +; 618: flags = flags ? uppercase + JSR _INTERP + DB $58,$06,$00 ; ENTER 6,0 + DB $68,D0195 ; LAB D0195 + DB $2A,$08 ; CB 8 + DB $16 ; IOR + DB $78,D0195 ; SAB D0195 +; 619: for i = numlines - 1 downto 0 + DB $6A,D0209 ; LAW D0209 + DB $2A,$01 ; CB 1 + DB $04 ; SUB +C0104: + DB $6E,$02 ; DLW 2 + DB $00 ; ZERO + DB $38,C0103 ; SKPLT C0103 + DB $0E ; DECR +; 620: strupper_10(strlinbuf:[i]) + DB $2C,$00,$10 ; CW 4096 + DB $66,$02 ; LLW 2 + DB $1E ; IDXW + DB $62 ; LW + DB $54,C0089 ; CALL C0089 +; 621: next + DB $50,C0104 ; SKIP C0104 +C0103: + DB $30 ; DROP +; 622: end + DB $5A ; LEAVE +; 623: def txtlower +C0105: ; txtlower() +; 624: word i, strptr + ; i = 2 + ; strptr = 4 +; 625: +; 626: flags = flags & #uppercase + JSR _INTERP + DB $58,$06,$00 ; ENTER 6,0 + DB $68,D0195 ; LAB D0195 + DB $2C,$F7,$FF ; CW -9 + DB $14 ; BAND + DB $78,D0195 ; SAB D0195 +; 627: for i = numlines - 1 downto 0 + DB $6A,D0209 ; LAW D0209 + DB $2A,$01 ; CB 1 + DB $04 ; SUB +C0108: + DB $6E,$02 ; DLW 2 + DB $00 ; ZERO + DB $38,C0107 ; SKPLT C0107 + DB $0E ; DECR +; 628: strlower_10(strlinbuf:[i]) + DB $2C,$00,$10 ; CW 4096 + DB $66,$02 ; LLW 2 + DB $1E ; IDXW + DB $62 ; LW + DB $54,C0095 ; CALL C0095 +; 629: next + DB $50,C0108 ; SKIP C0108 +C0107: + DB $30 ; DROP +; 630: end + DB $5A ; LEAVE +; 631: def prbyte_10(h) +C0109: ; prbyte_10() + ; h = 2 +; 632: cout('$') + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$24 ; CB 36 + DB $54,C0011 ; CALL C0011 +; 633: drop romcall(h, 0, 0, 0, $FDDA) + DB $66,$02 ; LLW 2 + DB $00 ; ZERO + DB $00 ; ZERO + DB $00 ; ZERO + DB $2C,$DA,$FD ; CW 64986 + DB $54,C0003 ; CALL C0003 + DB $30 ; DROP +; 634: end + DB $5A ; LEAVE +; 635: def prword_10(h) +C0111: ; prword_10() + ; h = 2 +; 636: cout('$') + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$24 ; CB 36 + DB $54,C0011 ; CALL C0011 +; 637: drop romcall(h >> 8, h, 0, 0, $F941) + DB $66,$02 ; LLW 2 + DB $2A,$08 ; CB 8 + DB $1C ; SHR + DB $66,$02 ; LLW 2 + DB $00 ; ZERO + DB $00 ; ZERO + DB $2C,$41,$F9 ; CW 63809 + DB $54,C0003 ; CALL C0003 + DB $30 ; DROP +; 638: end + DB $5A ; LEAVE +; 639: def print_10(i) +C0113: ; print_10() + ; i = 2 +; 640: byte numstr[7] + ; numstr = 4 +; 641: byte place, sign + ; place = 11 + ; sign = 12 +; 642: +; 643: place = 6 + JSR _INTERP + DB $58,$0D,$01 ; ENTER 13,1 + DB $2A,$06 ; CB 6 + DB $74,$0B ; SLB 11 +; 644: if i < 0 + DB $66,$02 ; LLW 2 + DB $00 ; ZERO + DB $46 ; ISLT + DB $4C,C0115 ; SKPFLS C0115 +; 645: sign = 1 + DB $2A,$01 ; CB 1 + DB $74,$0C ; SLB 12 +; 646: i = -i + DB $66,$02 ; LLW 2 + DB $10 ; NEG + DB $76,$02 ; SLW 2 +; 647: else + DB $50,C0116 ; SKIP C0116 +C0115: +; 648: sign = 0 + DB $00 ; ZERO + DB $74,$0C ; SLB 12 +; 649: fin +C0116: +; 650: while i >= 10 +C0117: + DB $66,$02 ; LLW 2 + DB $2A,$0A ; CB 10 + DB $48 ; ISGE + DB $4C,C0118 ; SKPFLS C0118 +; 651: i =, numstr[place] = i % 10 + '0' + DB $28,$04 ; LLA 4 + DB $64,$0B ; LLB 11 + DB $02 ; IDXB + DB $34 ; PUSH + DB $66,$02 ; LLW 2 + DB $2A,$0A ; CB 10 + DB $0A ; DIV,MOD + DB $2A,$30 ; CB 48 + DB $02 ; ADD + DB $36 ; PULL + DB $2E ; SWAP + DB $70 ; SB + DB $76,$02 ; SLW 2 +; 652: place = place - 1 + DB $64,$0B ; LLB 11 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $74,$0B ; SLB 11 +; 653: loop + DB $50,C0117 ; SKIP C0117 +C0118: +; 654: numstr[place] = i + '0' + DB $28,$04 ; LLA 4 + DB $64,$0B ; LLB 11 + DB $02 ; IDXB + DB $66,$02 ; LLW 2 + DB $2A,$30 ; CB 48 + DB $02 ; ADD + DB $70 ; SB +; 655: place = place - 1 + DB $64,$0B ; LLB 11 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $74,$0B ; SLB 11 +; 656: if sign + DB $64,$0C ; LLB 12 + DB $4C,C0119 ; SKPFLS C0119 +; 657: numstr[place] = '-' + DB $28,$04 ; LLA 4 + DB $64,$0B ; LLB 11 + DB $02 ; IDXB + DB $2A,$2D ; CB 45 + DB $70 ; SB +; 658: place = place - 1 + DB $64,$0B ; LLB 11 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $74,$0B ; SLB 11 +; 659: fin +C0119: +C0120: +; 660: numstr[place] = 6 - place + DB $28,$04 ; LLA 4 + DB $64,$0B ; LLB 11 + DB $02 ; IDXB + DB $2A,$06 ; CB 6 + DB $64,$0B ; LLB 11 + DB $04 ; SUB + DB $70 ; SB +; 661: prstr(@numstr[place]) + DB $28,$04 ; LLA 4 + DB $64,$0B ; LLB 11 + DB $02 ; IDXB + DB $54,C0015 ; CALL C0015 +; 662: end + DB $5A ; LEAVE +; 663: def nametostr_30(namestr, len, strptr) +C0121: ; nametostr_30() + ; namestr = 2 + ; len = 4 + ; strptr = 6 +; 664: ^strptr = len + JSR _INTERP + DB $58,$08,$03 ; ENTER 8,3 + DB $66,$06 ; LLW 6 + DB $66,$04 ; LLW 4 + DB $70 ; SB +; 665: memcpy(namestr, strptr + 1, len) + DB $66,$02 ; LLW 2 + DB $66,$06 ; LLW 6 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $66,$04 ; LLW 4 + DB $54,C0009 ; CALL C0009 +; 666: end + DB $5A ; LEAVE +; 667: ;def toupper_11(c) +; 668: ; if c >= 'a' +; 669: ; if c <= 'z' +; 670: ; return c - $20 +; 671: ; fin +; 672: ; fin +; 673: ; return c +; 674: ;end +; 675: asm toupper_11 +C0123: ; toupper_11() +; 676: LDA ESTKL,X + LDA ESTKL,X +; 677: AND #$7F + AND #$7F +; 678: CMP #'a' + CMP #'a' +; 679: BCC :+ + BCC :+ +; 680: CMP #'z'+1 + CMP #'z'+1 +; 681: BCS :+ + BCS :+ +; 682: SEC + SEC +; 683: SBC #$20 + SBC #$20 +; 684: : STA ESTKL,X +: STA ESTKL,X +; 685: end + RTS +; 686: asm clrhibit_10(strptr) +C0125: ; clrhibit_10() + ; strptr = 2 +; 687: LDY #$02 ; strptr + LDY #4 + LDA #1 + JSR ENTER + LDY #$02 ; strptr +; 688: LDA (FRMP),Y + LDA (FRMP),Y +; 689: STA SRCL + STA SRCL +; 690: INY + INY +; 691: LDA (FRMP),Y + LDA (FRMP),Y +; 692: STA SRCH + STA SRCH +; 693: LDY #$00 + LDY #$00 +; 694: LDA (SRC),Y + LDA (SRC),Y +; 695: BEQ :+ + BEQ :+ +; 696: TAY + TAY +; 697: CLHILP: LDA (SRC),Y +CLHILP: LDA (SRC),Y +; 698: AND #$7F + AND #$7F +; 699: STA (SRC),Y + STA (SRC),Y +; 700: DEY + DEY +; 701: BNE CLHILP + BNE CLHILP +; 702: : +: +; 703: end + JMP LEAVE +; 704: asm sethibit_10(strptr) +C0127: ; sethibit_10() + ; strptr = 2 +; 705: LDY #$02 ; strptr + LDY #4 + LDA #1 + JSR ENTER + LDY #$02 ; strptr +; 706: LDA (FRMP),Y + LDA (FRMP),Y +; 707: STA SRCL + STA SRCL +; 708: INY + INY +; 709: LDA (FRMP),Y + LDA (FRMP),Y +; 710: STA SRCH + STA SRCH +; 711: LDY #$00 + LDY #$00 +; 712: LDA (SRC),Y + LDA (SRC),Y +; 713: BEQ :+ + BEQ :+ +; 714: TAY + TAY +; 715: STHILP: LDA (SRC),Y +STHILP: LDA (SRC),Y +; 716: ORA #$80 + ORA #$80 +; 717: STA (SRC),Y + STA (SRC),Y +; 718: DEY + DEY +; 719: BNE STHILP + BNE STHILP +; 720: : +: +; 721: end + JMP LEAVE +; 722: asm cpyln_20(srcstr, dststr) +C0129: ; cpyln_20() + ; srcstr = 2 + ; dststr = 4 +; 723: LDY #$02 ; srcstr + LDY #6 + LDA #2 + JSR ENTER + LDY #$02 ; srcstr +; 724: LDA (FRMP),Y + LDA (FRMP),Y +; 725: STA SRCL + STA SRCL +; 726: INY + INY +; 727: LDA (FRMP),Y + LDA (FRMP),Y +; 728: STA SRCH + STA SRCH +; 729: INY ; dststr + INY ; dststr +; 730: LDA (FRMP),Y + LDA (FRMP),Y +; 731: STA DSTL + STA DSTL +; 732: INY + INY +; 733: LDA (FRMP),Y + LDA (FRMP),Y +; 734: STA DSTH + STA DSTH +; 735: LDY #$00 + LDY #$00 +; 736: LDA (SRC),Y + LDA (SRC),Y +; 737: TAY + TAY +; 738: LDA #$00 + LDA #$00 +; 739: INY + INY +; 740: STA (DST),Y + STA (DST),Y +; 741: DEY + DEY +; 742: BEQ :++ + BEQ :++ +; 743: CPLNLP: LDA (SRC),Y +CPLNLP: LDA (SRC),Y +; 744: CMP #$20 + CMP #$20 +; 745: BCS :+ + BCS :+ +; 746: ADC #$60 + ADC #$60 +; 747: : AND #$7F +: AND #$7F +; 748: STA (DST),Y + STA (DST),Y +; 749: DEY + DEY +; 750: BNE CPLNLP + BNE CPLNLP +; 751: LDA (SRC),Y + LDA (SRC),Y +; 752: : STA (DST),Y +: STA (DST),Y +; 753: end + JMP LEAVE +; 754: ; +; 755: ; File routines +; 756: ; +; 757: def readtxt_10(filename) +C0131: ; readtxt_10() + ; filename = 2 +; 758: byte txtbuf[81], refnum, i, j + ; txtbuf = 4 + ; refnum = 85 + ; i = 86 + ; j = 87 +; 759: +; 760: refnum = open_21(filename, iobuffer) + JSR _INTERP + DB $58,$58,$01 ; ENTER 88,1 + DB $66,$02 ; LLW 2 + DB $2C,$00,$08 ; CW 2048 + DB $54,C0025 ; CALL C0025 + DB $74,$55 ; SLB 85 +; 761: if refnum + DB $64,$55 ; LLB 85 + DB $4C,C0133 ; SKPFLS C0133 +; 762: drop newline_31(refnum, $7F, $0D) + DB $64,$55 ; LLB 85 + DB $2A,$7F ; CB 127 + DB $2A,$0D ; CB 13 + DB $54,C0037 ; CALL C0037 + DB $30 ; DROP +; 763: repeat +C0136: +; 764: txtbuf = read_31(refnum, @txtbuf + 1, maxlnlen) + DB $64,$55 ; LLB 85 + DB $28,$04 ; LLA 4 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $2A,$4F ; CB 79 + DB $54,C0029 ; CALL C0029 + DB $74,$04 ; SLB 4 +; 765: if txtbuf + DB $64,$04 ; LLB 4 + DB $4C,C0137 ; SKPFLS C0137 +; 766: sethibit_10(@txtbuf) + DB $28,$04 ; LLA 4 + DB $54,C0127 ; CALL C0127 +; 767: if flags & uppercase + DB $68,D0195 ; LAB D0195 + DB $2A,$08 ; CB 8 + DB $14 ; BAND + DB $4C,C0139 ; SKPFLS C0139 +; 768: strupper_10(@txtbuf) + DB $28,$04 ; LLA 4 + DB $54,C0089 ; CALL C0089 +; 769: fin +C0139: +C0140: +; 770: strlinbuf:[numlines] = newstr_11(@txtbuf) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0209 ; LAW D0209 + DB $1E ; IDXW + DB $28,$04 ; LLA 4 + DB $54,C0073 ; CALL C0073 + DB $72 ; SW +; 771: numlines = numlines + 1 + DB $6A,D0209 ; LAW D0209 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $7A,D0209 ; SAW D0209 +; 772: fin +C0137: +C0138: +; 773: if !(numlines & $0F) + DB $6A,D0209 ; LAW D0209 + DB $2A,$0F ; CB 15 + DB $14 ; BAND + DB $20 ; NOT + DB $4C,C0141 ; SKPFLS C0141 +; 774: cout('.') + DB $2A,$2E ; CB 46 + DB $54,C0011 ; CALL C0011 +; 775: fin +C0141: +C0142: +; 776: until txtbuf == 0 or numlines == maxlines + DB $64,$04 ; LLB 4 + DB $00 ; ZERO + DB $40 ; ISEQ + DB $6A,D0209 ; LAW D0209 + DB $2C,$DC,$05 ; CW 1500 + DB $40 ; ISEQ + DB $22 ; LOR + DB $4C,C0136 ; SKPFLS C0136 +C0135: +; 777: drop close_11(refnum) + DB $64,$55 ; LLB 85 + DB $54,C0027 ; CALL C0027 + DB $30 ; DROP +; 778: fin +C0133: +C0134: +; 779: if numlines == 0 + DB $6A,D0209 ; LAW D0209 + DB $00 ; ZERO + DB $40 ; ISEQ + DB $4C,C0143 ; SKPFLS C0143 +; 780: numlines = 1 + DB $2A,$01 ; CB 1 + DB $7A,D0209 ; SAW D0209 +; 781: fin +C0143: +C0144: +; 782: end + DB $5A ; LEAVE +; 783: def writetxt_10(filename) +C0145: ; writetxt_10() + ; filename = 2 +; 784: byte txtbuf[81], refnum + ; txtbuf = 4 + ; refnum = 85 +; 785: byte j, chr + ; j = 86 + ; chr = 87 +; 786: word i, strptr + ; i = 88 + ; strptr = 90 +; 787: +; 788: drop destroy_11(filename) + JSR _INTERP + DB $58,$5C,$01 ; ENTER 92,1 + DB $66,$02 ; LLW 2 + DB $54,C0035 ; CALL C0035 + DB $30 ; DROP +; 789: drop create_41(filename, $C3, $04, $00) ; full access, TXT file + DB $66,$02 ; LLW 2 + DB $2A,$C3 ; CB 195 + DB $2A,$04 ; CB 4 + DB $00 ; ZERO + DB $54,C0033 ; CALL C0033 + DB $30 ; DROP +; 790: refnum = open_21(filename, iobuffer) + DB $66,$02 ; LLW 2 + DB $2C,$00,$08 ; CW 2048 + DB $54,C0025 ; CALL C0025 + DB $74,$55 ; SLB 85 +; 791: if refnum == 0 + DB $64,$55 ; LLB 85 + DB $00 ; ZERO + DB $40 ; ISEQ + DB $4C,C0147 ; SKPFLS C0147 +; 792: return + DB $5A ; LEAVE +; 793: fin +C0147: +C0148: +; 794: for i = 0 to numlines - 1 + DB $00 ; ZERO +C0150: + DB $6E,$58 ; DLW 88 + DB $6A,D0209 ; LAW D0209 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $3A,C0149 ; SKPGT C0149 + DB $0C ; INCR +; 795: cpyln_20(strlinbuf:[i], @txtbuf) + DB $2C,$00,$10 ; CW 4096 + DB $66,$58 ; LLW 88 + DB $1E ; IDXW + DB $62 ; LW + DB $28,$04 ; LLA 4 + DB $54,C0129 ; CALL C0129 +; 796: txtbuf = txtbuf + 1 + DB $64,$04 ; LLB 4 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $74,$04 ; SLB 4 +; 797: txtbuf[txtbuf] = $0D + DB $28,$04 ; LLA 4 + DB $64,$04 ; LLB 4 + DB $02 ; IDXB + DB $2A,$0D ; CB 13 + DB $70 ; SB +; 798: drop write_31(refnum, @txtbuf + 1, txtbuf) + DB $64,$55 ; LLB 85 + DB $28,$04 ; LLA 4 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $64,$04 ; LLB 4 + DB $54,C0031 ; CALL C0031 + DB $30 ; DROP +; 799: if !(i & $0F) + DB $66,$58 ; LLW 88 + DB $2A,$0F ; CB 15 + DB $14 ; BAND + DB $20 ; NOT + DB $4C,C0151 ; SKPFLS C0151 +; 800: cout('.') + DB $2A,$2E ; CB 46 + DB $54,C0011 ; CALL C0011 +; 801: fin +C0151: +C0152: +; 802: next + DB $50,C0150 ; SKIP C0150 +C0149: + DB $30 ; DROP +; 803: drop close_11(refnum) + DB $64,$55 ; LLB 85 + DB $54,C0027 ; CALL C0027 + DB $30 ; DROP +; 804: end + DB $5A ; LEAVE +; 805: ; +; 806: ; Screen routines +; 807: ; +; 808: def clrscrn +C0153: ; clrscrn() +; 809: drop romcall(0, 0, 0, 0, $FC58) + JSR _INTERP + DB $00 ; ZERO + DB $00 ; ZERO + DB $00 ; ZERO + DB $00 ; ZERO + DB $2C,$58,$FC ; CW 64600 + DB $54,C0003 ; CALL C0003 + DB $30 ; DROP +; 810: end + DB $5C ; RET +; 811: def drawrow_30(row, ofst, strptr) +C0155: ; drawrow_30() + ; row = 2 + ; ofst = 4 + ; strptr = 6 +; 812: byte numchars + ; numchars = 8 +; 813: word scrnptr + ; scrnptr = 9 +; 814: +; 815: scrnptr = txtscrn[row] + JSR _INTERP + DB $58,$0B,$03 ; ENTER 11,3 + DB $26,D0000 ; LA D0000 + DB $66,$02 ; LLW 2 + DB $1E ; IDXW + DB $62 ; LW + DB $76,$09 ; SLW 9 +; 816: if ^strptr <= ofst + DB $66,$06 ; LLW 6 + DB $60 ; LB + DB $66,$04 ; LLW 4 + DB $4A ; ISLE + DB $4C,C0157 ; SKPFLS C0157 +; 817: numchars = 0 + DB $00 ; ZERO + DB $74,$08 ; SLB 8 +; 818: else + DB $50,C0158 ; SKIP C0158 +C0157: +; 819: numchars = ^strptr - ofst + DB $66,$06 ; LLW 6 + DB $60 ; LB + DB $66,$04 ; LLW 4 + DB $04 ; SUB + DB $74,$08 ; SLB 8 +; 820: fin +C0158: +; 821: if numchars >= 40 + DB $64,$08 ; LLB 8 + DB $2A,$28 ; CB 40 + DB $48 ; ISGE + DB $4C,C0159 ; SKPFLS C0159 +; 822: numchars = 40 + DB $2A,$28 ; CB 40 + DB $74,$08 ; SLB 8 +; 823: else + DB $50,C0160 ; SKIP C0160 +C0159: +; 824: memset($A0A0, scrnptr + numchars, 40 - numchars) + DB $2C,$A0,$A0 ; CW 41120 + DB $66,$09 ; LLW 9 + DB $64,$08 ; LLB 8 + DB $02 ; ADD + DB $2A,$28 ; CB 40 + DB $64,$08 ; LLB 8 + DB $04 ; SUB + DB $54,C0007 ; CALL C0007 +; 825: fin +C0160: +; 826: memcpy(strptr + ofst + 1, scrnptr, numchars) + DB $66,$06 ; LLW 6 + DB $66,$04 ; LLW 4 + DB $02 ; ADD + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $66,$09 ; LLW 9 + DB $64,$08 ; LLB 8 + DB $54,C0009 ; CALL C0009 +; 827: end + DB $5A ; LEAVE +; 828: defopt drawscrn_20(toprow, ofst) +C0161: ; drawscrn_20() + ; toprow = 2 + ; ofst = 4 +; 829: byte row, numchars + ; row = 6 + ; numchars = 7 +; 830: word strptr, scrnptr + ; strptr = 8 + ; scrnptr = 10 +; 831: +; 832: for row = 0 to 23 + LDY #12 + LDA #2 + JSR ENTER + DEX + STY ESTKL,X + STY ESTKH,X +C0164: + LDY #$06 + LDA ESTKL,X + STA (FRMP),Y + DEX + LDA #$17 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + LDA ESTKH-1,X + SBC ESTKH,X + BPL :+ + JMP C0163 +: + INC ESTKL,X + BNE :+ + INC ESTKH,X +: +; 833: strptr = strlinbuf:[toprow + row] + DEX + STY ESTKL,X + LDA #$10 + STA ESTKH,X + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR IDXW + JSR LW + LDY #$08 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 834: scrnptr = txtscrn[row] + LDA #D0000 + STA ESTKH,X + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR IDXW + JSR LW + LDY #$0A + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 835: if ^strptr <= ofst + LDY #$08 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR LB + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR ISLE + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0165 +: +; 836: numchars = 0 + DEX + LDY #$00 + STY ESTKL,X + STY ESTKH,X + LDY #$07 + LDA ESTKL,X + STA (FRMP),Y +; 837: else + INX + JMP C0166 +C0165: +; 838: numchars = ^strptr - ofst + DEX + LDY #$08 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR LB + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JSR SUB + LDY #$07 + LDA ESTKL,X + STA (FRMP),Y +; 839: fin + INX +C0166: +; 840: if numchars >= 40 + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA #$28 + STA ESTKL,X + STY ESTKH,X + JSR ISGE + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0167 +: +; 841: numchars = 40 + DEX + LDA #$28 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDY #$07 + LDA ESTKL,X + STA (FRMP),Y +; 842: else + INX + JMP C0168 +C0167: +; 843: memset($A0A0, scrnptr + numchars, 40 - numchars) + DEX + LDA #$A0 + STA ESTKL,X + STA ESTKH,X + DEX + LDY #$0A + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + DEX + LDA #$28 + STA ESTKL,X + STY ESTKH,X + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SUB + JSR C0007 +; 844: fin +C0168: +; 845: memcpy(strptr + ofst + 1, scrnptr, numchars) + DEX + LDY #$08 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JSR ADD + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + DEX + LDY #$0A + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR C0009 +; 846: next + JMP C0164 +C0163: +; 847: end + INX + JMP LEAVE +; 848: def cursoff +C0169: ; cursoff() +; 849: if flags & showcurs + JSR _INTERP + DB $68,D0195 ; LAB D0195 + DB $2A,$04 ; CB 4 + DB $14 ; BAND + DB $4C,C0171 ; SKPFLS C0171 +; 850: ^cursptr = underchr + DB $6A,D0207 ; LAW D0207 + DB $68,D0201 ; LAB D0201 + DB $70 ; SB +; 851: flags = flags & #showcurs + DB $68,D0195 ; LAB D0195 + DB $2C,$FB,$FF ; CW -5 + DB $14 ; BAND + DB $78,D0195 ; SAB D0195 +; 852: fin +C0171: +C0172: +; 853: end + DB $5C ; RET +; 854: def curson +C0173: ; curson() +; 855: if !(flags & showcurs) + JSR _INTERP + DB $68,D0195 ; LAB D0195 + DB $2A,$04 ; CB 4 + DB $14 ; BAND + DB $20 ; NOT + DB $4C,C0175 ; SKPFLS C0175 +; 856: cursptr = txtscrn[cursy] + cursx + DB $26,D0000 ; LA D0000 + DB $68,D0198 ; LAB D0198 + DB $1E ; IDXW + DB $62 ; LW + DB $68,D0197 ; LAB D0197 + DB $02 ; ADD + DB $7A,D0207 ; SAW D0207 +; 857: underchr = ^cursptr + DB $6A,D0207 ; LAW D0207 + DB $60 ; LB + DB $78,D0201 ; SAB D0201 +; 858: ^cursptr = curschr + DB $6A,D0207 ; LAW D0207 + DB $68,D0202 ; LAB D0202 + DB $70 ; SB +; 859: flags = flags ? showcurs + DB $68,D0195 ; LAB D0195 + DB $2A,$04 ; CB 4 + DB $16 ; IOR + DB $78,D0195 ; SAB D0195 +; 860: fin +C0175: +C0176: +; 861: end + DB $5C ; RET +; 862: def cursflash() +C0177: ; cursflash() +; 863: if flags & showcurs + JSR _INTERP + DB $68,D0195 ; LAB D0195 + DB $2A,$04 ; CB 4 + DB $14 ; BAND + DB $4C,C0179 ; SKPFLS C0179 +; 864: if flash == 0 + DB $68,D0196 ; LAB D0196 + DB $00 ; ZERO + DB $40 ; ISEQ + DB $4C,C0181 ; SKPFLS C0181 +; 865: ^cursptr = curschr + DB $6A,D0207 ; LAW D0207 + DB $68,D0202 ; LAB D0202 + DB $70 ; SB +; 866: elsif flash == 128 + DB $50,C0182 ; SKIP C0182 +C0181: + DB $68,D0196 ; LAB D0196 + DB $2A,$80 ; CB 128 + DB $40 ; ISEQ + DB $4C,C0183 ; SKPFLS C0183 +; 867: ^cursptr = underchr + DB $6A,D0207 ; LAW D0207 + DB $68,D0201 ; LAB D0201 + DB $70 ; SB +; 868: fin +C0183: +C0182: +; 869: flash = flash + 1 + DB $68,D0196 ; LAB D0196 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $78,D0196 ; SAB D0196 +; 870: fin +C0179: +C0180: +; 871: end + DB $5C ; RET +; 872: def redraw +C0184: ; redraw() +; 873: cursoff() + JSR _INTERP + DB $54,C0169 ; CALL C0169 +; 874: drawscrn_20(scrntop, scrnleft) + DB $6A,D0205 ; LAW D0205 + DB $68,D0199 ; LAB D0199 + DB $54,C0161 ; CALL C0161 +; 875: curson() + DB $54,C0173 ; CALL C0173 +; 876: end + DB $5C ; RET +; 877: def curshome +C0186: ; curshome() +; 878: cursoff() + JSR _INTERP + DB $54,C0169 ; CALL C0169 +; 879: cursrow = 0 + DB $00 ; ZERO + DB $7A,D0203 ; SAW D0203 +; 880: curscol = 0 + DB $00 ; ZERO + DB $78,D0200 ; SAB D0200 +; 881: cursx = 0 + DB $00 ; ZERO + DB $78,D0197 ; SAB D0197 +; 882: cursy = 0 + DB $00 ; ZERO + DB $78,D0198 ; SAB D0198 +; 883: scrnleft = 0 + DB $00 ; ZERO + DB $78,D0199 ; SAB D0199 +; 884: scrntop = 0 + DB $00 ; ZERO + DB $7A,D0205 ; SAW D0205 +; 885: drawscrn_20(scrntop, scrnleft) + DB $6A,D0205 ; LAW D0205 + DB $68,D0199 ; LAB D0199 + DB $54,C0161 ; CALL C0161 +; 886: curson() + DB $54,C0173 ; CALL C0173 +; 887: end + DB $5C ; RET +; 888: def cursend +C0188: ; cursend() +; 889: cursoff() + JSR _INTERP + DB $54,C0169 ; CALL C0169 +; 890: if numlines > 23 + DB $6A,D0209 ; LAW D0209 + DB $2A,$17 ; CB 23 + DB $44 ; ISGT + DB $4C,C0190 ; SKPFLS C0190 +; 891: cursrow = numlines - 1 + DB $6A,D0209 ; LAW D0209 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $7A,D0203 ; SAW D0203 +; 892: cursy = 23 + DB $2A,$17 ; CB 23 + DB $78,D0198 ; SAB D0198 +; 893: scrntop = cursrow - 23 + DB $6A,D0203 ; LAW D0203 + DB $2A,$17 ; CB 23 + DB $04 ; SUB + DB $7A,D0205 ; SAW D0205 +; 894: else + DB $50,C0191 ; SKIP C0191 +C0190: +; 895: cursrow = numlines - 1 + DB $6A,D0209 ; LAW D0209 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $7A,D0203 ; SAW D0203 +; 896: cursy = numlines - 1 + DB $6A,D0209 ; LAW D0209 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $78,D0198 ; SAB D0198 +; 897: scrntop = 0 + DB $00 ; ZERO + DB $7A,D0205 ; SAW D0205 +; 898: fin +C0191: +; 899: curscol = 0 + DB $00 ; ZERO + DB $78,D0200 ; SAB D0200 +; 900: cursx = 0 + DB $00 ; ZERO + DB $78,D0197 ; SAB D0197 +; 901: scrnleft = 0 + DB $00 ; ZERO + DB $78,D0199 ; SAB D0199 +; 902: drawscrn_20(scrntop, scrnleft) + DB $6A,D0205 ; LAW D0205 + DB $68,D0199 ; LAB D0199 + DB $54,C0161 ; CALL C0161 +; 903: curson() + DB $54,C0173 ; CALL C0173 +; 904: end + DB $5C ; RET +; 905: def cursup +C0192: ; cursup() +; 906: if cursrow > 0 + JSR _INTERP + DB $6A,D0203 ; LAW D0203 + DB $00 ; ZERO + DB $44 ; ISGT + DB $4C,C0194 ; SKPFLS C0194 +; 907: cursoff() + DB $54,C0169 ; CALL C0169 +; 908: cursrow = cursrow - 1 + DB $6A,D0203 ; LAW D0203 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $7A,D0203 ; SAW D0203 +; 909: if cursy > 0 + DB $68,D0198 ; LAB D0198 + DB $00 ; ZERO + DB $44 ; ISGT + DB $4C,C0196 ; SKPFLS C0196 +; 910: cursy = cursy - 1 + DB $68,D0198 ; LAB D0198 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $78,D0198 ; SAB D0198 +; 911: else + DB $50,C0197 ; SKIP C0197 +C0196: +; 912: scrntop = cursrow + DB $6A,D0203 ; LAW D0203 + DB $7A,D0205 ; SAW D0205 +; 913: drawscrn_20(scrntop, scrnleft) + DB $6A,D0205 ; LAW D0205 + DB $68,D0199 ; LAB D0199 + DB $54,C0161 ; CALL C0161 +; 914: fin +C0197: +; 915: curson() + DB $54,C0173 ; CALL C0173 +; 916: fin +C0194: +C0195: +; 917: end + DB $5C ; RET +; 918: def pgup +C0198: ; pgup() +; 919: byte i + ; i = 2 +; 920: +; 921: for i = pgjmp downto 0 + JSR _INTERP + DB $58,$03,$00 ; ENTER 3,0 + DB $2A,$10 ; CB 16 +C0201: + DB $6C,$02 ; DLB 2 + DB $00 ; ZERO + DB $38,C0200 ; SKPLT C0200 + DB $0E ; DECR +; 922: cursup() + DB $54,C0192 ; CALL C0192 +; 923: next + DB $50,C0201 ; SKIP C0201 +C0200: + DB $30 ; DROP +; 924: end + DB $5A ; LEAVE +; 925: def cursdown +C0202: ; cursdown() +; 926: if cursrow < numlines - 1 + JSR _INTERP + DB $6A,D0203 ; LAW D0203 + DB $6A,D0209 ; LAW D0209 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $46 ; ISLT + DB $4C,C0204 ; SKPFLS C0204 +; 927: cursoff() + DB $54,C0169 ; CALL C0169 +; 928: cursrow = cursrow + 1 + DB $6A,D0203 ; LAW D0203 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $7A,D0203 ; SAW D0203 +; 929: if cursy < 23 + DB $68,D0198 ; LAB D0198 + DB $2A,$17 ; CB 23 + DB $46 ; ISLT + DB $4C,C0206 ; SKPFLS C0206 +; 930: cursy = cursy + 1 + DB $68,D0198 ; LAB D0198 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $78,D0198 ; SAB D0198 +; 931: else + DB $50,C0207 ; SKIP C0207 +C0206: +; 932: scrntop = cursrow - 23 + DB $6A,D0203 ; LAW D0203 + DB $2A,$17 ; CB 23 + DB $04 ; SUB + DB $7A,D0205 ; SAW D0205 +; 933: drawscrn_20(scrntop, scrnleft) + DB $6A,D0205 ; LAW D0205 + DB $68,D0199 ; LAB D0199 + DB $54,C0161 ; CALL C0161 +; 934: fin +C0207: +; 935: curson() + DB $54,C0173 ; CALL C0173 +; 936: fin +C0204: +C0205: +; 937: end + DB $5C ; RET +; 938: def pgdown +C0208: ; pgdown() +; 939: byte i + ; i = 2 +; 940: +; 941: for i = pgjmp downto 0 + JSR _INTERP + DB $58,$03,$00 ; ENTER 3,0 + DB $2A,$10 ; CB 16 +C0211: + DB $6C,$02 ; DLB 2 + DB $00 ; ZERO + DB $38,C0210 ; SKPLT C0210 + DB $0E ; DECR +; 942: cursdown() + DB $54,C0202 ; CALL C0202 +; 943: next + DB $50,C0211 ; SKIP C0211 +C0210: + DB $30 ; DROP +; 944: end + DB $5A ; LEAVE +; 945: def cursleft +C0212: ; cursleft() +; 946: if curscol > 0 + JSR _INTERP + DB $68,D0200 ; LAB D0200 + DB $00 ; ZERO + DB $44 ; ISGT + DB $4C,C0214 ; SKPFLS C0214 +; 947: cursoff() + DB $54,C0169 ; CALL C0169 +; 948: curscol = curscol - 1 + DB $68,D0200 ; LAB D0200 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $78,D0200 ; SAB D0200 +; 949: if cursx > 0 + DB $68,D0197 ; LAB D0197 + DB $00 ; ZERO + DB $44 ; ISGT + DB $4C,C0216 ; SKPFLS C0216 +; 950: cursx = cursx - 1 + DB $68,D0197 ; LAB D0197 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $78,D0197 ; SAB D0197 +; 951: else + DB $50,C0217 ; SKIP C0217 +C0216: +; 952: scrnleft = curscol + DB $68,D0200 ; LAB D0200 + DB $78,D0199 ; SAB D0199 +; 953: drawscrn_20(scrntop, scrnleft) + DB $6A,D0205 ; LAW D0205 + DB $68,D0199 ; LAB D0199 + DB $54,C0161 ; CALL C0161 +; 954: fin +C0217: +; 955: curson() + DB $54,C0173 ; CALL C0173 +; 956: fin +C0214: +C0215: +; 957: end + DB $5C ; RET +; 958: def pgleft +C0218: ; pgleft() +; 959: byte i + ; i = 2 +; 960: +; 961: for i = 7 downto 0 + JSR _INTERP + DB $58,$03,$00 ; ENTER 3,0 + DB $2A,$07 ; CB 7 +C0221: + DB $6C,$02 ; DLB 2 + DB $00 ; ZERO + DB $38,C0220 ; SKPLT C0220 + DB $0E ; DECR +; 962: cursleft() + DB $54,C0212 ; CALL C0212 +; 963: next + DB $50,C0221 ; SKIP C0221 +C0220: + DB $30 ; DROP +; 964: end + DB $5A ; LEAVE +; 965: def cursright +C0222: ; cursright() +; 966: if curscol < 80 + JSR _INTERP + DB $68,D0200 ; LAB D0200 + DB $2A,$50 ; CB 80 + DB $46 ; ISLT + DB $4C,C0224 ; SKPFLS C0224 +; 967: cursoff() + DB $54,C0169 ; CALL C0169 +; 968: curscol = curscol + 1 + DB $68,D0200 ; LAB D0200 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $78,D0200 ; SAB D0200 +; 969: if cursx < 39 + DB $68,D0197 ; LAB D0197 + DB $2A,$27 ; CB 39 + DB $46 ; ISLT + DB $4C,C0226 ; SKPFLS C0226 +; 970: cursx = cursx + 1 + DB $68,D0197 ; LAB D0197 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $78,D0197 ; SAB D0197 +; 971: else + DB $50,C0227 ; SKIP C0227 +C0226: +; 972: scrnleft = curscol - 39 + DB $68,D0200 ; LAB D0200 + DB $2A,$27 ; CB 39 + DB $04 ; SUB + DB $78,D0199 ; SAB D0199 +; 973: drawscrn_20(scrntop, scrnleft) + DB $6A,D0205 ; LAW D0205 + DB $68,D0199 ; LAB D0199 + DB $54,C0161 ; CALL C0161 +; 974: fin +C0227: +; 975: curson() + DB $54,C0173 ; CALL C0173 +; 976: fin +C0224: +C0225: +; 977: end + DB $5C ; RET +; 978: def pgright +C0228: ; pgright() +; 979: byte i + ; i = 2 +; 980: +; 981: for i = 7 downto 0 + JSR _INTERP + DB $58,$03,$00 ; ENTER 3,0 + DB $2A,$07 ; CB 7 +C0231: + DB $6C,$02 ; DLB 2 + DB $00 ; ZERO + DB $38,C0230 ; SKPLT C0230 + DB $0E ; DECR +; 982: cursright() + DB $54,C0222 ; CALL C0222 +; 983: next + DB $50,C0231 ; SKIP C0231 +C0230: + DB $30 ; DROP +; 984: end + DB $5A ; LEAVE +; 985: ; +; 986: ; Keyboard routines +; 987: ; +; 988: def keyin2e_01 +C0232: ; keyin2e_01() +; 989: repeat + JSR _INTERP +C0235: +; 990: cursflash() + DB $54,C0177 ; CALL C0177 +; 991: until ^keyboard >= 128 + DB $2C,$00,$C0 ; CW 49152 + DB $60 ; LB + DB $2A,$80 ; CB 128 + DB $48 ; ISGE + DB $4C,C0235 ; SKPFLS C0235 +C0234: +; 992: return ^keystrobe + DB $2C,$10,$C0 ; CW 49168 + DB $60 ; LB + DB $5C ; RET +; 993: end +; 994: def keyin2_01 +C0236: ; keyin2_01() +; 995: byte key + ; key = 2 +; 996: +; 997: repeat + JSR _INTERP + DB $58,$03,$00 ; ENTER 3,0 +C0239: +; 998: cursflash() + DB $54,C0177 ; CALL C0177 +; 999: key = ^keyboard + DB $2C,$00,$C0 ; CW 49152 + DB $60 ; LB + DB $74,$02 ; SLB 2 +; 1000: if key == keyctrll + DB $64,$02 ; LLB 2 + DB $2A,$8C ; CB 140 + DB $40 ; ISEQ + DB $4C,C0240 ; SKPFLS C0240 +; 1001: drop ^keystrobe + DB $2C,$10,$C0 ; CW 49168 + DB $60 ; LB + DB $30 ; DROP +; 1002: flags = flags ^ shiftlock + DB $68,D0195 ; LAB D0195 + DB $2A,$80 ; CB 128 + DB $18 ; XOR + DB $78,D0195 ; SAB D0195 +; 1003: key = 0 + DB $00 ; ZERO + DB $74,$02 ; SLB 2 +; 1004: fin +C0240: +C0241: +; 1005: until key >= 128 + DB $64,$02 ; LLB 2 + DB $2A,$80 ; CB 128 + DB $48 ; ISGE + DB $4C,C0239 ; SKPFLS C0239 +C0238: +; 1006: drop ^keystrobe + DB $2C,$10,$C0 ; CW 49168 + DB $60 ; LB + DB $30 ; DROP +; 1007: if key == keyctrln + DB $64,$02 ; LLB 2 + DB $2A,$8E ; CB 142 + DB $40 ; ISEQ + DB $4C,C0242 ; SKPFLS C0242 +; 1008: key = $DB ; [ + DB $2A,$DB ; CB 219 + DB $74,$02 ; SLB 2 +; 1009: elsif key == keyctrlp + DB $50,C0243 ; SKIP C0243 +C0242: + DB $64,$02 ; LLB 2 + DB $2A,$90 ; CB 144 + DB $40 ; ISEQ + DB $4C,C0244 ; SKPFLS C0244 +; 1010: key = $DF ; _ + DB $2A,$DF ; CB 223 + DB $74,$02 ; SLB 2 +; 1011: elsif key == keyctrlb + DB $50,C0243 ; SKIP C0243 +C0244: + DB $64,$02 ; LLB 2 + DB $2A,$82 ; CB 130 + DB $40 ; ISEQ + DB $4C,C0245 ; SKPFLS C0245 +; 1012: key = $DC ; \ + DB $2A,$DC ; CB 220 + DB $74,$02 ; SLB 2 +; 1013: elsif key == keyarrowleft + DB $50,C0243 ; SKIP C0243 +C0245: + DB $64,$02 ; LLB 2 + DB $2A,$88 ; CB 136 + DB $40 ; ISEQ + DB $4C,C0246 ; SKPFLS C0246 +; 1014: if ^pushbttn3 < 128 + DB $2C,$63,$C0 ; CW 49251 + DB $60 ; LB + DB $2A,$80 ; CB 128 + DB $46 ; ISLT + DB $4C,C0247 ; SKPFLS C0247 +; 1015: key = $FF + DB $2A,$FF ; CB 255 + DB $74,$02 ; SLB 2 +; 1016: fin +C0247: +C0248: +; 1017: elsif key >= $C0 and flags < shiftlock + DB $50,C0243 ; SKIP C0243 +C0246: + DB $64,$02 ; LLB 2 + DB $2A,$C0 ; CB 192 + DB $48 ; ISGE + DB $68,D0195 ; LAB D0195 + DB $2A,$80 ; CB 128 + DB $46 ; ISLT + DB $24 ; LAND + DB $4C,C0249 ; SKPFLS C0249 +; 1018: if ^pushbttn3 < 128 + DB $2C,$63,$C0 ; CW 49251 + DB $60 ; LB + DB $2A,$80 ; CB 128 + DB $46 ; ISLT + DB $4C,C0250 ; SKPFLS C0250 +; 1019: if key == $C0 + DB $64,$02 ; LLB 2 + DB $2A,$C0 ; CB 192 + DB $40 ; ISEQ + DB $4C,C0252 ; SKPFLS C0252 +; 1020: key = $D0 ; P + DB $2A,$D0 ; CB 208 + DB $74,$02 ; SLB 2 +; 1021: elsif key == $DD + DB $50,C0253 ; SKIP C0253 +C0252: + DB $64,$02 ; LLB 2 + DB $2A,$DD ; CB 221 + DB $40 ; ISEQ + DB $4C,C0254 ; SKPFLS C0254 +; 1022: key = $CD ; M + DB $2A,$CD ; CB 205 + DB $74,$02 ; SLB 2 +; 1023: elsif key == $DE + DB $50,C0253 ; SKIP C0253 +C0254: + DB $64,$02 ; LLB 2 + DB $2A,$DE ; CB 222 + DB $40 ; ISEQ + DB $4C,C0255 ; SKPFLS C0255 +; 1024: key = $CE ; N + DB $2A,$CE ; CB 206 + DB $74,$02 ; SLB 2 +; 1025: fin +C0255: +C0253: +; 1026: else + DB $50,C0251 ; SKIP C0251 +C0250: +; 1027: key = key ? $E0 + DB $64,$02 ; LLB 2 + DB $2A,$E0 ; CB 224 + DB $16 ; IOR + DB $74,$02 ; SLB 2 +; 1028: fin +C0251: +; 1029: fin +C0249: +C0243: +; 1030: return key + DB $64,$02 ; LLB 2 + DB $5A ; LEAVE +; 1031: end +; 1032: ; +; 1033: ; Printer routines +; 1034: ; +; 1035: def printtxt_10(slot) +C0256: ; printtxt_10() + ; slot = 2 +; 1036: byte txtbuf[80] + ; txtbuf = 4 +; 1037: word i, scrncsw + ; i = 84 + ; scrncsw = 86 +; 1038: +; 1039: scrncsw = *(csw) + JSR _INTERP + DB $58,$58,$01 ; ENTER 88,1 + DB $2A,$36 ; CB 54 + DB $62 ; LW + DB $76,$56 ; SLW 86 +; 1040: *(csw) = $C000 ? (slot << 8) + DB $2A,$36 ; CB 54 + DB $2C,$00,$C0 ; CW 49152 + DB $66,$02 ; LLW 2 + DB $2A,$08 ; CB 8 + DB $1A ; SHL + DB $16 ; IOR + DB $72 ; SW +; 1041: for i = 0 to numlines - 1 + DB $00 ; ZERO +C0259: + DB $6E,$54 ; DLW 84 + DB $6A,D0209 ; LAW D0209 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $3A,C0258 ; SKPGT C0258 + DB $0C ; INCR +; 1042: cpyln_20(strlinbuf:[i], @txtbuf) + DB $2C,$00,$10 ; CW 4096 + DB $66,$54 ; LLW 84 + DB $1E ; IDXW + DB $62 ; LW + DB $28,$04 ; LLA 4 + DB $54,C0129 ; CALL C0129 +; 1043: prstr(@txtbuf) + DB $28,$04 ; LLA 4 + DB $54,C0015 ; CALL C0015 +; 1044: crout() + DB $54,C0039 ; CALL C0039 +; 1045: next + DB $50,C0259 ; SKIP C0259 +C0258: + DB $30 ; DROP +; 1046: *(csw) = scrncsw + DB $2A,$36 ; CB 54 + DB $66,$56 ; LLW 86 + DB $72 ; SW +; 1047: end + DB $5A ; LEAVE +; 1048: def openline_11(row) +C0260: ; openline_11() + ; row = 2 +; 1049: if numlines < maxlines + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $6A,D0209 ; LAW D0209 + DB $2C,$DC,$05 ; CW 1500 + DB $46 ; ISLT + DB $4C,C0262 ; SKPFLS C0262 +; 1050: memcpy(@strlinbuf:[row], @strlinbuf:[row + 1], (numlines - row) * 2) + DB $2C,$00,$10 ; CW 4096 + DB $66,$02 ; LLW 2 + DB $1E ; IDXW + DB $2C,$00,$10 ; CW 4096 + DB $66,$02 ; LLW 2 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $1E ; IDXW + DB $6A,D0209 ; LAW D0209 + DB $66,$02 ; LLW 2 + DB $04 ; SUB + DB $2A,$02 ; CB 2 + DB $06 ; MUL + DB $54,C0009 ; CALL C0009 +; 1051: strlinbuf:[row] = @nullstr + DB $2C,$00,$10 ; CW 4096 + DB $66,$02 ; LLW 2 + DB $1E ; IDXW + DB $26,D0048 ; LA D0048 + DB $72 ; SW +; 1052: numlines = numlines + 1 + DB $6A,D0209 ; LAW D0209 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $7A,D0209 ; SAW D0209 +; 1053: flags = flags ? changed + DB $68,D0195 ; LAB D0195 + DB $2A,$01 ; CB 1 + DB $16 ; IOR + DB $78,D0195 ; SAB D0195 +; 1054: return 1 + DB $2A,$01 ; CB 1 + DB $5A ; LEAVE +; 1055: fin +C0262: +C0263: +; 1056: bell() + DB $54,C0041 ; CALL C0041 +; 1057: return 0 + DB $00 ; ZERO + DB $5A ; LEAVE +; 1058: end +; 1059: def cutline +C0264: ; cutline() +; 1060: freestr_10(cutbuf) + JSR _INTERP + DB $6A,D0211 ; LAW D0211 + DB $54,C0069 ; CALL C0069 +; 1061: cutbuf = strlinbuf:[cursrow] + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0203 ; LAW D0203 + DB $1E ; IDXW + DB $62 ; LW + DB $7A,D0211 ; SAW D0211 +; 1062: memcpy(@strlinbuf:[cursrow + 1], @strlinbuf:[cursrow], (numlines - cursrow) * 2) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0203 ; LAW D0203 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $1E ; IDXW + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0203 ; LAW D0203 + DB $1E ; IDXW + DB $6A,D0209 ; LAW D0209 + DB $6A,D0203 ; LAW D0203 + DB $04 ; SUB + DB $2A,$02 ; CB 2 + DB $06 ; MUL + DB $54,C0009 ; CALL C0009 +; 1063: if numlines > 1 + DB $6A,D0209 ; LAW D0209 + DB $2A,$01 ; CB 1 + DB $44 ; ISGT + DB $4C,C0266 ; SKPFLS C0266 +; 1064: numlines = numlines - 1 + DB $6A,D0209 ; LAW D0209 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $7A,D0209 ; SAW D0209 +; 1065: fin +C0266: +C0267: +; 1066: flags = flags ? changed + DB $68,D0195 ; LAB D0195 + DB $2A,$01 ; CB 1 + DB $16 ; IOR + DB $78,D0195 ; SAB D0195 +; 1067: if cursrow == numlines + DB $6A,D0203 ; LAW D0203 + DB $6A,D0209 ; LAW D0209 + DB $40 ; ISEQ + DB $4C,C0268 ; SKPFLS C0268 +; 1068: cursup() + DB $54,C0192 ; CALL C0192 +; 1069: fin +C0268: +C0269: +; 1070: redraw() + DB $54,C0184 ; CALL C0184 +; 1071: end + DB $5C ; RET +; 1072: def pasteline +C0270: ; pasteline() +; 1073: if cutbuf and numlines < maxlines + JSR _INTERP + DB $6A,D0211 ; LAW D0211 + DB $6A,D0209 ; LAW D0209 + DB $2C,$DC,$05 ; CW 1500 + DB $46 ; ISLT + DB $24 ; LAND + DB $4C,C0272 ; SKPFLS C0272 +; 1074: memcpy(@strlinbuf:[cursrow], @strlinbuf:[cursrow + 1], (numlines - cursrow) * 2) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0203 ; LAW D0203 + DB $1E ; IDXW + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0203 ; LAW D0203 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $1E ; IDXW + DB $6A,D0209 ; LAW D0209 + DB $6A,D0203 ; LAW D0203 + DB $04 ; SUB + DB $2A,$02 ; CB 2 + DB $06 ; MUL + DB $54,C0009 ; CALL C0009 +; 1075: strlinbuf:[cursrow] = newstr_11(cutbuf) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0203 ; LAW D0203 + DB $1E ; IDXW + DB $6A,D0211 ; LAW D0211 + DB $54,C0073 ; CALL C0073 + DB $72 ; SW +; 1076: numlines = numlines + 1 + DB $6A,D0209 ; LAW D0209 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $7A,D0209 ; SAW D0209 +; 1077: flags = flags ? changed + DB $68,D0195 ; LAB D0195 + DB $2A,$01 ; CB 1 + DB $16 ; IOR + DB $78,D0195 ; SAB D0195 +; 1078: redraw() + DB $54,C0184 ; CALL C0184 +; 1079: else + DB $50,C0273 ; SKIP C0273 +C0272: +; 1080: bell() + DB $54,C0041 ; CALL C0041 +; 1081: fin +C0273: +; 1082: end + DB $5C ; RET +; 1083: def joinline +C0274: ; joinline() +; 1084: byte joinstr[80], joinlen + ; joinstr = 2 + ; joinlen = 82 +; 1085: +; 1086: if cursrow < numlines - 1 + JSR _INTERP + DB $58,$53,$00 ; ENTER 83,0 + DB $6A,D0203 ; LAW D0203 + DB $6A,D0209 ; LAW D0209 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $46 ; ISLT + DB $4C,C0276 ; SKPFLS C0276 +; 1087: strcpy_20(strlinbuf:[cursrow], @joinstr) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0203 ; LAW D0203 + DB $1E ; IDXW + DB $62 ; LW + DB $28,$02 ; LLA 2 + DB $54,C0043 ; CALL C0043 +; 1088: joinlen = joinstr + ^(strlinbuf:[cursrow + 1]) + DB $64,$02 ; LLB 2 + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0203 ; LAW D0203 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $1E ; IDXW + DB $62 ; LW + DB $60 ; LB + DB $02 ; ADD + DB $74,$52 ; SLB 82 +; 1089: if joinlen < 80 + DB $64,$52 ; LLB 82 + DB $2A,$50 ; CB 80 + DB $46 ; ISLT + DB $4C,C0278 ; SKPFLS C0278 +; 1090: memcpy(strlinbuf:[cursrow + 1] + 1, @joinstr + joinstr + 1, ^(strlinbuf:[cursrow + 1])) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0203 ; LAW D0203 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $1E ; IDXW + DB $62 ; LW + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $28,$02 ; LLA 2 + DB $64,$02 ; LLB 2 + DB $02 ; ADD + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0203 ; LAW D0203 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $1E ; IDXW + DB $62 ; LW + DB $60 ; LB + DB $54,C0009 ; CALL C0009 +; 1091: joinstr = joinlen + DB $64,$52 ; LLB 82 + DB $74,$02 ; SLB 2 +; 1092: freestr_10(strlinbuf:[cursrow]) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0203 ; LAW D0203 + DB $1E ; IDXW + DB $62 ; LW + DB $54,C0069 ; CALL C0069 +; 1093: strlinbuf:[cursrow] = newstr_11(@joinstr) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0203 ; LAW D0203 + DB $1E ; IDXW + DB $28,$02 ; LLA 2 + DB $54,C0073 ; CALL C0073 + DB $72 ; SW +; 1094: freestr_10(strlinbuf:[cursrow + 1]) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0203 ; LAW D0203 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $1E ; IDXW + DB $62 ; LW + DB $54,C0069 ; CALL C0069 +; 1095: numlines = numlines - 1 + DB $6A,D0209 ; LAW D0209 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $7A,D0209 ; SAW D0209 +; 1096: memcpy(@strlinbuf:[cursrow + 2], @strlinbuf:[cursrow + 1], (numlines - cursrow) * 2) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0203 ; LAW D0203 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $1E ; IDXW + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0203 ; LAW D0203 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $1E ; IDXW + DB $6A,D0209 ; LAW D0209 + DB $6A,D0203 ; LAW D0203 + DB $04 ; SUB + DB $2A,$02 ; CB 2 + DB $06 ; MUL + DB $54,C0009 ; CALL C0009 +; 1097: flags = flags ? changed + DB $68,D0195 ; LAB D0195 + DB $2A,$01 ; CB 1 + DB $16 ; IOR + DB $78,D0195 ; SAB D0195 +; 1098: redraw() + DB $54,C0184 ; CALL C0184 +; 1099: else + DB $50,C0279 ; SKIP C0279 +C0278: +; 1100: bell() + DB $54,C0041 ; CALL C0041 +; 1101: fin +C0279: +; 1102: fin +C0276: +C0277: +; 1103: end + DB $5A ; LEAVE +; 1104: def splitline +C0280: ; splitline() +; 1105: byte splitstr[80], splitlen + ; splitstr = 2 + ; splitlen = 82 +; 1106: +; 1107: if openline_11(cursrow + 1) + JSR _INTERP + DB $58,$53,$00 ; ENTER 83,0 + DB $6A,D0203 ; LAW D0203 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $54,C0260 ; CALL C0260 + DB $4C,C0282 ; SKPFLS C0282 +; 1108: if curscol + DB $68,D0200 ; LAB D0200 + DB $4C,C0284 ; SKPFLS C0284 +; 1109: splitlen = ^(strlinbuf:[cursrow]) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0203 ; LAW D0203 + DB $1E ; IDXW + DB $62 ; LW + DB $60 ; LB + DB $74,$52 ; SLB 82 +; 1110: if curscol < splitlen - 1 + DB $68,D0200 ; LAB D0200 + DB $64,$52 ; LLB 82 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $46 ; ISLT + DB $4C,C0286 ; SKPFLS C0286 +; 1111: memcpy(strlinbuf:[cursrow] + curscol + 1, @splitstr + 1, splitlen - curscol) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0203 ; LAW D0203 + DB $1E ; IDXW + DB $62 ; LW + DB $68,D0200 ; LAB D0200 + DB $02 ; ADD + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $28,$02 ; LLA 2 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $64,$52 ; LLB 82 + DB $68,D0200 ; LAB D0200 + DB $04 ; SUB + DB $54,C0009 ; CALL C0009 +; 1112: splitstr = splitlen - curscol + DB $64,$52 ; LLB 82 + DB $68,D0200 ; LAB D0200 + DB $04 ; SUB + DB $74,$02 ; SLB 2 +; 1113: strlinbuf:[cursrow + 1] = newstr_11(@splitstr) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0203 ; LAW D0203 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $1E ; IDXW + DB $28,$02 ; LLA 2 + DB $54,C0073 ; CALL C0073 + DB $72 ; SW +; 1114: memcpy(strlinbuf:[cursrow] + 1, @splitstr + 1, curscol) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0203 ; LAW D0203 + DB $1E ; IDXW + DB $62 ; LW + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $28,$02 ; LLA 2 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0200 ; LAB D0200 + DB $54,C0009 ; CALL C0009 +; 1115: splitstr = curscol + DB $68,D0200 ; LAB D0200 + DB $74,$02 ; SLB 2 +; 1116: freestr_10(strlinbuf:[cursrow]) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0203 ; LAW D0203 + DB $1E ; IDXW + DB $62 ; LW + DB $54,C0069 ; CALL C0069 +; 1117: strlinbuf:[cursrow] = newstr_11(@splitstr) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0203 ; LAW D0203 + DB $1E ; IDXW + DB $28,$02 ; LLA 2 + DB $54,C0073 ; CALL C0073 + DB $72 ; SW +; 1118: fin +C0286: +C0287: +; 1119: else + DB $50,C0285 ; SKIP C0285 +C0284: +; 1120: strlinbuf:[cursrow + 1] = strlinbuf:[cursrow] + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0203 ; LAW D0203 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $1E ; IDXW + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0203 ; LAW D0203 + DB $1E ; IDXW + DB $62 ; LW + DB $72 ; SW +; 1121: strlinbuf:[cursrow] = @nullstr + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0203 ; LAW D0203 + DB $1E ; IDXW + DB $26,D0048 ; LA D0048 + DB $72 ; SW +; 1122: fin +C0285: +; 1123: curscol = 0 + DB $00 ; ZERO + DB $78,D0200 ; SAB D0200 +; 1124: cursx = 0 + DB $00 ; ZERO + DB $78,D0197 ; SAB D0197 +; 1125: scrnleft = 0 + DB $00 ; ZERO + DB $78,D0199 ; SAB D0199 +; 1126: redraw() + DB $54,C0184 ; CALL C0184 +; 1127: cursdown() + DB $54,C0202 ; CALL C0202 +; 1128: fin +C0282: +C0283: +; 1129: end + DB $5A ; LEAVE +; 1130: def editkey_11(key) +C0288: ; editkey_11() + ; key = 2 +; 1131: if key >= keyspace + JSR _INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $66,$02 ; LLW 2 + DB $2A,$A0 ; CB 160 + DB $48 ; ISGE + DB $4C,C0290 ; SKPFLS C0290 +; 1132: return 1 + DB $2A,$01 ; CB 1 + DB $5A ; LEAVE +; 1133: elsif key == keydelete + DB $50,C0291 ; SKIP C0291 +C0290: + DB $66,$02 ; LLW 2 + DB $2A,$FF ; CB 255 + DB $40 ; ISEQ + DB $4C,C0292 ; SKPFLS C0292 +; 1134: return 1 + DB $2A,$01 ; CB 1 + DB $5A ; LEAVE +; 1135: elsif key == keyctrld + DB $50,C0291 ; SKIP C0291 +C0292: + DB $66,$02 ; LLW 2 + DB $2A,$84 ; CB 132 + DB $40 ; ISEQ + DB $4C,C0293 ; SKPFLS C0293 +; 1136: return 1 + DB $2A,$01 ; CB 1 + DB $5A ; LEAVE +; 1137: elsif key == keyctrlr + DB $50,C0291 ; SKIP C0291 +C0293: + DB $66,$02 ; LLW 2 + DB $2A,$92 ; CB 146 + DB $40 ; ISEQ + DB $4C,C0294 ; SKPFLS C0294 +; 1138: return 1 + DB $2A,$01 ; CB 1 + DB $5A ; LEAVE +; 1139: fin +C0294: +C0291: +; 1140: return 0 + DB $00 ; ZERO + DB $5A ; LEAVE +; 1141: end +; 1142: def editline_11(key) +C0295: ; editline_11() + ; key = 2 +; 1143: byte editstr[80] + ; editstr = 4 +; 1144: word undoline + ; undoline = 84 +; 1145: +; 1146: if (editkey_11(key)) + JSR _INTERP + DB $58,$56,$01 ; ENTER 86,1 + DB $66,$02 ; LLW 2 + DB $54,C0288 ; CALL C0288 + DB $4C,C0297 ; SKPFLS C0297 +; 1147: flags = flags ? changed + DB $68,D0195 ; LAB D0195 + DB $2A,$01 ; CB 1 + DB $16 ; IOR + DB $78,D0195 ; SAB D0195 +; 1148: memset($A0A0, @editstr, 80) + DB $2C,$A0,$A0 ; CW 41120 + DB $28,$04 ; LLA 4 + DB $2A,$50 ; CB 80 + DB $54,C0007 ; CALL C0007 +; 1149: strcpy_20(strlinbuf:[cursrow], @editstr) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0203 ; LAW D0203 + DB $1E ; IDXW + DB $62 ; LW + DB $28,$04 ; LLA 4 + DB $54,C0043 ; CALL C0043 +; 1150: undoline = strlinbuf:[cursrow] + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0203 ; LAW D0203 + DB $1E ; IDXW + DB $62 ; LW + DB $76,$54 ; SLW 84 +; 1151: strlinbuf:[cursrow] = @editstr + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0203 ; LAW D0203 + DB $1E ; IDXW + DB $28,$04 ; LLA 4 + DB $72 ; SW +; 1152: repeat +C0300: +; 1153: if key >= keyspace + DB $66,$02 ; LLW 2 + DB $2A,$A0 ; CB 160 + DB $48 ; ISGE + DB $4C,C0301 ; SKPFLS C0301 +; 1154: if key == keydelete + DB $66,$02 ; LLW 2 + DB $2A,$FF ; CB 255 + DB $40 ; ISEQ + DB $4C,C0303 ; SKPFLS C0303 +; 1155: if curscol > 0 + DB $68,D0200 ; LAB D0200 + DB $00 ; ZERO + DB $44 ; ISGT + DB $4C,C0305 ; SKPFLS C0305 +; 1156: if curscol <= editstr + DB $68,D0200 ; LAB D0200 + DB $64,$04 ; LLB 4 + DB $4A ; ISLE + DB $4C,C0307 ; SKPFLS C0307 +; 1157: memcpy(@editstr[curscol + 1], @editstr[curscol], editstr - curscol) + DB $28,$04 ; LLA 4 + DB $68,D0200 ; LAB D0200 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $02 ; IDXB + DB $28,$04 ; LLA 4 + DB $68,D0200 ; LAB D0200 + DB $02 ; IDXB + DB $64,$04 ; LLB 4 + DB $68,D0200 ; LAB D0200 + DB $04 ; SUB + DB $54,C0009 ; CALL C0009 +; 1158: editstr = editstr - 1 + DB $64,$04 ; LLB 4 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $74,$04 ; SLB 4 +; 1159: fin +C0307: +C0308: +; 1160: curscol = curscol - 1 + DB $68,D0200 ; LAB D0200 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $78,D0200 ; SAB D0200 +; 1161: cursoff() + DB $54,C0169 ; CALL C0169 +; 1162: if cursx > 0 + DB $68,D0197 ; LAB D0197 + DB $00 ; ZERO + DB $44 ; ISGT + DB $4C,C0309 ; SKPFLS C0309 +; 1163: cursx = cursx - 1 + DB $68,D0197 ; LAB D0197 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $78,D0197 ; SAB D0197 +; 1164: drawrow_30(cursy, scrnleft, @editstr) + DB $68,D0198 ; LAB D0198 + DB $68,D0199 ; LAB D0199 + DB $28,$04 ; LLA 4 + DB $54,C0155 ; CALL C0155 +; 1165: else + DB $50,C0310 ; SKIP C0310 +C0309: +; 1166: scrnleft = scrnleft - 1 + DB $68,D0199 ; LAB D0199 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $78,D0199 ; SAB D0199 +; 1167: drawscrn_20(scrntop, scrnleft) + DB $6A,D0205 ; LAW D0205 + DB $68,D0199 ; LAB D0199 + DB $54,C0161 ; CALL C0161 +; 1168: fin +C0310: +; 1169: curson() + DB $54,C0173 ; CALL C0173 +; 1170: fin +C0305: +C0306: +; 1171: elsif curscol < maxlnlen + DB $50,C0304 ; SKIP C0304 +C0303: + DB $68,D0200 ; LAB D0200 + DB $2A,$4F ; CB 79 + DB $46 ; ISLT + DB $4C,C0311 ; SKPFLS C0311 +; 1172: curscol = curscol + 1 + DB $68,D0200 ; LAB D0200 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $78,D0200 ; SAB D0200 +; 1173: cursx = cursx + 1 + DB $68,D0197 ; LAB D0197 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $78,D0197 ; SAB D0197 +; 1174: if flags & insmode + DB $68,D0195 ; LAB D0195 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C0312 ; SKPFLS C0312 +; 1175: if editstr < maxlnlen or editstr.maxlnlen == $A0 + DB $64,$04 ; LLB 4 + DB $2A,$4F ; CB 79 + DB $46 ; ISLT + DB $28,$53 ; LLA 83 + DB $60 ; LB + DB $2A,$A0 ; CB 160 + DB $40 ; ISEQ + DB $22 ; LOR + DB $4C,C0314 ; SKPFLS C0314 +; 1176: editstr = editstr + 1 + DB $64,$04 ; LLB 4 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $74,$04 ; SLB 4 +; 1177: if curscol >= editstr + DB $68,D0200 ; LAB D0200 + DB $64,$04 ; LLB 4 + DB $48 ; ISGE + DB $4C,C0316 ; SKPFLS C0316 +; 1178: editstr = curscol + DB $68,D0200 ; LAB D0200 + DB $74,$04 ; SLB 4 +; 1179: else + DB $50,C0317 ; SKIP C0317 +C0316: +; 1180: memcpy(@editstr[curscol], @editstr[curscol + 1], editstr - curscol) + DB $28,$04 ; LLA 4 + DB $68,D0200 ; LAB D0200 + DB $02 ; IDXB + DB $28,$04 ; LLA 4 + DB $68,D0200 ; LAB D0200 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $02 ; IDXB + DB $64,$04 ; LLB 4 + DB $68,D0200 ; LAB D0200 + DB $04 ; SUB + DB $54,C0009 ; CALL C0009 +; 1181: fin +C0317: +; 1182: else + DB $50,C0315 ; SKIP C0315 +C0314: +; 1183: curscol = curscol - 1 + DB $68,D0200 ; LAB D0200 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $78,D0200 ; SAB D0200 +; 1184: cursx = cursx - 1 + DB $68,D0197 ; LAB D0197 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $78,D0197 ; SAB D0197 +; 1185: key = editstr[curscol] + DB $28,$04 ; LLA 4 + DB $68,D0200 ; LAB D0200 + DB $02 ; IDXB + DB $60 ; LB + DB $76,$02 ; SLW 2 +; 1186: bell() + DB $54,C0041 ; CALL C0041 +; 1187: fin +C0315: +; 1188: else + DB $50,C0313 ; SKIP C0313 +C0312: +; 1189: if curscol > editstr + DB $68,D0200 ; LAB D0200 + DB $64,$04 ; LLB 4 + DB $44 ; ISGT + DB $4C,C0318 ; SKPFLS C0318 +; 1190: editstr = curscol + DB $68,D0200 ; LAB D0200 + DB $74,$04 ; SLB 4 +; 1191: fin +C0318: +C0319: +; 1192: fin +C0313: +; 1193: editstr[curscol] = caseconv_11(key) + DB $28,$04 ; LLA 4 + DB $68,D0200 ; LAB D0200 + DB $02 ; IDXB + DB $66,$02 ; LLW 2 + DB $54,C0083 ; CALL C0083 + DB $70 ; SB +; 1194: cursoff() + DB $54,C0169 ; CALL C0169 +; 1195: if cursx <= 39 + DB $68,D0197 ; LAB D0197 + DB $2A,$27 ; CB 39 + DB $4A ; ISLE + DB $4C,C0320 ; SKPFLS C0320 +; 1196: drawrow_30(cursy, scrnleft, @editstr) + DB $68,D0198 ; LAB D0198 + DB $68,D0199 ; LAB D0199 + DB $28,$04 ; LLA 4 + DB $54,C0155 ; CALL C0155 +; 1197: else + DB $50,C0321 ; SKIP C0321 +C0320: +; 1198: scrnleft = scrnleft + 1 + DB $68,D0199 ; LAB D0199 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $78,D0199 ; SAB D0199 +; 1199: cursx = 39 + DB $2A,$27 ; CB 39 + DB $78,D0197 ; SAB D0197 +; 1200: drawscrn_20(scrntop, scrnleft) + DB $6A,D0205 ; LAW D0205 + DB $68,D0199 ; LAB D0199 + DB $54,C0161 ; CALL C0161 +; 1201: fin +C0321: +; 1202: curson() + DB $54,C0173 ; CALL C0173 +; 1203: else + DB $50,C0304 ; SKIP C0304 +C0311: +; 1204: bell() + DB $54,C0041 ; CALL C0041 +; 1205: fin +C0304: +; 1206: elsif key == keyctrld + DB $50,C0302 ; SKIP C0302 +C0301: + DB $66,$02 ; LLW 2 + DB $2A,$84 ; CB 132 + DB $40 ; ISEQ + DB $4C,C0322 ; SKPFLS C0322 +; 1207: if curscol < editstr + DB $68,D0200 ; LAB D0200 + DB $64,$04 ; LLB 4 + DB $46 ; ISLT + DB $4C,C0323 ; SKPFLS C0323 +; 1208: memcpy(@editstr[curscol + 2], @editstr[curscol + 1], editstr - curscol) + DB $28,$04 ; LLA 4 + DB $68,D0200 ; LAB D0200 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $02 ; IDXB + DB $28,$04 ; LLA 4 + DB $68,D0200 ; LAB D0200 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $02 ; IDXB + DB $64,$04 ; LLB 4 + DB $68,D0200 ; LAB D0200 + DB $04 ; SUB + DB $54,C0009 ; CALL C0009 +; 1209: editstr = editstr - 1 + DB $64,$04 ; LLB 4 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $74,$04 ; SLB 4 +; 1210: cursoff() + DB $54,C0169 ; CALL C0169 +; 1211: drawrow_30(cursy, scrnleft, @editstr) + DB $68,D0198 ; LAB D0198 + DB $68,D0199 ; LAB D0199 + DB $28,$04 ; LLA 4 + DB $54,C0155 ; CALL C0155 +; 1212: curson() + DB $54,C0173 ; CALL C0173 +; 1213: fin +C0323: +C0324: +; 1214: elsif key == keyctrlr + DB $50,C0302 ; SKIP C0302 +C0322: + DB $66,$02 ; LLW 2 + DB $2A,$92 ; CB 146 + DB $40 ; ISEQ + DB $4C,C0325 ; SKPFLS C0325 +; 1215: strcpy_20(undoline, @editstr) + DB $66,$54 ; LLW 84 + DB $28,$04 ; LLA 4 + DB $54,C0043 ; CALL C0043 +; 1216: cursoff() + DB $54,C0169 ; CALL C0169 +; 1217: drawrow_30(cursy, scrnleft, @editstr) + DB $68,D0198 ; LAB D0198 + DB $68,D0199 ; LAB D0199 + DB $28,$04 ; LLA 4 + DB $54,C0155 ; CALL C0155 +; 1218: curson() + DB $54,C0173 ; CALL C0173 +; 1219: fin +C0325: +C0302: +; 1220: key = keyin_01() + DB $26,D0213 ; LA D0213 + DB $62 ; LW + DB $34 ; PUSH + DB $36 ; PULL + DB $56 ; ICAL + DB $76,$02 ; SLW 2 +; 1221: until !editkey_11(key) + DB $66,$02 ; LLW 2 + DB $54,C0288 ; CALL C0288 + DB $20 ; NOT + DB $4C,C0300 ; SKPFLS C0300 +C0299: +; 1222: if editstr + DB $64,$04 ; LLB 4 + DB $4C,C0326 ; SKPFLS C0326 +; 1223: strlinbuf:[cursrow] = newstr_11(@editstr) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0203 ; LAW D0203 + DB $1E ; IDXW + DB $28,$04 ; LLA 4 + DB $54,C0073 ; CALL C0073 + DB $72 ; SW +; 1224: else + DB $50,C0327 ; SKIP C0327 +C0326: +; 1225: strlinbuf:[cursrow] = @nullstr + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0203 ; LAW D0203 + DB $1E ; IDXW + DB $26,D0048 ; LA D0048 + DB $72 ; SW +; 1226: fin +C0327: +; 1227: freestr_10(undoline) + DB $66,$54 ; LLW 84 + DB $54,C0069 ; CALL C0069 +; 1228: fin +C0297: +C0298: +; 1229: return key + DB $66,$02 ; LLW 2 + DB $5A ; LEAVE +; 1230: end +; 1231: def editmode +C0328: ; editmode() +; 1232: repeat + JSR _INTERP +C0331: +; 1233: when editline_11(keyin_01()) + DB $26,D0213 ; LA D0213 + DB $62 ; LW + DB $34 ; PUSH + DB $36 ; PULL + DB $56 ; ICAL + DB $54,C0295 ; CALL C0295 +; 1234: is keyarrowup + DB $2A,$8B ; CB 139 + DB $3E,C0333 ; SKPNE C0333 +; 1235: cursup() + DB $54,C0192 ; CALL C0192 +; 1236: is keyarrowdown + DB $50,C0332 ; SKIP C0332 +C0333: + DB $2A,$8A ; CB 138 + DB $3E,C0334 ; SKPNE C0334 +; 1237: cursdown() + DB $54,C0202 ; CALL C0202 +; 1238: is keyarrowleft + DB $50,C0332 ; SKIP C0332 +C0334: + DB $2A,$88 ; CB 136 + DB $3E,C0335 ; SKPNE C0335 +; 1239: cursleft() + DB $54,C0212 ; CALL C0212 +; 1240: is keyarrowright + DB $50,C0332 ; SKIP C0332 +C0335: + DB $2A,$95 ; CB 149 + DB $3E,C0336 ; SKPNE C0336 +; 1241: cursright() + DB $54,C0222 ; CALL C0222 +; 1242: is keyctrlw + DB $50,C0332 ; SKIP C0332 +C0336: + DB $2A,$97 ; CB 151 + DB $3E,C0337 ; SKPNE C0337 +; 1243: pgup() + DB $54,C0198 ; CALL C0198 +; 1244: is keyctrlz + DB $50,C0332 ; SKIP C0332 +C0337: + DB $2A,$9A ; CB 154 + DB $3E,C0338 ; SKPNE C0338 +; 1245: pgdown() + DB $54,C0208 ; CALL C0208 +; 1246: is keyctrla + DB $50,C0332 ; SKIP C0332 +C0338: + DB $2A,$81 ; CB 129 + DB $3E,C0339 ; SKPNE C0339 +; 1247: pgleft() + DB $54,C0218 ; CALL C0218 +; 1248: is keyctrls + DB $50,C0332 ; SKIP C0332 +C0339: + DB $2A,$93 ; CB 147 + DB $3E,C0340 ; SKPNE C0340 +; 1249: pgright() + DB $54,C0228 ; CALL C0228 +; 1250: is keyctrlq + DB $50,C0332 ; SKIP C0332 +C0340: + DB $2A,$91 ; CB 145 + DB $3E,C0341 ; SKPNE C0341 +; 1251: curshome() + DB $54,C0186 ; CALL C0186 +; 1252: is keyctrle + DB $50,C0332 ; SKIP C0332 +C0341: + DB $2A,$85 ; CB 133 + DB $3E,C0342 ; SKPNE C0342 +; 1253: cursend() + DB $54,C0188 ; CALL C0188 +; 1254: is keyctrlx + DB $50,C0332 ; SKIP C0332 +C0342: + DB $2A,$98 ; CB 152 + DB $3E,C0343 ; SKPNE C0343 +; 1255: cutline() + DB $54,C0264 ; CALL C0264 +; 1256: is keyctrlv + DB $50,C0332 ; SKIP C0332 +C0343: + DB $2A,$96 ; CB 150 + DB $3E,C0344 ; SKPNE C0344 +; 1257: pasteline() + DB $54,C0270 ; CALL C0270 +; 1258: is keyctrlo + DB $50,C0332 ; SKIP C0332 +C0344: + DB $2A,$8F ; CB 143 + DB $3E,C0345 ; SKPNE C0345 +; 1259: drop openline_11(cursrow) + DB $6A,D0203 ; LAW D0203 + DB $54,C0260 ; CALL C0260 + DB $30 ; DROP +; 1260: redraw() + DB $54,C0184 ; CALL C0184 +; 1261: is keyenter + DB $50,C0332 ; SKIP C0332 +C0345: + DB $2A,$8D ; CB 141 + DB $3E,C0346 ; SKPNE C0346 +; 1262: if flags & insmode + DB $68,D0195 ; LAB D0195 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C0347 ; SKPFLS C0347 +; 1263: splitline() + DB $54,C0280 ; CALL C0280 +; 1264: else + DB $50,C0348 ; SKIP C0348 +C0347: +; 1265: drop openline_11(cursrow + 1) + DB $6A,D0203 ; LAW D0203 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $54,C0260 ; CALL C0260 + DB $30 ; DROP +; 1266: cursdown() + DB $54,C0202 ; CALL C0202 +; 1267: redraw() + DB $54,C0184 ; CALL C0184 +; 1268: fin +C0348: +; 1269: is keyctrlt + DB $50,C0332 ; SKIP C0332 +C0346: + DB $2A,$94 ; CB 148 + DB $3E,C0349 ; SKPNE C0349 +; 1270: joinline() + DB $54,C0274 ; CALL C0274 +; 1271: is keyctrli + DB $50,C0332 ; SKIP C0332 +C0349: + DB $2A,$89 ; CB 137 + DB $3E,C0350 ; SKPNE C0350 +; 1272: if flags & insmode + DB $68,D0195 ; LAB D0195 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C0351 ; SKPFLS C0351 +; 1273: flags = flags & #insmode + DB $68,D0195 ; LAB D0195 + DB $2C,$FD,$FF ; CW -3 + DB $14 ; BAND + DB $78,D0195 ; SAB D0195 +; 1274: curschr = ' ' + DB $2A,$20 ; CB 32 + DB $78,D0202 ; SAB D0202 +; 1275: else + DB $50,C0352 ; SKIP C0352 +C0351: +; 1276: flags = flags ? insmode + DB $68,D0195 ; LAB D0195 + DB $2A,$02 ; CB 2 + DB $16 ; IOR + DB $78,D0195 ; SAB D0195 +; 1277: curschr = '+' + DB $2A,$2B ; CB 43 + DB $78,D0202 ; SAB D0202 +; 1278: fin +C0352: +; 1279: is keyctrlc + DB $50,C0332 ; SKIP C0332 +C0350: + DB $2A,$83 ; CB 131 + DB $3E,C0353 ; SKPNE C0353 +; 1280: if flags & uppercase + DB $68,D0195 ; LAB D0195 + DB $2A,$08 ; CB 8 + DB $14 ; BAND + DB $4C,C0354 ; SKPFLS C0354 +; 1281: txtlower() + DB $54,C0105 ; CALL C0105 +; 1282: else + DB $50,C0355 ; SKIP C0355 +C0354: +; 1283: txtupper() + DB $54,C0101 ; CALL C0101 +; 1284: fin +C0355: +; 1285: redraw() + DB $54,C0184 ; CALL C0184 +; 1286: is keyescape + DB $50,C0332 ; SKIP C0332 +C0353: + DB $2A,$9B ; CB 155 + DB $3E,C0356 ; SKPNE C0356 +; 1287: cursoff() + DB $54,C0169 ; CALL C0169 +; 1288: cmdmode() + DB $54,C0000 ; CALL C0000 +; 1289: redraw() + DB $54,C0184 ; CALL C0184 +; 1290: wend + DB $50,C0332 ; SKIP C0332 +C0356: +C0332: + DB $30 ; DROP +; 1291: until 0 + DB $00 ; ZERO + DB $4C,C0331 ; SKPFLS C0331 +C0330: +; 1292: end + DB $5C ; RET +; 1293: ; +; 1294: ; Command mode +; 1295: ; +; 1296: def prfiles_11(optpath) +C0358: ; prfiles_11() + ; optpath = 2 +; 1297: byte path[64] + ; path = 4 +; 1298: byte refnum + ; refnum = 68 +; 1299: byte firstblk + ; firstblk = 69 +; 1300: byte entrylen, entriesblk + ; entrylen = 70 + ; entriesblk = 71 +; 1301: byte i, type, len + ; i = 72 + ; type = 73 + ; len = 74 +; 1302: word entry, filecnt + ; entry = 75 + ; filecnt = 77 +; 1303: +; 1304: if ^optpath + JSR _INTERP + DB $58,$4F,$01 ; ENTER 79,1 + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $4C,C0360 ; SKPFLS C0360 +; 1305: strcpy_20(optpath, @path) + DB $66,$02 ; LLW 2 + DB $28,$04 ; LLA 4 + DB $54,C0043 ; CALL C0043 +; 1306: else + DB $50,C0361 ; SKIP C0361 +C0360: +; 1307: drop getpfx_11(@path) + DB $28,$04 ; LLA 4 + DB $54,C0021 ; CALL C0021 + DB $30 ; DROP +; 1308: prstr(@path) + DB $28,$04 ; LLA 4 + DB $54,C0015 ; CALL C0015 +; 1309: crout() + DB $54,C0039 ; CALL C0039 +; 1310: fin +C0361: +; 1311: refnum = open_21(@path, iobuffer); + DB $28,$04 ; LLA 4 + DB $2C,$00,$08 ; CW 2048 + DB $54,C0025 ; CALL C0025 + DB $74,$44 ; SLB 68 +; 1312: if perr + DB $68,D0091 ; LAB D0091 + DB $4C,C0362 ; SKPFLS C0362 +; 1313: return perr + DB $68,D0091 ; LAB D0091 + DB $5A ; LEAVE +; 1314: fin +C0362: +C0363: +; 1315: firstblk = 1 + DB $2A,$01 ; CB 1 + DB $74,$45 ; SLB 69 +; 1316: repeat +C0365: +; 1317: if read_31(refnum, databuff, 512) == 512 + DB $64,$44 ; LLB 68 + DB $2C,$00,$0C ; CW 3072 + DB $2C,$00,$02 ; CW 512 + DB $54,C0029 ; CALL C0029 + DB $2C,$00,$02 ; CW 512 + DB $40 ; ISEQ + DB $4C,C0366 ; SKPFLS C0366 +; 1318: entry = databuff + 4 + DB $2C,$00,$0C ; CW 3072 + DB $2A,$04 ; CB 4 + DB $02 ; ADD + DB $76,$4B ; SLW 75 +; 1319: if firstblk + DB $64,$45 ; LLB 69 + DB $4C,C0368 ; SKPFLS C0368 +; 1320: entrylen = databuff.$23 + DB $2C,$23,$0C ; CW 3107 + DB $60 ; LB + DB $74,$46 ; SLB 70 +; 1321: entriesblk = databuff.$24 + DB $2C,$24,$0C ; CW 3108 + DB $60 ; LB + DB $74,$47 ; SLB 71 +; 1322: filecnt = databuff:$25 + DB $2C,$25,$0C ; CW 3109 + DB $62 ; LW + DB $76,$4D ; SLW 77 +; 1323: entry = entry + entrylen + DB $66,$4B ; LLW 75 + DB $64,$46 ; LLB 70 + DB $02 ; ADD + DB $76,$4B ; SLW 75 +; 1324: fin +C0368: +C0369: +; 1325: for i = firstblk to entriesblk + DB $64,$45 ; LLB 69 +C0371: + DB $6C,$48 ; DLB 72 + DB $64,$47 ; LLB 71 + DB $3A,C0370 ; SKPGT C0370 + DB $0C ; INCR +; 1326: type = ^entry + DB $66,$4B ; LLW 75 + DB $60 ; LB + DB $74,$49 ; SLB 73 +; 1327: if type <> 0 + DB $64,$49 ; LLB 73 + DB $00 ; ZERO + DB $42 ; ISNE + DB $4C,C0372 ; SKPFLS C0372 +; 1328: len = type & $0F + DB $64,$49 ; LLB 73 + DB $2A,$0F ; CB 15 + DB $14 ; BAND + DB $74,$4A ; SLB 74 +; 1329: ^entry = len + DB $66,$4B ; LLW 75 + DB $64,$4A ; LLB 74 + DB $70 ; SB +; 1330: prstr(entry) + DB $66,$4B ; LLW 75 + DB $54,C0015 ; CALL C0015 +; 1331: if type & $F0 == $D0 ; Is it a directory? + DB $64,$49 ; LLB 73 + DB $2A,$F0 ; CB 240 + DB $14 ; BAND + DB $2A,$D0 ; CB 208 + DB $40 ; ISEQ + DB $4C,C0374 ; SKPFLS C0374 +; 1332: cout('/') + DB $2A,$2F ; CB 47 + DB $54,C0011 ; CALL C0011 +; 1333: len = len + 1 + DB $64,$4A ; LLB 74 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $74,$4A ; SLB 74 +; 1334: fin +C0374: +C0375: +; 1335: for len = 20 - len downto 1 + DB $2A,$14 ; CB 20 + DB $64,$4A ; LLB 74 + DB $04 ; SUB +C0377: + DB $6C,$4A ; DLB 74 + DB $2A,$01 ; CB 1 + DB $38,C0376 ; SKPLT C0376 + DB $0E ; DECR +; 1336: cout(' ') + DB $2A,$20 ; CB 32 + DB $54,C0011 ; CALL C0011 +; 1337: next + DB $50,C0377 ; SKIP C0377 +C0376: + DB $30 ; DROP +; 1338: filecnt = filecnt - 1 + DB $66,$4D ; LLW 77 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $76,$4D ; SLW 77 +; 1339: fin +C0372: +C0373: +; 1340: entry = entry + entrylen + DB $66,$4B ; LLW 75 + DB $64,$46 ; LLB 70 + DB $02 ; ADD + DB $76,$4B ; SLW 75 +; 1341: next + DB $50,C0371 ; SKIP C0371 +C0370: + DB $30 ; DROP +; 1342: firstblk = 0 + DB $00 ; ZERO + DB $74,$45 ; SLB 69 +; 1343: else + DB $50,C0367 ; SKIP C0367 +C0366: +; 1344: filecnt = 0 + DB $00 ; ZERO + DB $76,$4D ; SLW 77 +; 1345: fin +C0367: +; 1346: until filecnt == 0 + DB $66,$4D ; LLW 77 + DB $00 ; ZERO + DB $40 ; ISEQ + DB $4C,C0365 ; SKPFLS C0365 +C0364: +; 1347: drop close_11(refnum) + DB $64,$44 ; LLB 68 + DB $54,C0027 ; CALL C0027 + DB $30 ; DROP +; 1348: crout() + DB $54,C0039 ; CALL C0039 +; 1349: return 0 + DB $00 ; ZERO + DB $5A ; LEAVE +; 1350: end +; 1351: def striplead_20(strptr, chr) +C0378: ; striplead_20() + ; strptr = 2 + ; chr = 4 +; 1352: while ^strptr and ^(strptr + 1) == chr + JSR _INTERP + DB $58,$06,$02 ; ENTER 6,2 +C0380: + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $66,$02 ; LLW 2 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $60 ; LB + DB $66,$04 ; LLW 4 + DB $40 ; ISEQ + DB $24 ; LAND + DB $4C,C0381 ; SKPFLS C0381 +; 1353: memcpy(strptr + 2, strptr + 1, ^strptr) + DB $66,$02 ; LLW 2 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $66,$02 ; LLW 2 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $54,C0009 ; CALL C0009 +; 1354: ^strptr = ^strptr - 1 + DB $66,$02 ; LLW 2 + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $70 ; SB +; 1355: loop + DB $50,C0380 ; SKIP C0380 +C0381: +; 1356: end + DB $5A ; LEAVE +; 1357: def parsecmd_11(strptr) +C0382: ; parsecmd_11() + ; strptr = 2 +; 1358: byte cmd + ; cmd = 4 +; 1359: +; 1360: cmd = 0 + JSR _INTERP + DB $58,$05,$01 ; ENTER 5,1 + DB $00 ; ZERO + DB $74,$04 ; SLB 4 +; 1361: striplead_20(strptr, ' ') + DB $66,$02 ; LLW 2 + DB $2A,$20 ; CB 32 + DB $54,C0378 ; CALL C0378 +; 1362: if ^strptr + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $4C,C0384 ; SKPFLS C0384 +; 1363: cmd = ^(strptr + 1) + DB $66,$02 ; LLW 2 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $60 ; LB + DB $74,$04 ; SLB 4 +; 1364: memcpy(strptr + 2, strptr + 1, ^strptr) + DB $66,$02 ; LLW 2 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $66,$02 ; LLW 2 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $54,C0009 ; CALL C0009 +; 1365: ^strptr = ^strptr - 1 + DB $66,$02 ; LLW 2 + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $70 ; SB +; 1366: fin +C0384: +C0385: +; 1367: if ^strptr + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $4C,C0386 ; SKPFLS C0386 +; 1368: striplead_20(strptr, ' ') + DB $66,$02 ; LLW 2 + DB $2A,$20 ; CB 32 + DB $54,C0378 ; CALL C0378 +; 1369: fin +C0386: +C0387: +; 1370: return cmd + DB $64,$04 ; LLB 4 + DB $5A ; LEAVE +; 1371: end +; 1372: def chkchng_01 +C0388: ; chkchng_01() +; 1373: if flags & changed + JSR _INTERP + DB $68,D0195 ; LAB D0195 + DB $2A,$01 ; CB 1 + DB $14 ; BAND + DB $4C,C0390 ; SKPFLS C0390 +; 1374: prstr(@losechng) + DB $26,D0107 ; LA D0107 + DB $54,C0015 ; CALL C0015 +; 1375: if toupper_11(keyin_01()) == 'N' + DB $26,D0213 ; LA D0213 + DB $62 ; LW + DB $34 ; PUSH + DB $36 ; PULL + DB $56 ; ICAL + DB $54,C0123 ; CALL C0123 + DB $2A,$4E ; CB 78 + DB $40 ; ISEQ + DB $4C,C0392 ; SKPFLS C0392 +; 1376: crout() + DB $54,C0039 ; CALL C0039 +; 1377: return 0 + DB $00 ; ZERO + DB $5C ; RET +; 1378: fin +C0392: +C0393: +; 1379: crout() + DB $54,C0039 ; CALL C0039 +; 1380: fin +C0390: +C0391: +; 1381: return 1 + DB $2A,$01 ; CB 1 + DB $5C ; RET +; 1382: end +; 1383: def quit +C0394: ; quit() +; 1384: if chkchng_01() + JSR _INTERP + DB $54,C0388 ; CALL C0388 + DB $4C,C0396 ; SKPFLS C0396 +; 1385: exit + DB $54,C0019 ; CALL C0019 +; 1386: fin +C0396: +C0397: +; 1387: end + DB $5C ; RET +; 1388: def cmdmode +C0000: ; cmdmode() +; 1389: byte slot + ; slot = 2 +; 1390: word cmdptr + ; cmdptr = 3 +; 1391: +; 1392: clrscrn(); + JSR _INTERP + DB $58,$05,$00 ; ENTER 5,0 + DB $54,C0153 ; CALL C0153 +; 1393: prstr(@version) + DB $26,D0049 ; LA D0049 + DB $54,C0015 ; CALL C0015 +; 1394: crout() + DB $54,C0039 ; CALL C0039 +; 1395: while 1 +C0399: + DB $2A,$01 ; CB 1 + DB $4C,C0400 ; SKPFLS C0400 +; 1396: prstr(@txtfile) + DB $26,D0144 ; LA D0144 + DB $54,C0015 ; CALL C0015 +; 1397: cmdptr = rdstr($BA) + DB $2A,$BA ; CB 186 + DB $54,C0017 ; CALL C0017 + DB $76,$03 ; SLW 3 +; 1398: when toupper_11(parsecmd_11(cmdptr)) + DB $66,$03 ; LLW 3 + DB $54,C0382 ; CALL C0382 + DB $54,C0123 ; CALL C0123 +; 1399: is 'A' + DB $2A,$41 ; CB 65 + DB $3E,C0402 ; SKPNE C0402 +; 1400: readtxt_10(cmdptr) + DB $66,$03 ; LLW 3 + DB $54,C0131 ; CALL C0131 +; 1401: flags = flags ? changed + DB $68,D0195 ; LAB D0195 + DB $2A,$01 ; CB 1 + DB $16 ; IOR + DB $78,D0195 ; SAB D0195 +; 1402: is 'R' + DB $50,C0401 ; SKIP C0401 +C0402: + DB $2A,$52 ; CB 82 + DB $3E,C0403 ; SKPNE C0403 +; 1403: if chkchng_01() + DB $54,C0388 ; CALL C0388 + DB $4C,C0404 ; SKPFLS C0404 +; 1404: inittxtbuf() + DB $54,C0081 ; CALL C0081 +; 1405: strcpy_20(cmdptr, @txtfile) + DB $66,$03 ; LLW 3 + DB $26,D0144 ; LA D0144 + DB $54,C0043 ; CALL C0043 +; 1406: readtxt_10(@txtfile) + DB $26,D0144 ; LA D0144 + DB $54,C0131 ; CALL C0131 +; 1407: flags = flags & #changed + DB $68,D0195 ; LAB D0195 + DB $2C,$FE,$FF ; CW -2 + DB $14 ; BAND + DB $78,D0195 ; SAB D0195 +; 1408: fin +C0404: +C0405: +; 1409: is 'W' + DB $50,C0401 ; SKIP C0401 +C0403: + DB $2A,$57 ; CB 87 + DB $3E,C0406 ; SKPNE C0406 +; 1410: if ^cmdptr + DB $66,$03 ; LLW 3 + DB $60 ; LB + DB $4C,C0407 ; SKPFLS C0407 +; 1411: strcpy_20(cmdptr, @txtfile) + DB $66,$03 ; LLW 3 + DB $26,D0144 ; LA D0144 + DB $54,C0043 ; CALL C0043 +; 1412: fin +C0407: +C0408: +; 1413: writetxt_10(@txtfile) + DB $26,D0144 ; LA D0144 + DB $54,C0145 ; CALL C0145 +; 1414: if flags & changed + DB $68,D0195 ; LAB D0195 + DB $2A,$01 ; CB 1 + DB $14 ; BAND + DB $4C,C0409 ; SKPFLS C0409 +; 1415: fin +C0409: +C0410: +; 1416: flags = flags & #changed + DB $68,D0195 ; LAB D0195 + DB $2C,$FE,$FF ; CW -2 + DB $14 ; BAND + DB $78,D0195 ; SAB D0195 +; 1417: is 'Q' + DB $50,C0401 ; SKIP C0401 +C0406: + DB $2A,$51 ; CB 81 + DB $3E,C0411 ; SKPNE C0411 +; 1418: quit() + DB $54,C0394 ; CALL C0394 +; 1419: is 'C' + DB $50,C0401 ; SKIP C0401 +C0411: + DB $2A,$43 ; CB 67 + DB $3E,C0412 ; SKPNE C0412 +; 1420: drop prfiles_11(cmdptr) + DB $66,$03 ; LLW 3 + DB $54,C0358 ; CALL C0358 + DB $30 ; DROP +; 1421: is 'P' + DB $50,C0401 ; SKIP C0401 +C0412: + DB $2A,$50 ; CB 80 + DB $3E,C0413 ; SKPNE C0413 +; 1422: drop setpfx_11(cmdptr) + DB $66,$03 ; LLW 3 + DB $54,C0023 ; CALL C0023 + DB $30 ; DROP +; 1423: is 'H' + DB $50,C0401 ; SKIP C0401 +C0413: + DB $2A,$48 ; CB 72 + DB $3E,C0414 ; SKPNE C0414 +; 1424: if ^cmdptr + DB $66,$03 ; LLW 3 + DB $60 ; LB + DB $4C,C0415 ; SKPFLS C0415 +; 1425: slot = cmdptr.1 - '0' + DB $28,$04 ; LLA 4 + DB $60 ; LB + DB $2A,$30 ; CB 48 + DB $04 ; SUB + DB $74,$02 ; SLB 2 +; 1426: else + DB $50,C0416 ; SKIP C0416 +C0415: +; 1427: slot = 1 + DB $2A,$01 ; CB 1 + DB $74,$02 ; SLB 2 +; 1428: fin +C0416: +; 1429: printtxt_10(slot) + DB $64,$02 ; LLB 2 + DB $54,C0256 ; CALL C0256 +; 1430: is 'E' + DB $50,C0401 ; SKIP C0401 +C0414: + DB $2A,$45 ; CB 69 + DB $3E,C0417 ; SKPNE C0417 +; 1431: return + DB $30 ; DROP + DB $5A ; LEAVE +; 1432: is 0 + DB $50,C0401 ; SKIP C0401 +C0417: + DB $00 ; ZERO + DB $3E,C0418 ; SKPNE C0418 +; 1433: return + DB $30 ; DROP + DB $5A ; LEAVE +; 1434: is 'N' + DB $50,C0401 ; SKIP C0401 +C0418: + DB $2A,$4E ; CB 78 + DB $3E,C0419 ; SKPNE C0419 +; 1435: if chkchng_01() + DB $54,C0388 ; CALL C0388 + DB $4C,C0420 ; SKPFLS C0420 +; 1436: inittxtbuf() + DB $54,C0081 ; CALL C0081 +; 1437: numlines = 1 + DB $2A,$01 ; CB 1 + DB $7A,D0209 ; SAW D0209 +; 1438: strcpy_20(@untitled, @txtfile) + DB $26,D0135 ; LA D0135 + DB $26,D0144 ; LA D0144 + DB $54,C0043 ; CALL C0043 +; 1439: fin +C0420: +C0421: +; 1440: otherwise + DB $50,C0401 ; SKIP C0401 +C0419: +; 1441: bell() + DB $54,C0041 ; CALL C0041 +; 1442: cout('?') + DB $2A,$3F ; CB 63 + DB $54,C0011 ; CALL C0011 +; 1443: crout() + DB $54,C0039 ; CALL C0039 +; 1444: wend +C0401: + DB $30 ; DROP +; 1445: if perr + DB $68,D0091 ; LAB D0091 + DB $4C,C0423 ; SKPFLS C0423 +; 1446: prstr(@errorstr) + DB $26,D0079 ; LA D0079 + DB $54,C0015 ; CALL C0015 +; 1447: drop romcall(perr, 0, 0, 0, $FDDA) + DB $68,D0091 ; LAB D0091 + DB $00 ; ZERO + DB $00 ; ZERO + DB $00 ; ZERO + DB $2C,$DA,$FD ; CW 64986 + DB $54,C0003 ; CALL C0003 + DB $30 ; DROP +; 1448: else + DB $50,C0424 ; SKIP C0424 +C0423: +; 1449: prstr(@okstr) + DB $26,D0088 ; LA D0088 + DB $54,C0015 ; CALL C0015 +; 1450: fin +C0424: +; 1451: crout() + DB $54,C0039 ; CALL C0039 +; 1452: loop + DB $50,C0399 ; SKIP C0399 +C0400: +; 1453: end + DB $5A ; LEAVE +; 1454: ; +; 1455: ; Init editor +; 1456: ; +; 1457: if !(^machid & $80) +START: ; JSR INTERP + DB $2C,$98,$BF ; CW 49048 + DB $60 ; LB + DB $2A,$80 ; CB 128 + DB $14 ; BAND + DB $20 ; NOT + DB $4C,C0425 ; SKPFLS C0425 +; 1458: flags = uppercase ? shiftlock + DB $2A,$08 ; CB 8 + DB $2A,$80 ; CB 128 + DB $16 ; IOR + DB $78,D0195 ; SAB D0195 +; 1459: keyin_01 = @keyin2_01 + DB $26,C0236 ; LA C0236 + DB $7A,D0213 ; SAW D0213 +; 1460: else + DB $50,C0426 ; SKIP C0426 +C0425: +; 1461: keyin_01 = @keyin2e_01 + DB $26,C0232 ; LA C0232 + DB $7A,D0213 ; SAW D0213 +; 1462: fin +C0426: +; 1463: inittxtbuf() + DB $54,C0081 ; CALL C0081 +; 1464: if ^argbuff + DB $2C,$06,$20 ; CW 8198 + DB $60 ; LB + DB $4C,C0427 ; SKPFLS C0427 +; 1465: strcpy_20(argbuff, @txtfile) + DB $2C,$06,$20 ; CW 8198 + DB $26,D0144 ; LA D0144 + DB $54,C0043 ; CALL C0043 +; 1466: prstr(@txtfile) + DB $26,D0144 ; LA D0144 + DB $54,C0015 ; CALL C0015 +; 1467: readtxt_10(@txtfile) + DB $26,D0144 ; LA D0144 + DB $54,C0131 ; CALL C0131 +; 1468: else + DB $50,C0428 ; SKIP C0428 +C0427: +; 1469: numlines = 1 + DB $2A,$01 ; CB 1 + DB $7A,D0209 ; SAW D0209 +; 1470: fin +C0428: +; 1471: curschr = '+' + DB $2A,$2B ; CB 43 + DB $78,D0202 ; SAB D0202 +; 1472: flags = flags ? insmode + DB $68,D0195 ; LAB D0195 + DB $2A,$02 ; CB 2 + DB $16 ; IOR + DB $78,D0195 ; SAB D0195 +; 1473: drawscrn_20(scrntop, scrnleft) + DB $6A,D0205 ; LAW D0205 + DB $68,D0199 ; LAB D0199 + DB $54,C0161 ; CALL C0161 +; 1474: curson() + DB $54,C0173 ; CALL C0173 +; 1475: editmode() + DB $54,C0328 ; CALL C0328 +; 1476: done + DB $5C ; RET diff --git a/plasma2/pled.sys b/plasma2/pled.sys new file mode 100755 index 0000000..68fa4a9 Binary files /dev/null and b/plasma2/pled.sys differ diff --git a/plasma2/plex.pla b/plasma2/plex.pla new file mode 100755 index 0000000..0636337 --- /dev/null +++ b/plasma2/plex.pla @@ -0,0 +1,2850 @@ +; +; Global constants +; +const FALSE = 0 +const TRUE = !FALSE +; +; Data and text buffer constants +; +const iobuffer = $0800 +const codebuff = $6000 +const codebuffsz = $5000 +const argbuff = $2006 +const inbuff = $0200 +const instr = $01FF +byte inref +;byte emptystk +; +; Symbol table variables +; +const idglobal_tblsz = $0800 +const idlocal_tblsz = $0200 +const idglobal_tbl = $1000 +const idlocal_tbl = $1800 +const ctag_max = 768 +const ctag_value = $1A00 +const ctag_flags = $0D00 +const idval = 0 +const idtype = 2 +const idname = 3 +const idrecsz = 4 +word globals = 0 +word datasize = 0 +word lastglobal +byte locals = 0 +word framesize = 0 +word lastlocal +const resolved = 1 +const is_ctag = $8000 +const mask_ctag = $7FFF +word codetag = -1 +word codeptr +word entrypoint = 0 +byte lastop = $FF +byte perr +; +; String variables +; +byte version[] = "PLASMA ][ EXECUTIVE VERSION 0.8 " +byte donemsg[] = "EXECUTION COMPLETE. PRESS A KEY..." +byte badfile[] = "FILE NOT FOUND" +byte brkmsg[] = "CTRL-C BREAK" +byte stkovflwmsg[] = "STACK OVERFLOW/UNDERFLOW ERROR" +; +; Tokens +; +const ID_TKN = $D6 ; V +const CHR_TKN = $C3 ; C +const INT_TKN = $C9 ; I +const STR_TKN = $D3 ; S +const EOL_TKN = $02 +const EOF_TKN = $01 +const ERR_TKN = $00 +; +; Binary operand operators +; +const SET_TKN = $BD ; = +const SETLIST_TKN = $B9 ; =, +const ADD_TKN = $AB ; + +const SUB_TKN = $AD ; - +const MUL_TKN = $AA ; * +const DIV_TKN = $AF ; / +const MOD_TKN = $A5 ; % +const OR_TKN = $BF ; ? +const EOR_TKN = $DE ; ^ +const AND_TKN = $A6 ; & +const SHR_TKN = $D2 ; R +const SHL_TKN = $CC ; L +const GT_TKN = $BE ; > +const GE_TKN = $C8 ; H +const LT_TKN = $BC ; < +const LE_TKN = $C2 ; B +const NE_TKN = $D5 ; U +const EQ_TKN = $C5 ; E +const LOGIC_AND_TKN = $CE ; N +const LOGIC_OR_TKN = $CF ; O +; +; Unary operand operators +; +const AT_TKN = $C0 ; @ +const DOT_TKN = $AE ; . +const COLON_TKN = $BA ; : +const NEG_TKN = $AD ; - +const COMP_TKN = $A3 ; # +const LOGIC_NOT_TKN = $A1 ; ! +const BPTR_TKN = $DE ; ^ +const WPTR_TKN = $AA ; * +const INC_TKN = $C1 ; A +const DEC_TKN = $C4 ; D +; +; Enclosure tokens +; +const OPEN_PAREN_TKN = $A8 ; ( +const CLOSE_PAREN_TKN = $A9 ; ) +const OPEN_BRACKET_TKN = $DB ; [ +const CLOSE_BRACKET_TKN = $DD ; ] +; +; Misc. tokens +; +const COMMA_TKN = $AC ; , +const COMMENT_TKN = $BB ; ; +; +; Keyword tokens +; +const CONST_TKN = $80 +const BYTE_TKN = $81 +const WORD_TKN = $82 +const IF_TKN = $83 +const ELSEIF_TKN = $84 +const ELSE_TKN = $85 +const FIN_TKN = $86 +const END_TKN = $87 +const WHILE_TKN = $88 +const LOOP_TKN = $89 +const CASE_TKN = $8A +const OF_TKN = $8B +const DEFAULT_TKN = $8C +const ENDCASE_TKN = $8D +const FOR_TKN = $8E +const TO_TKN = $8F +const DOWNTO_TKN = $90 +const STEP_TKN = $91 +const NEXT_TKN = $92 +const REPEAT_TKN = $93 +const UNTIL_TKN = $94 +const IFUNC_TKN = $95 +const NFUNC_TKN = $96 +const DROP_TKN = $97 +const DONE_TKN = $98 +const RETURN_TKN = $99 +const BREAK_TKN = $9A +const START_TKN = $9B +const EXIT_TKN = $9C +const EVAL_TKN = $9D +const FUNC_TKN = $9E +; +; Types +; +const CONST_TYPE = $01 +const BYTE_TYPE = $02 +const WORD_TYPE = $04 +const VAR_TYPE = $06 ; (WORD_TYPE | BYTE_TYPE) +const FUNC_TYPE = $08 +const FUNC_CONST_TYPE = $09 +const ADDR_TYPE = $0E ; (VAR_TYPE | FUNC_TYPE) +const LOCAL_TYPE = $10 +const BPTR_TYPE = $20 +const WPTR_TYPE = $40 +const PTR_TYPE = $60 ; (BPTR_TYPE | WPTR_TYPE) +const XBYTE_TYPE = $22 ; (BPTR_TYPE | BYTE_TYPE) +const XWORD_TYPE = $44 ; (WPTR_TYPE | WORD_TYPE) +const STR_TYPE = $80 +; +; Keywords +; +byte keywrds[] +byte = "IF", IF_TKN +byte = "TO", TO_TKN +byte = "IS", OF_TKN +byte = "OR", LOGIC_OR_TKN +byte = "FOR", FOR_TKN +byte = "FIN", FIN_TKN +byte = "DEF", IFUNC_TKN +byte = "END", END_TKN +byte = "AND", LOGIC_AND_TKN +byte = "NOT", LOGIC_NOT_TKN +byte = "BYTE", BYTE_TKN +byte = "WORD", WORD_TKN +byte = "DROP", DROP_TKN +byte = "ELSE", ELSE_TKN +byte = "NEXT", NEXT_TKN +byte = "WHEN", CASE_TKN +byte = "LOOP", LOOP_TKN +byte = "FUNC", FUNC_TKN +byte = "STEP", STEP_TKN +byte = "EXIT", EXIT_TKN +byte = "DONE", DONE_TKN +byte = "WEND", ENDCASE_TKN +byte = "CONST", CONST_TKN +byte = "ELSIF", ELSEIF_TKN +byte = "WHILE", WHILE_TKN +byte = "UNTIL", UNTIL_TKN +byte = "BREAK", BREAK_TKN +byte = "OTHER", DEFAULT_TKN +byte = "DOWNTO", DOWNTO_TKN +byte = "REPEAT", REPEAT_TKN +byte = "DEFOPT", NFUNC_TKN +byte = "RETURN", RETURN_TKN +byte = $FF +; +; Mathematical ops +; +const bops_tblsz = 18 ; minus 1 +byte bops_tbl[] ; Highest precedence +byte = MUL_TKN, DIV_TKN, MOD_TKN +byte = ADD_TKN, SUB_TKN +byte = SHR_TKN, SHL_TKN +byte = AND_TKN +byte = EOR_TKN +byte = OR_TKN +byte = GT_TKN, GE_TKN, LT_TKN, LE_TKN +byte = EQ_TKN, NE_TKN +byte = LOGIC_AND_TKN +byte = LOGIC_OR_TKN +byte = COMMA_TKN + ; Lowest precedence +byte bops_prec[] ; Highest precedence +byte = 1, 1, 1 +byte = 2, 2 +byte = 3, 3 +byte = 4 +byte = 5 +byte = 6 +byte = 7, 7, 7, 7 +byte = 8, 8 +byte = 9 +byte = 10 +byte = 11 + ; Lowest precedence +byte opstack[16] +byte precstack[16] +word opsp = -1 +; +; Scanner variables +; +byte token, tknlen +word scanptr, tknptr +word constval +word lineno = 0 +; +; Compiler output messages +; +byte entrypt_str[] = "START: " +byte dup_id[] = "DUPLICATE IDENTIFIER" +byte undecl_id[] = "UNDECLARED IDENTIFIER" +byte bad_cnst[] = "BAD CONSTANT" +byte bad_offset[] = "BAD STRUCT OFFSET" +byte bad_decl[] = "BAD DECLARATION" +byte bad_op[] = "BAD OPERATION" +byte bad_stmnt[] = "BAD STATMENT" +byte bad_expr[] = "BAD EXPRESSION" +byte bad_syntax[] = "BAD SYNTAX" +byte estk_overflw[] = "EVAL STACK OVERFLOW" +byte estk_underflw[] = "EVAL STACK UNDERFLOW" +byte local_overflw[] = "LOCAL FRAME OVERFLOW" +byte global_sym_overflw[] = "GLOBAL SYMBOL TABLE OVERFLOW" +byte local_sym_overflw[] = "LOCAL SYMBOL TABLE OVERFLOW" +byte ctag_full[] = "CODE LABEL OVERFLOW" +byte no_close_paren[] = "MISSING CLOSING PAREN" +byte no_close_bracket[] = "MISSING CLOSING BRACKET" +byte missing_op[] = "MISSING OPERAND" +byte no_fin[] = "MISSING FIN" +byte no_loop[] = "MISSING LOOP" +byte no_until[] = "MISSING UNTIL" +byte no_done[] = "MISSING DONE" +byte no_local_init[] = "NO INITIALIZED LOCALS" +; +; Runtime functions +; +byte runtime0[] = "romcall" +byte RUNTIME0[] = "ROMCALL" +byte runtime1[] = "syscall" +byte RUNTIME1[] = "SYSCALL" +byte runtime2[] = "memset" +byte RUNTIME2[] = "MEMSET" +byte runtime3[] = "memcpy" +byte RUNTIME3[] = "MEMCPY" +byte runtime4[] = "cout" +byte RUNTIME4[] = "COUT" +byte runtime5[] = "cin" +byte RUNTIME5[] = "CIN" +byte runtime6[] = "prstr" +byte RUNTIME6[] = "PRSTR" +byte runtime7[] = "rdstr" +byte RUNTIME7[] = "RDSTR" +; +; Parser variables +; +byte infunc = 0 +byte stack_loop = 0 +byte prevstmnt = 0 +word retfunc_tag = 0 +word break_tag = 0 +func parse_expr_01, parse_module_01 +; +; Defines for ASM routines +; +asm equates + TMP EQU $F0 + TMPL EQU TMP + TMPH EQU TMP+1 + SRC EQU TMP + SRCL EQU SRC + SRCH EQU SRC+1 + DST EQU SRC+2 + DSTL EQU DST + DSTH EQU DST+1 + ESP EQU DST+2 + SAVEESP EQU ESP+1 + SAVESP EQU SAVEESP+1 + SAVEFP EQU SAVESP+1 + SAVETMR EQU SAVEFP+2 + SAVEINT EQU SAVETMR+2 + TMRVEC EQU $03E8 + INTVEC EQU $03EA +JMPTMP: JMP (TMP) +STKOVFLW: + LDY #$02 + JMP EXECRET +BRKCHK: + LDA $C000 + CMP #$83 ; CTRL-C + BNE :+ + BIT $C010 + LDY #$01 + JMP EXECRET +: +end +; +; ENTER MODULE UNDER TEST +; +asm execentry + LDA ESTKL,X + STA TMPL + LDA ESTKH,X + STA TMPH + STX SAVEESP + TSX + STX SAVESP + LDA FRMPL + STA SAVEFP + LDA FRMPH + STA SAVEFP+1 + LDA TMRVEC + STA SAVETMR + LDA TMRVEC+1 + STA SAVETMR+1 + LDA INTVEC + STA SAVEINT + LDA INTVEC+1 + STA SAVEINT+1 + LDA #BRKCHK + STA TMRVEC+1 + LDA #STKOVFLW + STA INTVEC+1 + LDX #ESTKSZ/2 + JSR JMPTMP + LDY #$00 +EXECRET: + STY TMP + BIT ROMIN + BIT $C054 + BIT $C051 + BIT $C058 + JSR $FB39 ; SET TEXT MODE + BIT LCBNK2 + LDA SAVEFP + STA FRMPL + LDA SAVEFP+1 + STA FRMPH + LDA SAVETMR + STA TMRVEC + LDA SAVETMR+1 + STA TMRVEC+1 + LDA SAVEINT + STA INTVEC + LDA SAVEINT+1 + STA INTVEC+1 + LDX SAVESP + TXS + LDX SAVEESP + LDY TMP + STY ESTKL,X + LDY #$00 + STY ESTKH,X +end +; +; CALL 6502 ROUTINE +; ROMCALL(AREG, XREG, YREG, STATUS, ADDR) +; +asm romcall + PHP + LDA ESTKL,X + STA TMPL + LDA ESTKH,X + STA TMPH + INX + LDA ESTKL,X + PHA + INX + LDA ESTKL,X + TAY + INX + LDA ESTKL+1,X + PHA + LDA ESTKL,X + INX + STX ESP + TAX + PLA + BIT ROMIN + PLP + JSR JMPTMP + PHP + BIT LCBNK2 + STA REGVALS+0 + STX REGVALS+1 + STY REGVALS+2 + PLA + STA REGVALS+3 + LDX ESP + LDA #REGVALS + STA ESTKL,X + STY ESTKH,X + PLP + RTS +REGVALS: DS 4 +end +; +; BREAK INTO MONITOR +; +asm monitor + STX ESP + LDA #$4C + STA $03F8 + LDA #REENTER + STA $03FA + TSX + TXA + PHA + BIT ROMIN + JMP $FF69 +REENTER: PLA + TAX + TXS + LDX ESP + BIT LCBNK2 +end +; +; RETURN EVAL STACK POINTER +; +;asm estk +; TXA +; DEX +; STA ESTKL,X +; LDA #$00 +; STA ESTKH,X +;end +; +; ASSERT EVAL STACK POINTER VALUE +; +;asm assert_estk +; INX +; TXA +; CMP ESTKL-1,X +; BEQ :+ +; BRK +;: +;end +; +; CALL PRODOS +; SYSCALL(CMD, PARAMS) +; +asm syscall + LDA ESTKL,X + LDY ESTKH,X + STA PARAMS + STY PARAMS+1 + INX + LDA ESTKL,X + STA CMD + STX ESP + BIT ROMIN + JSR $BF00 +CMD: DB 00 +PARAMS: DW 0000 + BIT LCBNK2 + LDX ESP + STA ESTKL,X + LDY #$00 + STY ESTKH,X +end +; +; SET MEMORY TO VALUE +; MEMSET(VALUE, ADDR, SIZE) +; +asm memset + LDY #$00 + LDA ESTKL+1,X + STA DSTL + LDA ESTKH+1,X + STA DSTH + INC ESTKL,X + INC ESTKH,X +SETMEM: DEC ESTKL,X + BNE :+ + DEC ESTKH,X + BEQ MEMEXIT +: LDA ESTKL+2,X + STA (DST),Y + INY + BNE :+ + INC DSTH +: DEC ESTKL,X + BNE :+ + DEC ESTKH,X + BEQ MEMEXIT +: LDA ESTKH+2,X + STA (DST),Y + INY + BNE SETMEM + INC DSTH + BNE SETMEM +MEMEXIT: INX + INX + INX +end +; +; COPY MEMORY +; MEMCPY(SRCADDR, DSTADDR, SIZE) +; +asm memcpy + LDY #$00 + LDA ESTKL,X + BNE :+ + LDA ESTKH,X + BEQ MEMEXIT +: LDA ESTKL+1,X + STA DSTL + LDA ESTKH+1,X + STA DSTH + LDA ESTKL+2,X + STA SRCL + LDA ESTKH+2,X + STA SRCH + CMP DSTH + BCC REVCPY + BNE FORCPY + LDA SRCL + CMP DSTL + BCS FORCPY +REVCPY: ; REVERSE DIRECTION COPY +; CLC + LDA ESTKL,X + ADC DSTL + STA DSTL + LDA ESTKH,X + ADC DSTH + STA DSTH + CLC + LDA ESTKL,X + ADC SRCL + STA SRCL + LDA ESTKH,X + ADC SRCH + STA SRCH + INC ESTKH,X +REVCPYLP: + LDA DSTL + BNE :+ + DEC DSTH +: DEC DSTL + LDA SRCL + BNE :+ + DEC SRCH +: DEC SRCL + LDA (SRC),Y + STA (DST),Y + DEC ESTKL,X + BNE REVCPYLP + DEC ESTKH,X + BNE REVCPYLP + BEQ MEMEXIT +FORCPY: INC ESTKH,X +FORCPYLP: + LDA (SRC),Y + STA (DST),Y + INC DSTL + BNE :+ + INC DSTH +: INC SRCL + BNE :+ + INC SRCH +: DEC ESTKL,X + BNE FORCPYLP + DEC ESTKH,X + BNE FORCPYLP + BEQ MEMEXIT +end +; +; CHAR OUT +; COUT(CHAR) +; +asm cout + LDA ESTKL,X + INX + ORA #$80 + BIT ROMIN + JSR $FDED + BIT LCBNK2 +end +; +; CHAR IN +; RDKEY() +; +asm cin + BIT ROMIN + STX ESP + JSR $FD0C + LDX ESP + BIT LCBNK2 + DEX + AND #$7F + STA ESTKL,X + LDY #$00 + STY ESTKH,X +end +; +; PRINT STRING +; PRSTR(STR) +; +asm prstr + LDY #$00 + LDA ESTKL,X + STA SRCL + LDA ESTKH,X + STA SRCH + BIT ROMIN + LDA (SRC),Y + STA ESTKL,X + BEQ :+ +_PRS1: INY + LDA (SRC),Y + ORA #$80 + JSR $FDED + TYA + CMP ESTKL,X + BNE _PRS1 +: INX + BIT LCBNK2 +end +; +; READ STRING +; STR = RDSTR(PROMPTCHAR) +; +asm rdstr + LDA ESTKL,X + STA $33 + STX ESP + BIT ROMIN + JSR $FD6A + BIT LCBNK2 + STX $01FF +: LDA $01FF,X + AND #$7F + STA $01FF,X + DEX + BPL :- + LDX ESP + LDA #$FF + STA ESTKL,X + LDA #$01 + STA ESTKH,X +end +;def toupper_11(c) +; if c >= 'a' +; if c <= 'z' +; return c - $20 +; fin +; fin +; return c +;end +asm toupper_11 + LDA ESTKL,X + CMP #'a' + BCC :+ + CMP #'z'+1 + BCS :+ + SEC + SBC #$20 + STA ESTKL,X +: +end +; +; EXIT +; +asm exit + JSR $BF00 + DB $65 + DW EXITTBL +EXITTBL: + DB 4 + DB 0 +end +; +; ProDOS routines +; +def getpfx_11(path) + byte params[3] + + ^path = 0 + params.0 = 1 + params:1 = path + perr = syscall($C7, @params) + return path +end +def setpfx_11(path) + byte params[3] + + params.0 = 1 + params:1 = path + perr = syscall($C6, @params) + return path +end +def open_21(path, buff) + byte params[6] + + params.0 = 3 + params:1 = path + params:3 = buff + params.5 = 0 + perr = syscall($C8, @params) + return params.5 +end +def close_11(refnum) + byte params[2] + + params.0 = 1 + params.1 = refnum + perr = syscall($CC, @params) + return perr +end +def read_31(refnum, buff, len) + byte params[8] + + params.0 = 4 + params.1 = refnum + params:2 = buff + params:4 = len + params:6 = 0 + perr = syscall($CA, @params) + return params:6 +end +def write_31(refnum, buff, len) + byte params[8] + + params.0 = 4 + params.1 = refnum + params:2 = buff + params:4 = len + params:6 = 0 + perr = syscall($CB, @params) + return params:6 +end +def create_41(path, access, type, aux) + byte params[12] + + params.0 = 7 + params:1 = path + params.3 = access + params.4 = type + params:5 = aux + params.7 = $1 + params:8 = 0 + params:10 = 0 + perr = syscall($C0, @params) + return perr +end +def destroy_11(path) + byte params[12] + + params.0 = 1 + params:1 = path + perr = syscall($C1, @params) + return perr +end +def newline_31(refnum, emask, nlchar) + byte params[4] + + params.0 = 3 + params.1 = refnum + params.2 = emask + params.3 = nlchar + perr = syscall($C9, @params) + return perr +end +def crout + cout($0D) +end +def prbyte_10(h) + cout('$') + drop romcall(h, 0, 0, 0, $FDDA) +end +def prword_10(h) + cout('$') + drop romcall(h >> 8, h, 0, 0, $F941) +end +def print_10(i) + byte numstr[7] + byte place, sign + + place = 6 + if i < 0 + sign = 1 + i = -i + else + sign = 0 + fin + while i >= 10 + i =, numstr[place] = i % 10 + '0' + place = place - 1 + loop + numstr[place] = i + '0' + place = place - 1 + if sign + numstr[place] = '-' + place = place - 1 + fin + numstr[place] = 6 - place + prstr(@numstr[place]) +end +def nametostr_30(namestr, len, strptr) + ^strptr = len + memcpy(namestr, strptr + 1, len) +end + +;===================================== +; +; PLASMA Compiler +; +;===================================== + +; +; Error handler +; +def parse_err_11(err) + word i + + drop close_11(0) + crout() + print_10(lineno) + cout(':') + prstr(err) + crout() + prstr(instr) + crout() + for i = inbuff to tknptr - 1 + cout(' ') + next + cout('^') + cin() + exit() + return ERR_TKN +end +; +; Emit bytecode +; +def ctag_new_01 + if codetag >= ctag_max + return parse_err_11(@ctag_full) + fin + codetag = codetag + 1 + ctag_value:[codetag] = 0 + ctag_flags.[codetag] = 0 + return codetag ? is_ctag +end +defopt ctag_resolve_21(tag, addr) + word updtptr, nextptr + + tag = tag & mask_ctag + if ctag_flags.[tag] & resolved + return parse_err_11(@dup_id) + fin + updtptr = ctag_value:[tag] + while updtptr + ; + ; Update list of addresses needing resolution + ; + nextptr = *updtptr + *updtptr = addr + updtptr = nextptr + loop + ctag_value:[tag] = addr + ctag_flags.[tag] = ctag_flags.[tag] ? resolved + return 0 +end +defopt emit_byte_10(bval) + ^codeptr = bval + codeptr = codeptr + 1 +end +defopt emit_word_10(wval) + *codeptr = wval + codeptr = codeptr + 2 +end +def emit_fill_10(size) + memset(0, codeptr, size) + codeptr = codeptr + size +end +def emit_codetag_10(tag) + drop ctag_resolve_21(tag, codeptr) +end +defopt emit_op_10(op) + lastop = op + ^codeptr = op + codeptr = codeptr + 1 +end +def emit_tag_10(tag) + word updtptr + + if tag & is_ctag + tag = tag & mask_ctag + updtptr = ctag_value:[tag] + if !(ctag_flags.[tag] & resolved) + ; + ; Add to list of tags needing resolution + ; + ctag_value:[tag] = codeptr + fin + emit_word_10(updtptr) + else + emit_word_10(tag + codebuff) + fin +end +def emit_iddata_30(value, size, namestr) + emit_fill_10(size) +end +def emit_data_41(vartype, consttype, constval, constsize) + byte i + word size, chrptr + + if consttype == 0 + size = constsize + emit_fill_10(constsize) + elsif consttype == STR_TYPE + size = constsize + chrptr = constval + constsize = constsize - 1 + emit_byte_10(constsize) + while constsize > 0 + emit_byte_10(^chrptr) + chrptr = chrptr + 1 + constsize = constsize - 1 + loop + else + if vartype == WORD_TYPE + size = 2 + emit_word_10(constval) + else + size = 1 + emit_byte_10(constval) + fin + fin + return size +end +def emit_const_10(cval) + if cval == 0 + emit_op_10($00) + elsif cval > 0 and cval < 256 + emit_op_10($2A) + emit_byte_10(cval) + else + emit_op_10($2C) + emit_word_10(cval) + fin +end +def emit_lb + emit_op_10($60) +end +def emit_lw + emit_op_10($62) +end +def emit_llb_10(index) + emit_op_10($64) + emit_byte_10(index) +end +def emit_llw_10(index) + emit_op_10($66) + emit_byte_10(index) +end +def emit_lab_10(tag) + emit_op_10($68) + emit_tag_10(tag) +end +def emit_law_10(tag) + emit_op_10($6A) + emit_tag_10(tag) +end +def emit_sb + emit_op_10($70) +end +def emit_sw + emit_op_10($72) +end +def emit_slb_10(index) + emit_op_10($74) + emit_byte_10(index) +end +def emit_slw_10(index) + emit_op_10($76) + emit_byte_10(index) +end +def emit_dlb_10(index) + emit_op_10($6C) + emit_byte_10(index) +end +def emit_dlw_10(index) + emit_op_10($6E) + emit_byte_10(index) +end +def emit_sab_10(tag) + emit_op_10($78) + emit_tag_10(tag) +end +def emit_saw_10(tag) + emit_op_10($7A) + emit_tag_10(tag) +end +def emit_dab_10(tag) + emit_op_10($7C) + emit_tag_10(tag) +end +def emit_daw_10(tag) + emit_op_10($7E) + emit_tag_10(tag) +end +def emit_call_10(tag) + emit_op_10($54) + emit_tag_10(tag) +end +def emit_ical + emit_op_10($56) +end +def emit_push + emit_op_10($34) +end +def emit_pull + ; + ; Skip if last op was push + ; + if lastop == $34 + codeptr = codeptr - 1 + lastop = $FF + else + emit_op_10($36) + fin +end +def emit_localaddr_10(index) + emit_op_10($28) + emit_byte_10(index) +end +def emit_globaladdr_10(tag) + emit_op_10($26) + emit_tag_10(tag) +end +def emit_indexbyte + emit_op_10($02) +end +def emit_indexword + emit_op_10($1E) +end +defopt emit_unaryop_11(op) + when op + is NEG_TKN + emit_op_10($10) + is COMP_TKN + emit_op_10($12) + is LOGIC_NOT_TKN + emit_op_10($20) + is INC_TKN + emit_op_10($0C) + is DEC_TKN + emit_op_10($0E) + is BPTR_TKN + emit_op_10($60) + is WPTR_TKN + emit_op_10($62) + otherwise + return FALSE + wend + return TRUE +end +defopt emit_binaryop_11(op) + when op + is MUL_TKN + ; + ; Replace MUL 2 with SHL 1 + ; + if lastop == $2A and ^(codeptr - 1) == 2 ; CB 2 + codeptr = codeptr - 1 + emit_byte_10(1) ; CB 1 + emit_op_10($1A) ; SHL + else + emit_op_10($06) + fin + is DIV_TKN + ; + ; Replace DIV 2 with SHR 1 + ; + if lastop == $2A and ^(codeptr - 1) == 2 ; CB 2 + codeptr = codeptr - 1 + emit_byte_10(1) ; CB 1 + emit_op_10($1C) ; SHR + else + emit_op_10($08) + fin + is MOD_TKN + emit_op_10($0A) + is ADD_TKN + ; + ; Replace ADD 1 with INCR + ; + if lastop == $2A and ^(codeptr - 1) == 1 ; CB 1 + codeptr = codeptr - 2 + emit_op_10($0C) ; INC_OP + else + emit_op_10($02) + fin + is SUB_TKN + ; + ; Replace SUB 1 with DECR + ; + if lastop == $2A and ^(codeptr - 1) == 1 ; CB 1 + codeptr = codeptr - 2 + emit_op_10($0E) ; DEC_OP + else + emit_op_10($04) + fin + is SHL_TKN + emit_op_10($1A) + is SHR_TKN + emit_op_10($1C) + is AND_TKN + emit_op_10($14) + is OR_TKN + emit_op_10($16) + is EOR_TKN + emit_op_10($18) + is EQ_TKN + emit_op_10($40) + is NE_TKN + emit_op_10($42) + is GE_TKN + emit_op_10($48) + is LT_TKN + emit_op_10($46) + is GT_TKN + emit_op_10($44) + is LE_TKN + emit_op_10($4A) + is LOGIC_OR_TKN + emit_op_10($22) + is LOGIC_AND_TKN + emit_op_10($24) + is COMMA_TKN + ; Do nothing except move to next stanza in expression + otherwise + return FALSE + wend + return TRUE +end +def emit_brtru_10(tag) + emit_op_10($4E) + emit_tag_10(tag) +end +def emit_brfls_10(tag) + emit_op_10($4C) + emit_tag_10(tag) +end +def emit_brgt_10(tag) + emit_op_10($3A) + emit_tag_10(tag) +end +def emit_brlt_10(tag) + emit_op_10($38) + emit_tag_10(tag) +end +def emit_brne_10(tag) + emit_op_10($3E) + emit_tag_10(tag) +end +def emit_jump_10(tag) + emit_op_10($50) + emit_tag_10(tag) +end +def emit_drop + emit_op_10($30) +end +def emit_swap + emit_op_10($2E) +end +def emit_leave_10(framesize) + if framesize > 2 + emit_op_10($5A) + else + emit_op_10($5C) + fin +end +def emit_enter_20(framesize, cparams) + emit_byte_10($20) + emit_byte_10($D0) + emit_byte_10($03) + if framesize > 2 + emit_op_10($58) + emit_byte_10(framesize) + emit_byte_10(cparams) + fin +end +def emit_start + ; + ; Save address + ; + entrypoint = codeptr + emit_byte_10(emit_start.[0]) + emit_byte_10(emit_start.[1]) + emit_byte_10(emit_start.[2]) +end +def emit_exit + emit_op_10($00) + emit_op_10($5C) +end +; +; Lexical anaylzer +; +;def isalpha_11(c) +; if c >= 'A' and c <= 'Z' +; return TRUE +; elsif c >= 'a' and c <= 'z' +; return TRUE +; elsif c == '_' +; return TRUE +; fin +; return FALSE +;end +asm isalpha_11 + LDY #$00 + LDA ESTKL,X + CMP #'A' + BCC ISALRET + CMP #'Z'+1 + BCS :+ + DEY + BNE ISALRET +: CMP #'a' + BCC ISALRET + CMP #'z'+1 + BCS :+ + DEY + BNE ISALRET +: CMP #'_' + BNE ISALRET + DEY +ISALRET: + STY ESTKL,X + STY ESTKH,X + RTS +end +;def isnum_11(c) +; if c >= '0' and c <= '9' +; return TRUE +; fin +; return FALSE +;end +asm isnum_11 + LDY #$00 + LDA ESTKL,X + CMP #'0' + BCC :+ + CMP #'9'+1 + BCS :+ + DEY +: STY ESTKL,X + STY ESTKH,X + RTS +end +;def isalphanum_11(c) +; if c >= 'A' and c <= 'Z' +; return TRUE +; elsif c >= '0' and c <= '9' +; return TRUE +; elsif c >= 'a' and c <= 'z' +; return TRUE +; elsif c == '_' +; return TRUE +; fin +; return FALSE +;end +asm isalphanum_11 + LDY #$00 + LDA ESTKL,X + CMP #'0' + BCC ISANRET + CMP #'9'+1 + BCS :+ + DEY + BNE ISANRET +: CMP #'A' + BCC ISANRET + CMP #'Z'+1 + BCS :+ + DEY + BNE ISANRET +: CMP #'a' + BCC :+ + CMP #'z'+1 + BCS ISANRET + DEY + BNE ISANRET +: CMP #'_' + BNE ISANRET + DEY +ISANRET: + STY ESTKL,X + STY ESTKH,X + RTS +end +defopt keymatch_21(chrptr, len) + byte i, keypos + + keypos = 0 + while keywrds[keypos] < len + keypos = keypos + keywrds[keypos] + 2 + loop + while keywrds[keypos] == len + for i = 1 to len + if toupper_11((chrptr).[i - 1]) <> keywrds[keypos + i] + break + fin + next + if i > len + return keywrds[keypos + keywrds[keypos] + 1] + fin + keypos = keypos + keywrds[keypos] + 2 + loop + return ID_TKN +end +defopt scan_01 + ; + ; Scan for token based on first character + ; + while ^scanptr and ^scanptr <= ' ' + scanptr = scanptr + 1 + loop + tknptr = scanptr + if !^scanptr or ^scanptr == ';' + if token <> EOF_TKN + token = EOL_TKN + fin + elsif isalpha_11(^scanptr) + ; + ; ID, either variable name or reserved word + ; + repeat + scanptr = scanptr + 1 + until !isalphanum_11(^scanptr) + tknlen = scanptr - tknptr; + token = keymatch_21(tknptr, tknlen) + elsif isnum_11(^scanptr) + ; + ; Number constant + ; + token = INT_TKN + constval = 0 + repeat + constval = constval * 10 + ^scanptr - '0' + scanptr = scanptr + 1 + until !isnum_11(^scanptr) + elsif ^scanptr == '$' + ; + ; Hexadecimal constant + ; + token = INT_TKN; + constval = 0 + repeat + scanptr = scanptr + 1 + if ^scanptr >= '0' and ^scanptr <= '9' + constval = (constval << 4) + ^scanptr - '0' + elsif ^scanptr >= 'A' and ^scanptr <= 'F' + constval = (constval << 4) + ^scanptr - '7'; 'A'-10 + elsif ^scanptr >= 'a' and ^scanptr <= 'f' + constval = (constval << 4) + ^scanptr - 'W'; 'a'-10 + else + break; + fin + until !^scanptr + elsif ^scanptr == $27 ; ' + ; + ; Character constant + ; + token = CHR_TKN + if ^(scanptr + 1) <> $5C ; \ + constval = ^(scanptr + 1) + if ^(scanptr + 2) <> $27 ; ' + return parse_err_11(@bad_cnst) + fin + scanptr = scanptr + 3 + else + when ^(scanptr + 2) + is 'n' + constval = $0D + is 'r' + constval = $0A + is 't' + constval = $09 + otherwise + constval = ^(scanptr + 2) + wend + if ^(scanptr + 3) <> $27 ; ' + return parse_err_11(@bad_cnst) + fin + scanptr = scanptr + 4 + fin + elsif ^scanptr == '"' + ; + ; String constant + ; + token = STR_TKN + scanptr = scanptr + 1 + constval = scanptr + while ^scanptr and ^scanptr <> '"' + scanptr = scanptr + 1 + loop + if !^scanptr + return parse_err_11(@bad_cnst) + fin + scanptr = scanptr + 1 + else + ; + ; Potential two and three character tokens + ; + when ^scanptr + is '>' + if ^(scanptr + 1) == '>' + token = SHR_TKN + scanptr = scanptr + 2 + elsif ^(scanptr + 1) == '=' + token = GE_TKN + scanptr = scanptr + 2 + else + token = GT_TKN + scanptr = scanptr + 1 + fin + is '<' + if ^(scanptr + 1) == '<' + token = SHL_TKN + scanptr = scanptr + 2 + elsif ^(scanptr + 1) == '=' + token = LE_TKN + scanptr = scanptr + 2 + elsif ^(scanptr + 1) == '>' + token = NE_TKN + scanptr = scanptr + 2 + else + token = LT_TKN + scanptr = scanptr + 1 + fin + is '=' + if ^(scanptr + 1) == '=' + token = EQ_TKN + scanptr = scanptr + 2; + elsif ^(scanptr + 1) == ',' + token = SETLIST_TKN + scanptr = scanptr + 2; + else + token = SET_TKN; + scanptr = scanptr + 1 + fin + otherwise + ; + ; Simple single character tokens + ; + token = ^scanptr ? $80 + scanptr = scanptr + 1 + wend + fin + tknlen = scanptr - tknptr + return token +end +def rewind_10(ptr) + scanptr = ptr +end +; +; Get next line of input +; +def nextln_01 + byte i, chr + + scanptr = inbuff + ^instr = read_31(inref, inbuff, $7F) + inbuff[^instr] = $00 + if ^instr + lineno = lineno + 1 + if !(lineno & $0F) + cout('.') + fin +; cout('>') +; prstr(instr) +; crout + drop scan_01() + else + ^instr = 0 + ^inbuff = $00 + token = DONE_TKN + fin + return ^instr +end +; +; Alebraic op to stack op +; +def push_op_21(op, prec) + opsp = opsp + 1 + if opsp == 16 + return parse_err_11(@estk_overflw) + fin + opstack[opsp] = op + precstack[opsp] = prec + return 0 +end +def pop_op_01 + if opsp < 0 + return parse_err_11(@estk_underflw) + fin + opsp = opsp - 1 + return opstack[opsp + 1] +end +def tos_op_01 + if opsp < 0 + return 0 + fin + return opstack[opsp] +end +def tos_op_prec_11(tos) + if opsp <= tos + return 100 + fin + return precstack[opsp] +end +; +; Symbol table +; +defopt idmatch_41(nameptr, len, idptr, idcnt) + byte i + + while idcnt + if len == (idptr).idname + for i = 1 to len + if (nameptr).[i - 1] <> (idptr).idname.[i] + break + fin + next + if i > len + return idptr + fin + fin + idptr = idptr + (idptr).idname + idrecsz + idcnt = idcnt - 1 + loop + return 0 +end +;def dumpsym_20(idptr, idcnt) +; while idcnt +; prword_10((idptr):idval) +; cout(' ') +; prbyte_10((idptr).idtype) +; cout(' ') +; prstr(@(idptr).idname) +; cout('=') +; if (idptr).idtype & ADDR_TYPE +; if (idptr):idval & is_ctag +; prword_10(ctag_value:[(idptr):idval & mask_ctag]) +; else +; prword_10((idptr):idval + codebuff) +; fin +; else +; prword_10((idptr):idval) +; fin +; crout() +; idptr = idptr + (idptr).idname + idrecsz +; idcnt = idcnt - 1 +; loop +;end +def id_lookup_21(nameptr, len) + word idptr + + idptr = idmatch_41(nameptr, len, idlocal_tbl, locals) + if idptr + return idptr + fin + idptr = idmatch_41(nameptr, len, idglobal_tbl, globals) + if idptr + return idptr + fin + return parse_err_11(@undecl_id) +end +def idglobal_lookup_21(nameptr, len) + return idmatch_41(nameptr, len, idglobal_tbl, globals) +end +def idlocal_add_41(namestr, len, type, size) + if idmatch_41(namestr, len, @idlocal_tbl, locals) + return parse_err_11(@dup_id) + fin + (lastlocal):idval = framesize + (lastlocal).idtype = type ? LOCAL_TYPE + nametostr_30(namestr, len, lastlocal + idname) + locals = locals + 1 + lastlocal = lastlocal + idrecsz + len + if lastlocal > idlocal_tbl + idlocal_tblsz + prstr(@local_sym_overflw) + exit + fin + framesize = framesize + size + if framesize > 255 + prstr(@local_overflw) + return FALSE + fin + return TRUE +end +def iddata_add_41(namestr, len, type, size) + if idmatch_41(namestr, len, idglobal_tbl, globals) + return parse_err_11(@dup_id) + fin + (lastglobal):idval = datasize + (lastglobal).idtype = type + nametostr_30(namestr, len, lastglobal + idname) + emit_iddata_30(datasize, size, lastglobal + idname) + globals = globals + 1 + lastglobal = lastglobal + idrecsz + len + if lastglobal > idglobal_tbl + idglobal_tblsz + prstr(@global_sym_overflw) + exit + fin + datasize = datasize + size + return TRUE +end +def iddata_size_30(type, varsize, initsize) + if varsize > initsize + datasize = datasize + emit_data_41(0, 0, 0, varsize - initsize) + else + datasize = datasize + initsize + fin +; if datasize <> codeptr - codebuff +; prstr(@emiterr) +; keyin_01() +; fin +end +def idglobal_add_41(namestr, len, type, value) + if idmatch_41(namestr, len, idglobal_tbl, globals) + return parse_err_11(@dup_id) + fin + (lastglobal):idval = value + (lastglobal).idtype = type + nametostr_30(namestr, len, lastglobal + idname) + globals = globals + 1 + lastglobal = lastglobal + idrecsz + len + if lastglobal > idglobal_tbl + idglobal_tblsz + prstr(@global_sym_overflw) + exit + fin + return TRUE +end +def idfunc_add_31(namestr, len, tag) + return idglobal_add_41(namestr, len, FUNC_TYPE, tag) +end +def idconst_add_31(namestr, len, value) + return idglobal_add_41(namestr, len, CONST_TYPE, value) +end +def idglobal_init + word ctag + + lineno = 0 + codeptr = codebuff + lastop = $FF + entrypoint = 0 + datasize = 0 + globals = 0 + lastglobal = idglobal_tbl + codetag = -1 + ctag = ctag_new_01() + drop idfunc_add_31(@runtime0 + 1, runtime0, ctag) + drop idfunc_add_31(@RUNTIME0 + 1, RUNTIME0, ctag) + drop ctag_resolve_21(ctag, @romcall) + ctag = ctag_new_01() + drop idfunc_add_31(@runtime1 + 1, runtime1, ctag) + drop idfunc_add_31(@RUNTIME1 + 1, RUNTIME1, ctag) + drop ctag_resolve_21(ctag, @syscall) + ctag = ctag_new_01() + drop idfunc_add_31(@runtime2 + 1, runtime2, ctag) + drop idfunc_add_31(@RUNTIME2 + 1, RUNTIME2, ctag) + drop ctag_resolve_21(ctag, @memset) + ctag = ctag_new_01() + drop idfunc_add_31(@runtime3 + 1, runtime3, ctag) + drop idfunc_add_31(@RUNTIME3 + 1, RUNTIME3, ctag) + drop ctag_resolve_21(ctag, @memcpy) + ctag = ctag_new_01() + drop idfunc_add_31(@runtime4 + 1, runtime4, ctag) + drop idfunc_add_31(@RUNTIME4 + 1, RUNTIME4, ctag) + drop ctag_resolve_21(ctag, @cout) + ctag = ctag_new_01() + drop idfunc_add_31(@runtime5 + 1, runtime5, ctag) + drop idfunc_add_31(@RUNTIME5 + 1, RUNTIME5, ctag) + drop ctag_resolve_21(ctag, @cin) + ctag = ctag_new_01() + drop idfunc_add_31(@runtime6 + 1, runtime6, ctag) + drop idfunc_add_31(@RUNTIME6 + 1, RUNTIME6, ctag) + drop ctag_resolve_21(ctag, @prstr) + ctag = ctag_new_01() + drop idfunc_add_31(@runtime7 + 1, runtime7, ctag) + drop idfunc_add_31(@RUNTIME7 + 1, RUNTIME7, ctag) + drop ctag_resolve_21(ctag, @rdstr) +end +def idlocal_init + locals = 0 + framesize = 2 + lastlocal = idlocal_tbl +end +; +; Parser +; +def parse_term_01 + when scan_01() + is ID_TKN + return TRUE + is INT_TKN + return TRUE + is CHR_TKN + return TRUE + is STR_TKN + return TRUE + is OPEN_PAREN_TKN + if !parse_expr_01() + return FALSE + fin + if token <> CLOSE_PAREN_TKN + return parse_err_11(@no_close_paren) + fin + return TRUE + wend + return FALSE +end +def parse_constval_21(valptr, sizeptr) + byte mod, type + word idptr + + mod = 0 + type = 0 + *valptr = 0 + while !parse_term_01() + when token + is SUB_TKN + mod = mod ? 1 + is COMP_TKN + mod = mod ? 2 + is LOGIC_NOT_TKN + mod = mod ? 4 + is AT_TKN + mod = mod ? 8 + otherwise + return 0 + wend + loop + when token + is STR_TKN + *valptr = constval + ^sizeptr = tknlen - 1 + type = STR_TYPE + if mod + return parse_err_11(@bad_op) + fin + is CHR_TKN + *valptr = constval + ^sizeptr = 1 + type = BYTE_TYPE + is INT_TKN + *valptr = constval + ^sizeptr = 2 + type = WORD_TYPE + is ID_TKN + ^sizeptr = 2 + idptr = id_lookup_21(tknptr, tknlen) + if !idptr + return parse_err_11(@bad_cnst) + fin + type = (idptr).idtype + *valptr = (idptr):idval + if type & VAR_TYPE and !(mod & 8) + return parse_err_11(@bad_cnst) + fin + otherwise + return parse_err_11(@bad_cnst) + wend + if mod & 1 + *valptr = -*valptr + fin + if mod & 2 + *valptr = #*valptr + fin + if mod & 4 + *valptr = !*valptr + fin + return type +end +def ispostop_01 + when token + is OPEN_PAREN_TKN + return TRUE + is OPEN_BRACKET_TKN + return TRUE + is DOT_TKN + return TRUE + is COLON_TKN + return TRUE + wend + return FALSE +end +def parse_value_11(rvalue) + byte cparams, deref, type, emit_val + word optos, idptr, value + byte elem_type, elem_size + word elem_offset + + deref = rvalue + optos = opsp + type = 0 + emit_val = 0 + value = 0 + + ; + ; Parse pre-ops + ; + while !parse_term_01() + when token + is ADD_TKN + is BPTR_TKN + if deref + drop push_op_21(token, 0) + else + type = type ? BPTR_TYPE + deref = deref + 1 + fin + is WPTR_TKN + if deref + drop push_op_21(token, 0) + else + type = type ? WPTR_TYPE + deref = deref + 1 + fin + is AT_TKN + deref = deref - 1 + is SUB_TKN + drop push_op_21(token, 0) + is COMP_TKN + drop push_op_21(token, 0) + is LOGIC_NOT_TKN + drop push_op_21(token, 0) + otherwise + return 0 + wend + loop + ; + ; Determine terminal type + ; + when token + is INT_TKN + type = type ? CONST_TYPE + value = constval + is CHR_TKN + type = type ? CONST_TYPE + value = constval + is ID_TKN + idptr = id_lookup_21(tknptr, tknlen) + if !idptr + return 0 + fin + if !(idptr).idtype + return 0 + fin + type = type ? (idptr).idtype + value = (idptr):idval + is CLOSE_PAREN_TKN + type = type ? WORD_TYPE + emit_val = 1 + otherwise + return 0 + wend + ; + ; Constant optimizations + ; + if type & CONST_TYPE + cparams = TRUE + while optos < opsp and cparams + when tos_op_01() + is NEG_TKN + drop pop_op_01() + value = -value + is COMP_TKN + drop pop_op_01() + value = #value + is LOGIC_NOT_TKN + drop pop_op_01() + value = !value + otherwise + cparams = FALSE + wend + loop + fin + ; + ; Parse post-ops + ; + drop scan_01() + while ispostop_01() + if token == OPEN_BRACKET_TKN + ; + ; Array + ; + if !emit_val + if type & ADDR_TYPE + if type & LOCAL_TYPE + emit_localaddr_10(value) + else + emit_globaladdr_10(value) + fin + elsif type & CONST_TYPE + emit_const_10(value) + fin + emit_val = 1 + fin ; !emit_val + if type & PTR_TYPE + emit_lw() + fin + if !parse_expr_01() + return 0 + fin + if token <> CLOSE_BRACKET_TKN + return parse_err_11(@no_close_bracket) + fin + if type & WORD_TYPE + type = WPTR_TYPE + emit_indexword() + else + type = BPTR_TYPE + emit_indexbyte() + fin + drop scan_01() + elsif token == DOT_TKN or token == COLON_TKN + ; + ; Dot and Colon + ; + if token == DOT_TKN + elem_type = BPTR_TYPE + else + elem_type = WPTR_TYPE + fin + if parse_constval_21(@elem_offset, @elem_size) + ; + ; Constant structure offset + ; + if !emit_val + if type & VAR_TYPE + if type & LOCAL_TYPE + emit_localaddr_10(value + elem_offset) + else + ; emit_globaladdr_10(value + elem_offset) + emit_globaladdr_10(value) + emit_const_10(elem_offset) + drop emit_binaryop_11(ADD_TKN) + fin + elsif type & CONST_TYPE + value = value + elem_offset + emit_const_10(value) + else ; FUNC_TYPE + emit_globaladdr_10(value) + emit_const_10(elem_offset) + drop emit_binaryop_11(ADD_TKN) + fin + emit_val = 1 + else + if elem_offset <> 0 + emit_const_10(elem_offset) + drop emit_binaryop_11(ADD_TKN) + fin + fin ; !emit_val + drop scan_01() + elsif token == OPEN_BRACKET_TKN + ; + ; Array of arrays + ; + if !emit_val + if type & ADDR_TYPE + if type & LOCAL_TYPE + emit_localaddr_10(value) + else + emit_globaladdr_10(value) + fin + elsif type & CONST_TYPE + emit_const_10(value) + fin + emit_val = 1 + fin ; !emit_val + repeat + if emit_val > 1 + emit_indexword() + emit_lw() + fin + emit_val = emit_val + 1 + if !parse_expr_01() + return parse_err_11(@bad_expr) + fin + if token <> CLOSE_BRACKET_TKN + return parse_err_11(@no_close_bracket) + fin + until scan_01() <> OPEN_BRACKET_TKN + if elem_type & WPTR_TYPE + emit_indexword() + else + emit_indexbyte() + fin + else + return parse_err_11(@bad_offset) + fin + type = elem_type + elsif token == OPEN_PAREN_TKN + ; + ; Function call + ; + if !emit_val and type & VAR_TYPE + if type & LOCAL_TYPE + emit_localaddr_10(value) + else + emit_globaladdr_10(value) + fin + fin + if !(type & FUNC_CONST_TYPE) + emit_push() + fin + drop parse_expr_01() + if token <> CLOSE_PAREN_TKN + return parse_err_11(@no_close_paren) + fin + if type & FUNC_CONST_TYPE + emit_call_10(value) + else + emit_pull() + emit_ical() + fin + emit_val = 1 + type = WORD_TYPE + drop scan_01() + fin + loop + if emit_val + if rvalue + if deref and type & PTR_TYPE + if type & BPTR_TYPE + emit_lb() + else + emit_lw() + fin + fin + fin + else ; emit_val + if type & CONST_TYPE + emit_const_10(value) + elsif deref + if type & FUNC_TYPE + emit_call_10(value) + elsif type & VAR_TYPE + if type & LOCAL_TYPE + if type & BYTE_TYPE + emit_llb_10(value) + else + emit_llw_10(value) + fin + else + if type & BYTE_TYPE + emit_lab_10(value) + else + emit_law_10(value) + fin + fin + elsif type & PTR_TYPE + if type & BPTR_TYPE + emit_lb() + else + emit_lw() + fin + fin + else + if type & LOCAL_TYPE + emit_localaddr_10(value) + else + emit_globaladdr_10(value) + fin + fin + fin ; emit_val + while optos < opsp + if !emit_unaryop_11(pop_op_01()) + return parse_err_11(@bad_op) + fin + loop + return type +end +def parse_constexpr_21(valptr, sizeptr) + byte type, size1, size2 + word val1, val2 + + type = parse_constval_21(@val1, @size1) + if !type + return 0 + fin + size2 = 0 + when scan_01() + is ADD_TKN + type = parse_constval_21(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 + val2 + is SUB_TKN + type = parse_constval_21(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 - val2 + is MUL_TKN + type = parse_constval_21(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 * val2 + is DIV_TKN + type = parse_constval_21(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 + val2 + is MOD_TKN + type = parse_constval_21(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 % val2 + drop + is AND_TKN + type = parse_constval_21(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 & val2 + is OR_TKN + type = parse_constval_21(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 ? val2 + is EOR_TKN + type = parse_constval_21(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 ^ val2 + otherwise + *valptr = val1 + wend + if size1 > size2 + ^sizeptr = size1 + else + ^sizeptr = size2 + fin + return type +end +def parse_expr_01 + byte prevmatch, matchop, i + word optos + + matchop = 0 + optos = opsp + repeat + prevmatch = matchop + matchop = 0 + if parse_value_11(1) + matchop = 1 + for i = 0 to bops_tblsz + if token == bops_tbl[i] + matchop = 2 + if bops_prec[i] >= tos_op_prec_11(optos) + if !emit_binaryop_11(pop_op_01()) + return parse_err_11(@bad_op) + fin + fin + drop push_op_21(token, bops_prec[i]) + break + fin + next + fin + until matchop <> 2 + if matchop == 0 and prevmatch == 2 + return parse_err_11(@missing_op) + fin + while optos < opsp + if !emit_binaryop_11(pop_op_01()) + return parse_err_11(@bad_op) + fin + loop + return matchop or prevmatch +end +def parse_setlist_21(addr, type) + word nexttype, nextaddr, idptr, saveptr + + if !(type & VAR_TYPE) + emit_push() + fin + nexttype = 0 + nextaddr = 0 + if scan_01() == ID_TKN + idptr = id_lookup_21(tknptr, tknlen) + if !idptr + return FALSE + fin + nexttype = (idptr).idtype + if type & VAR_TYPE + nextaddr = (idptr):idval + fin + fin + saveptr = tknptr + drop scan_01() + if nexttype & VAR_TYPE and token == SET_TKN + drop parse_expr_01() + if type & LOCAL_TYPE + if type & BYTE_TYPE + emit_slb_10(nextaddr) + else + emit_slw_10(nextaddr) + fin + else + if type & BYTE_TYPE + emit_sab_10(nextaddr) + else + emit_saw_10(nextaddr) + fin + fin + elsif nexttype & VAR_TYPE and token == SETLIST_TKN + if !parse_setlist_21(nextaddr, nexttype) + return FALSE + fin + else + tknptr = saveptr + rewind_10(tknptr) + nexttype = parse_value_11(0) + if nexttype <> 0 + if token == SET_TKN + emit_push() + drop parse_expr_01() + emit_pull() + emit_swap() + if nexttype & (BYTE_TYPE ? BPTR_TYPE) + emit_sb() + else + emit_sw() + fin + fin + elsif token == SETLIST_TKN + if !parse_setlist_21(0, nexttype) + return FALSE + fin + else + return parse_err_11(@bad_syntax) + fin + fin + if type & VAR_TYPE + if type & LOCAL_TYPE + if type & BYTE_TYPE + emit_slb_10(addr) + else + emit_slw_10(addr) + fin + else + if type & BYTE_TYPE + emit_sab_10(addr) + else + emit_saw_10(addr) + fin + fin + else + emit_pull() + emit_swap() + if type & (BYTE_TYPE ? BPTR_TYPE) + emit_sb() + else + emit_sw() + fin + fin + return TRUE +end +def parse_stmnt_01 + byte type, i + word tag_prevbrk, tag_else, tag_endif, tag_while, tag_wend + word tag_repeat, tag_for, tag_choice, idptr, saveptr, addr, stepdir + + if token <> END_TKN and token <> DONE_TKN + prevstmnt = token + fin + when token + is IF_TKN + drop parse_expr_01() + tag_else = ctag_new_01() + tag_endif = ctag_new_01() + emit_brfls_10(tag_else) + drop scan_01() + repeat + while parse_stmnt_01() + drop nextln_01() + loop + if token <> ELSEIF_TKN + break + fin + emit_jump_10(tag_endif) + emit_codetag_10(tag_else) + if !parse_expr_01() + return 0 + fin + tag_else = ctag_new_01() + emit_brfls_10(tag_else) + until FALSE + if token == ELSE_TKN + emit_jump_10(tag_endif) + emit_codetag_10(tag_else) + drop scan_01() + while parse_stmnt_01() + drop nextln_01() + loop + emit_codetag_10(tag_endif) + else + emit_codetag_10(tag_else) + emit_codetag_10(tag_endif) + fin + if token <> FIN_TKN + return parse_err_11(@no_fin) + fin + is FOR_TKN + stack_loop = stack_loop + 1 + tag_for = ctag_new_01() + tag_prevbrk = break_tag + break_tag = ctag_new_01() + if scan_01() <> ID_TKN + return parse_err_11(@bad_stmnt) + fin + idptr = id_lookup_21(tknptr, tknlen) + if idptr + type = (idptr).idtype + addr = (idptr):idval + else + return FALSE + fin + if scan_01() <> SET_TKN + return parse_err_11(@bad_stmnt) + fin + if !parse_expr_01() + return parse_err_11(@bad_stmnt) + fin + emit_codetag_10(tag_for) + if type & LOCAL_TYPE + if type & BYTE_TYPE + emit_dlb_10(addr) + else + emit_dlw_10(addr) + fin + else + if type & BYTE_TYPE + emit_dab_10(addr) + else + emit_daw_10(addr) + fin + fin + stepdir = 1 + if token == TO_TKN + drop parse_expr_01() + elsif token == DOWNTO_TKN + drop parse_expr_01() + stepdir = -1 + fin + if stepdir > 0 + emit_brgt_10(break_tag) + else + emit_brlt_10(break_tag) + fin + if token == STEP_TKN + drop parse_expr_01() + if stepdir > 0 + drop emit_binaryop_11(ADD_TKN) + else + drop emit_binaryop_11(SUB_TKN) + fin + else + if stepdir > 0 + drop emit_unaryop_11(INC_TKN) + else + drop emit_unaryop_11(DEC_TKN) + fin + fin + while parse_stmnt_01() + drop nextln_01() + loop + if token <> NEXT_TKN + return parse_err_11(@bad_stmnt) + fin + emit_jump_10(tag_for) + emit_codetag_10(break_tag) + emit_drop() + break_tag = tag_prevbrk + stack_loop = stack_loop - 1 + is WHILE_TKN + tag_while = ctag_new_01() + tag_wend = ctag_new_01() + tag_prevbrk = break_tag + break_tag = tag_wend + emit_codetag_10(tag_while) + drop parse_expr_01() + emit_brfls_10(tag_wend) + while parse_stmnt_01() + drop nextln_01() + loop + if token <> LOOP_TKN + return parse_err_11(@no_loop) + fin + emit_jump_10(tag_while) + emit_codetag_10(tag_wend) + break_tag = tag_prevbrk + is REPEAT_TKN + tag_repeat = ctag_new_01() + tag_prevbrk = break_tag + break_tag = ctag_new_01() + emit_codetag_10(tag_repeat) + drop scan_01() + while parse_stmnt_01() + drop nextln_01() + loop + if token <> UNTIL_TKN + return parse_err_11(@no_until) + fin + drop parse_expr_01() + emit_brfls_10(tag_repeat) + emit_codetag_10(break_tag) + break_tag = tag_prevbrk + is CASE_TKN + stack_loop = stack_loop + 1 + tag_choice = ctag_new_01() + tag_prevbrk = break_tag + break_tag = ctag_new_01() + drop parse_expr_01() + drop nextln_01() + while token <> ENDCASE_TKN + when token + is OF_TKN + if !parse_expr_01() + return parse_err_11(@bad_stmnt) + fin + emit_brne_10(tag_choice) + while parse_stmnt_01() + drop nextln_01() + loop + emit_jump_10(break_tag) + emit_codetag_10(tag_choice) + tag_choice = ctag_new_01() + is DEFAULT_TKN + drop scan_01() + while parse_stmnt_01() + drop nextln_01() + loop + if token <> ENDCASE_TKN + return parse_err_11(@bad_stmnt) + fin + otherwise + return parse_err_11(@bad_stmnt) + wend + loop + emit_codetag_10(break_tag) + emit_drop() + break_tag = tag_prevbrk + stack_loop = stack_loop - 1 + is BREAK_TKN + if break_tag + emit_jump_10(break_tag) + else + return parse_err_11(@bad_stmnt) + fin + is RETURN_TKN + if infunc + for i = 1 to stack_loop + emit_drop() + next + drop parse_expr_01() + emit_leave_10(framesize) + else + return parse_err_11(@bad_stmnt) + fin + is EXIT_TKN + drop parse_expr_01() + emit_exit() + is DROP_TKN + drop parse_expr_01() + emit_drop() + is ELSE_TKN + return FALSE + is ELSEIF_TKN + return FALSE + is FIN_TKN + return FALSE + is LOOP_TKN + return FALSE + is UNTIL_TKN + return FALSE + is NEXT_TKN + return FALSE + is OF_TKN + return FALSE + is DEFAULT_TKN + return FALSE + is ENDCASE_TKN + return FALSE + is END_TKN + return FALSE + is DONE_TKN + return FALSE + is IFUNC_TKN + return FALSE + is NFUNC_TKN + return FALSE + is EOF_TKN + return FALSE + is EOL_TKN + return TRUE + otherwise + if token == ID_TKN + saveptr = tknptr + idptr = id_lookup_21(tknptr, tknlen) + if !idptr + return FALSE + fin + type = (idptr).idtype + if type & ADDR_TYPE + addr = (idptr):idval + if scan_01() == SET_TKN + if type & VAR_TYPE + drop parse_expr_01() + if type & LOCAL_TYPE + if type & BYTE_TYPE + emit_slb_10(addr) + else + emit_slw_10(addr) + fin + else + if type & BYTE_TYPE + emit_sab_10(addr) + else + emit_saw_10(addr) + fin + fin + return TRUE + fin + elsif token == SETLIST_TKN and type & VAR_TYPE + return parse_setlist_21(addr, type); + elsif token == EOL_TKN and type & FUNC_TYPE + emit_call_10(addr) + return TRUE + fin + fin + tknptr = saveptr + fin + rewind_10(tknptr) + type = parse_value_11(0) + if type + if token == SET_TKN + drop parse_expr_01() + if type & XBYTE_TYPE + emit_sb() + else + emit_sw() + fin + elsif token == SETLIST_TKN + return parse_setlist_21(0, type); + else + if type & BPTR_TYPE + emit_lb() + elsif type & WPTR_TYPE + emit_lw() + fin + fin + else + return parse_err_11(@bad_syntax) + fin + wend + if scan_01() <> EOL_TKN + return parse_err_11(@bad_syntax) + fin + return TRUE +end +def parse_var_11(type) + byte consttype, constsize, idlen + word idptr, constval, arraysize, size + + idlen = 0 + size = 1 + if scan_01() == ID_TKN + idptr = tknptr + idlen = tknlen + if scan_01() == OPEN_BRACKET_TKN + size = 0 + drop parse_constexpr_21(@size, @constsize) + if token <> CLOSE_BRACKET_TKN + return parse_err_11(@no_close_bracket) + fin + drop scan_01() + fin + fin + if type == WORD_TYPE + size = size * 2 + fin + if token == SET_TKN + if infunc + return parse_err_11(@no_local_init) + fin + if idlen + drop iddata_add_41(idptr, idlen, type, 0) + fin + consttype = parse_constexpr_21(@constval, @constsize) + if consttype + arraysize = emit_data_41(type, consttype, constval, constsize) + while token == COMMA_TKN + consttype = parse_constexpr_21(@constval, @constsize) + if consttype + arraysize = arraysize + emit_data_41(type, consttype, constval, constsize) + else + return parse_err_11(@bad_decl) + fin + loop + if token <> EOL_TKN + return parse_err_11(@no_close_bracket) + fin + iddata_size_30(PTR_TYPE, size, arraysize); + else + return parse_err_11(@bad_decl) + fin + elsif idlen + if infunc + drop idlocal_add_41(idptr, idlen, type, size) + else + drop iddata_add_41(idptr, idlen, type, size) + fin + fin + return TRUE +end +def parse_vars_01 + byte idlen, type, size + word value, idptr + + when token + is CONST_TKN + if scan_01() <> ID_TKN + return parse_err_11(@bad_cnst) + fin + idptr = tknptr; + idlen = tknlen + if scan_01() <> SET_TKN + return parse_err_11(@bad_cnst) + fin + if !parse_constexpr_21(@value, @size) + return parse_err_11(@bad_cnst) + fin + drop idconst_add_31(idptr, idlen, value) + is BYTE_TKN + type = BYTE_TYPE + repeat + if !parse_var_11(type) + return FALSE + fin + until token <> COMMA_TKN + is WORD_TKN + type = WORD_TYPE + repeat + if !parse_var_11(type) + return FALSE + fin + until token <> COMMA_TKN + is FUNC_TKN + repeat + if scan_01() == ID_TKN + drop idfunc_add_31(tknptr, tknlen, ctag_new_01()) + else + return parse_err_11(@bad_decl) + fin + until scan_01() <> COMMA_TKN + is EOL_TKN + return TRUE + otherwise + return FALSE + wend + return TRUE +end +def parse_func_01 + byte opt, cfnparms + word func_tag, idptr + + if token == IFUNC_TKN or token == NFUNC_TKN + opt = token - IFUNC_TKN + if scan_01() <> ID_TKN + return parse_err_11(@bad_decl) + fin + cfnparms = 0 + infunc = TRUE + idptr = idglobal_lookup_21(tknptr, tknlen) + if idptr + func_tag = (idptr):idval + else + func_tag = ctag_new_01() + drop idfunc_add_31(tknptr, tknlen, func_tag) + fin + emit_codetag_10(func_tag) + retfunc_tag = ctag_new_01() + idlocal_init() + if scan_01() == OPEN_PAREN_TKN + repeat + if scan_01() == ID_TKN + cfnparms = cfnparms + 1 + drop idlocal_add_41(tknptr, tknlen, WORD_TYPE, 2) + drop scan_01() + fin + until token <> COMMA_TKN + if token <> CLOSE_PAREN_TKN + return parse_err_11(@bad_decl) + fin + drop scan_01() + fin + while parse_vars_01() + drop nextln_01() + loop + emit_enter_20(framesize, cfnparms) + prevstmnt = 0 + while parse_stmnt_01() + drop nextln_01() + loop + infunc = FALSE + if token <> END_TKN + return parse_err_11(@bad_syntax) + fin + if scan_01() <> EOL_TKN + return parse_err_11(@bad_syntax) + fin + if prevstmnt <> RETURN_TKN + emit_leave_10(framesize) + fin + return TRUE + elsif token == EOL_TKN + return TRUE + fin + return FALSE +end +def parse_module_01 + entrypoint = 0 + idglobal_init() + idlocal_init() + if nextln_01() + while parse_vars_01() + drop nextln_01() + loop + while parse_func_01() + drop nextln_01() + loop + if token <> DONE_TKN + emit_start() + prevstmnt = 0 + while parse_stmnt_01() + drop nextln_01() + loop + if token <> DONE_TKN + drop parse_err_11(@no_done) + fin + if prevstmnt <> EXIT_TKN + emit_const_10(0) + emit_exit() + fin + fin + ; dumpsym(idglobal_tbl, globals) + ; prstr(@entrypt_str) + ; prword(entrypoint) + ; crout() + ; keyin_01() + return TRUE + fin + return FALSE +end +def exec + when execentry() + is 0 + crout() + prstr(@donemsg) + is 1 + crout() + prstr(@brkmsg) + is 2 + crout() + prstr(@stkovflwmsg) + wend +end +; +; Compile PLASMA file and execute it +; +;emptystk = estk() +prstr(@version) +crout() +if ^argbuff + inref = open_21(argbuff, iobuffer) +else + inref = open_21(rdstr($BA), iobuffer) +fin +if inref + drop newline_31(inref, $7F, $0D) + if parse_module_01() + drop close_11(inref) + exec(entrypoint) + ; + ; Close all files + ; + ^$BFD8 = 0 + drop close_11(0) + else + drop close_11(inref) + crout() + prstr(@badfile) + fin + cin() +; crout +; dumpsym(@idglobal_tbl, globals) +; crout +fin +done diff --git a/plasma2/plex.s b/plasma2/plex.s new file mode 100755 index 0000000..57d529b --- /dev/null +++ b/plasma2/plex.s @@ -0,0 +1,11246 @@ + .INCLUDE "plstub.s" +; 1: ; +; 2: ; Global constants +; 3: ; +; 4: const FALSE = 0 + ; FALSE = 0 +; 5: const TRUE = !FALSE + ; TRUE = -1 +; 6: ; +; 7: ; Data and text buffer constants +; 8: ; +; 9: const iobuffer = $0800 + ; iobuffer = 2048 +; 10: const codebuff = $6000 + ; codebuff = 24576 +; 11: const codebuffsz = $5000 + ; codebuffsz = 20480 +; 12: const argbuff = $2006 + ; argbuff = 8198 +; 13: const inbuff = $0200 + ; inbuff = 512 +; 14: const instr = $01FF + ; instr = 511 +; 15: byte inref +D0000: DS 1 ; inref +; 16: ;byte emptystk +; 17: ; +; 18: ; Symbol table variables +; 19: ; +; 20: const idglobal_tblsz = $0800 + ; idglobal_tblsz = 2048 +; 21: const idlocal_tblsz = $0200 + ; idlocal_tblsz = 512 +; 22: const idglobal_tbl = $1000 + ; idglobal_tbl = 4096 +; 23: const idlocal_tbl = $1800 + ; idlocal_tbl = 6144 +; 24: const ctag_max = 768 + ; ctag_max = 768 +; 25: const ctag_value = $1A00 + ; ctag_value = 6656 +; 26: const ctag_flags = $0D00 + ; ctag_flags = 3328 +; 27: const idval = 0 + ; idval = 0 +; 28: const idtype = 2 + ; idtype = 2 +; 29: const idname = 3 + ; idname = 3 +; 30: const idrecsz = 4 + ; idrecsz = 4 +; 31: word globals = 0 +D0001: ; globals + DW $0000 +; 32: word datasize = 0 +D0003: ; datasize + DW $0000 +; 33: word lastglobal +D0005: DS 2 ; lastglobal +; 34: byte locals = 0 +D0007: ; locals + DB $00 +; 35: word framesize = 0 +D0008: ; framesize + DW $0000 +; 36: word lastlocal +D0010: DS 2 ; lastlocal +; 37: const resolved = 1 + ; resolved = 1 +; 38: const is_ctag = $8000 + ; is_ctag = 32768 +; 39: const mask_ctag = $7FFF + ; mask_ctag = 32767 +; 40: word codetag = -1 +D0012: ; codetag + DW $FFFF +; 41: word codeptr +D0014: DS 2 ; codeptr +; 42: word entrypoint = 0 +D0016: ; entrypoint + DW $0000 +; 43: byte lastop = $FF +D0018: ; lastop + DB $FF +; 44: byte perr +D0019: DS 1 ; perr +; 45: ; +; 46: ; String variables +; 47: ; +; 48: byte version[] = "PLASMA ][ EXECUTIVE VERSION 0.8 " +D0020: ; version + DB $20 + DB $50,$4C,$41,$53,$4D,$41,$20,$5D + DB $5B,$20,$45,$58,$45,$43,$55,$54 + DB $49,$56,$45,$20,$56,$45,$52,$53 + DB $49,$4F,$4E,$20,$30,$2E,$38,$20 +; 49: byte donemsg[] = "EXECUTION COMPLETE. PRESS A KEY..." +D0053: ; donemsg + DB $23 + DB $45,$58,$45,$43,$55,$54,$49,$4F + DB $4E,$20,$43,$4F,$4D,$50,$4C,$45 + DB $54,$45,$2E,$20,$20,$50,$52,$45 + DB $53,$53,$20,$41,$20,$4B,$45,$59 + DB $2E,$2E,$2E +; 50: byte badfile[] = "FILE NOT FOUND" +D0089: ; badfile + DB $0E + DB $46,$49,$4C,$45,$20,$4E,$4F,$54 + DB $20,$46,$4F,$55,$4E,$44 +; 51: byte brkmsg[] = "CTRL-C BREAK" +D0104: ; brkmsg + DB $0C + DB $43,$54,$52,$4C,$2D,$43,$20,$42 + DB $52,$45,$41,$4B +; 52: byte stkovflwmsg[] = "STACK OVERFLOW/UNDERFLOW ERROR" +D0117: ; stkovflwmsg + DB $1E + DB $53,$54,$41,$43,$4B,$20,$4F,$56 + DB $45,$52,$46,$4C,$4F,$57,$2F,$55 + DB $4E,$44,$45,$52,$46,$4C,$4F,$57 + DB $20,$45,$52,$52,$4F,$52 +; 53: ; +; 54: ; Tokens +; 55: ; +; 56: const ID_TKN = $D6 ; V + ; ID_TKN = 214 +; 57: const CHR_TKN = $C3 ; C + ; CHR_TKN = 195 +; 58: const INT_TKN = $C9 ; I + ; INT_TKN = 201 +; 59: const STR_TKN = $D3 ; S + ; STR_TKN = 211 +; 60: const EOL_TKN = $02 + ; EOL_TKN = 2 +; 61: const EOF_TKN = $01 + ; EOF_TKN = 1 +; 62: const ERR_TKN = $00 + ; ERR_TKN = 0 +; 63: ; +; 64: ; Binary operand operators +; 65: ; +; 66: const SET_TKN = $BD ; = + ; SET_TKN = 189 +; 67: const SETLIST_TKN = $B9 ; =, + ; SETLIST_TKN = 185 +; 68: const ADD_TKN = $AB ; + + ; ADD_TKN = 171 +; 69: const SUB_TKN = $AD ; - + ; SUB_TKN = 173 +; 70: const MUL_TKN = $AA ; * + ; MUL_TKN = 170 +; 71: const DIV_TKN = $AF ; / + ; DIV_TKN = 175 +; 72: const MOD_TKN = $A5 ; % + ; MOD_TKN = 165 +; 73: const OR_TKN = $BF ; ? + ; OR_TKN = 191 +; 74: const EOR_TKN = $DE ; ^ + ; EOR_TKN = 222 +; 75: const AND_TKN = $A6 ; & + ; AND_TKN = 166 +; 76: const SHR_TKN = $D2 ; R + ; SHR_TKN = 210 +; 77: const SHL_TKN = $CC ; L + ; SHL_TKN = 204 +; 78: const GT_TKN = $BE ; > + ; GT_TKN = 190 +; 79: const GE_TKN = $C8 ; H + ; GE_TKN = 200 +; 80: const LT_TKN = $BC ; < + ; LT_TKN = 188 +; 81: const LE_TKN = $C2 ; B + ; LE_TKN = 194 +; 82: const NE_TKN = $D5 ; U + ; NE_TKN = 213 +; 83: const EQ_TKN = $C5 ; E + ; EQ_TKN = 197 +; 84: const LOGIC_AND_TKN = $CE ; N + ; LOGIC_AND_TKN = 206 +; 85: const LOGIC_OR_TKN = $CF ; O + ; LOGIC_OR_TKN = 207 +; 86: ; +; 87: ; Unary operand operators +; 88: ; +; 89: const AT_TKN = $C0 ; @ + ; AT_TKN = 192 +; 90: const DOT_TKN = $AE ; . + ; DOT_TKN = 174 +; 91: const COLON_TKN = $BA ; : + ; COLON_TKN = 186 +; 92: const NEG_TKN = $AD ; - + ; NEG_TKN = 173 +; 93: const COMP_TKN = $A3 ; # + ; COMP_TKN = 163 +; 94: const LOGIC_NOT_TKN = $A1 ; ! + ; LOGIC_NOT_TKN = 161 +; 95: const BPTR_TKN = $DE ; ^ + ; BPTR_TKN = 222 +; 96: const WPTR_TKN = $AA ; * + ; WPTR_TKN = 170 +; 97: const INC_TKN = $C1 ; A + ; INC_TKN = 193 +; 98: const DEC_TKN = $C4 ; D + ; DEC_TKN = 196 +; 99: ; +; 100: ; Enclosure tokens +; 101: ; +; 102: const OPEN_PAREN_TKN = $A8 ; ( + ; OPEN_PAREN_TKN = 168 +; 103: const CLOSE_PAREN_TKN = $A9 ; ) + ; CLOSE_PAREN_TKN = 169 +; 104: const OPEN_BRACKET_TKN = $DB ; [ + ; OPEN_BRACKET_TKN = 219 +; 105: const CLOSE_BRACKET_TKN = $DD ; ] + ; CLOSE_BRACKET_TKN = 221 +; 106: ; +; 107: ; Misc. tokens +; 108: ; +; 109: const COMMA_TKN = $AC ; , + ; COMMA_TKN = 172 +; 110: const COMMENT_TKN = $BB ; ; + ; COMMENT_TKN = 187 +; 111: ; +; 112: ; Keyword tokens +; 113: ; +; 114: const CONST_TKN = $80 + ; CONST_TKN = 128 +; 115: const BYTE_TKN = $81 + ; BYTE_TKN = 129 +; 116: const WORD_TKN = $82 + ; WORD_TKN = 130 +; 117: const IF_TKN = $83 + ; IF_TKN = 131 +; 118: const ELSEIF_TKN = $84 + ; ELSEIF_TKN = 132 +; 119: const ELSE_TKN = $85 + ; ELSE_TKN = 133 +; 120: const FIN_TKN = $86 + ; FIN_TKN = 134 +; 121: const END_TKN = $87 + ; END_TKN = 135 +; 122: const WHILE_TKN = $88 + ; WHILE_TKN = 136 +; 123: const LOOP_TKN = $89 + ; LOOP_TKN = 137 +; 124: const CASE_TKN = $8A + ; CASE_TKN = 138 +; 125: const OF_TKN = $8B + ; OF_TKN = 139 +; 126: const DEFAULT_TKN = $8C + ; DEFAULT_TKN = 140 +; 127: const ENDCASE_TKN = $8D + ; ENDCASE_TKN = 141 +; 128: const FOR_TKN = $8E + ; FOR_TKN = 142 +; 129: const TO_TKN = $8F + ; TO_TKN = 143 +; 130: const DOWNTO_TKN = $90 + ; DOWNTO_TKN = 144 +; 131: const STEP_TKN = $91 + ; STEP_TKN = 145 +; 132: const NEXT_TKN = $92 + ; NEXT_TKN = 146 +; 133: const REPEAT_TKN = $93 + ; REPEAT_TKN = 147 +; 134: const UNTIL_TKN = $94 + ; UNTIL_TKN = 148 +; 135: const IFUNC_TKN = $95 + ; IFUNC_TKN = 149 +; 136: const NFUNC_TKN = $96 + ; NFUNC_TKN = 150 +; 137: const DROP_TKN = $97 + ; DROP_TKN = 151 +; 138: const DONE_TKN = $98 + ; DONE_TKN = 152 +; 139: const RETURN_TKN = $99 + ; RETURN_TKN = 153 +; 140: const BREAK_TKN = $9A + ; BREAK_TKN = 154 +; 141: const START_TKN = $9B + ; START_TKN = 155 +; 142: const EXIT_TKN = $9C + ; EXIT_TKN = 156 +; 143: const EVAL_TKN = $9D + ; EVAL_TKN = 157 +; 144: const FUNC_TKN = $9E + ; FUNC_TKN = 158 +; 145: ; +; 146: ; Types +; 147: ; +; 148: const CONST_TYPE = $01 + ; CONST_TYPE = 1 +; 149: const BYTE_TYPE = $02 + ; BYTE_TYPE = 2 +; 150: const WORD_TYPE = $04 + ; WORD_TYPE = 4 +; 151: const VAR_TYPE = $06 ; (WORD_TYPE | BYTE_TYPE) + ; VAR_TYPE = 6 +; 152: const FUNC_TYPE = $08 + ; FUNC_TYPE = 8 +; 153: const FUNC_CONST_TYPE = $09 + ; FUNC_CONST_TYPE = 9 +; 154: const ADDR_TYPE = $0E ; (VAR_TYPE | FUNC_TYPE) + ; ADDR_TYPE = 14 +; 155: const LOCAL_TYPE = $10 + ; LOCAL_TYPE = 16 +; 156: const BPTR_TYPE = $20 + ; BPTR_TYPE = 32 +; 157: const WPTR_TYPE = $40 + ; WPTR_TYPE = 64 +; 158: const PTR_TYPE = $60 ; (BPTR_TYPE | WPTR_TYPE) + ; PTR_TYPE = 96 +; 159: const XBYTE_TYPE = $22 ; (BPTR_TYPE | BYTE_TYPE) + ; XBYTE_TYPE = 34 +; 160: const XWORD_TYPE = $44 ; (WPTR_TYPE | WORD_TYPE) + ; XWORD_TYPE = 68 +; 161: const STR_TYPE = $80 + ; STR_TYPE = 128 +; 162: ; +; 163: ; Keywords +; 164: ; +; 165: byte keywrds[] +D0148: ; keywrds +; 166: byte = "IF", IF_TKN + DB $02 + DB $49,$46 + DB $83 +; 167: byte = "TO", TO_TKN + DB $02 + DB $54,$4F + DB $8F +; 168: byte = "IS", OF_TKN + DB $02 + DB $49,$53 + DB $8B +; 169: byte = "OR", LOGIC_OR_TKN + DB $02 + DB $4F,$52 + DB $CF +; 170: byte = "FOR", FOR_TKN + DB $03 + DB $46,$4F,$52 + DB $8E +; 171: byte = "FIN", FIN_TKN + DB $03 + DB $46,$49,$4E + DB $86 +; 172: byte = "DEF", IFUNC_TKN + DB $03 + DB $44,$45,$46 + DB $95 +; 173: byte = "END", END_TKN + DB $03 + DB $45,$4E,$44 + DB $87 +; 174: byte = "AND", LOGIC_AND_TKN + DB $03 + DB $41,$4E,$44 + DB $CE +; 175: byte = "NOT", LOGIC_NOT_TKN + DB $03 + DB $4E,$4F,$54 + DB $A1 +; 176: byte = "BYTE", BYTE_TKN + DB $04 + DB $42,$59,$54,$45 + DB $81 +; 177: byte = "WORD", WORD_TKN + DB $04 + DB $57,$4F,$52,$44 + DB $82 +; 178: byte = "DROP", DROP_TKN + DB $04 + DB $44,$52,$4F,$50 + DB $97 +; 179: byte = "ELSE", ELSE_TKN + DB $04 + DB $45,$4C,$53,$45 + DB $85 +; 180: byte = "NEXT", NEXT_TKN + DB $04 + DB $4E,$45,$58,$54 + DB $92 +; 181: byte = "WHEN", CASE_TKN + DB $04 + DB $57,$48,$45,$4E + DB $8A +; 182: byte = "LOOP", LOOP_TKN + DB $04 + DB $4C,$4F,$4F,$50 + DB $89 +; 183: byte = "FUNC", FUNC_TKN + DB $04 + DB $46,$55,$4E,$43 + DB $9E +; 184: byte = "STEP", STEP_TKN + DB $04 + DB $53,$54,$45,$50 + DB $91 +; 185: byte = "EXIT", EXIT_TKN + DB $04 + DB $45,$58,$49,$54 + DB $9C +; 186: byte = "DONE", DONE_TKN + DB $04 + DB $44,$4F,$4E,$45 + DB $98 +; 187: byte = "WEND", ENDCASE_TKN + DB $04 + DB $57,$45,$4E,$44 + DB $8D +; 188: byte = "CONST", CONST_TKN + DB $05 + DB $43,$4F,$4E,$53,$54 + DB $80 +; 189: byte = "ELSIF", ELSEIF_TKN + DB $05 + DB $45,$4C,$53,$49,$46 + DB $84 +; 190: byte = "WHILE", WHILE_TKN + DB $05 + DB $57,$48,$49,$4C,$45 + DB $88 +; 191: byte = "UNTIL", UNTIL_TKN + DB $05 + DB $55,$4E,$54,$49,$4C + DB $94 +; 192: byte = "BREAK", BREAK_TKN + DB $05 + DB $42,$52,$45,$41,$4B + DB $9A +; 193: byte = "OTHER", DEFAULT_TKN + DB $05 + DB $4F,$54,$48,$45,$52 + DB $8C +; 194: byte = "DOWNTO", DOWNTO_TKN + DB $06 + DB $44,$4F,$57,$4E,$54,$4F + DB $90 +; 195: byte = "REPEAT", REPEAT_TKN + DB $06 + DB $52,$45,$50,$45,$41,$54 + DB $93 +; 196: byte = "DEFOPT", NFUNC_TKN + DB $06 + DB $44,$45,$46,$4F,$50,$54 + DB $96 +; 197: byte = "RETURN", RETURN_TKN + DB $06 + DB $52,$45,$54,$55,$52,$4E + DB $99 +; 198: byte = $FF + DB $FF +; 199: ; +; 200: ; Mathematical ops +; 201: ; +; 202: const bops_tblsz = 18 ; minus 1 + ; bops_tblsz = 18 +; 203: byte bops_tbl[] ; Highest precedence +D0341: ; bops_tbl +; 204: byte = MUL_TKN, DIV_TKN, MOD_TKN + DB $AA + DB $AF + DB $A5 +; 205: byte = ADD_TKN, SUB_TKN + DB $AB + DB $AD +; 206: byte = SHR_TKN, SHL_TKN + DB $D2 + DB $CC +; 207: byte = AND_TKN + DB $A6 +; 208: byte = EOR_TKN + DB $DE +; 209: byte = OR_TKN + DB $BF +; 210: byte = GT_TKN, GE_TKN, LT_TKN, LE_TKN + DB $BE + DB $C8 + DB $BC + DB $C2 +; 211: byte = EQ_TKN, NE_TKN + DB $C5 + DB $D5 +; 212: byte = LOGIC_AND_TKN + DB $CE +; 213: byte = LOGIC_OR_TKN + DB $CF +; 214: byte = COMMA_TKN + DB $AC +; 215: ; Lowest precedence +; 216: byte bops_prec[] ; Highest precedence +D0360: ; bops_prec +; 217: byte = 1, 1, 1 + DB $01 + DB $01 + DB $01 +; 218: byte = 2, 2 + DB $02 + DB $02 +; 219: byte = 3, 3 + DB $03 + DB $03 +; 220: byte = 4 + DB $04 +; 221: byte = 5 + DB $05 +; 222: byte = 6 + DB $06 +; 223: byte = 7, 7, 7, 7 + DB $07 + DB $07 + DB $07 + DB $07 +; 224: byte = 8, 8 + DB $08 + DB $08 +; 225: byte = 9 + DB $09 +; 226: byte = 10 + DB $0A +; 227: byte = 11 + DB $0B +; 228: ; Lowest precedence +; 229: byte opstack[16] +D0379: DS 16 ; opstack +; 230: byte precstack[16] +D0395: DS 16 ; precstack +; 231: word opsp = -1 +D0411: ; opsp + DW $FFFF +; 232: ; +; 233: ; Scanner variables +; 234: ; +; 235: byte token, tknlen +D0413: DS 1 ; token +D0414: DS 1 ; tknlen +; 236: word scanptr, tknptr +D0415: DS 2 ; scanptr +D0417: DS 2 ; tknptr +; 237: word constval +D0419: DS 2 ; constval +; 238: word lineno = 0 +D0421: ; lineno + DW $0000 +; 239: ; +; 240: ; Compiler output messages +; 241: ; +; 242: byte entrypt_str[] = "START: " +D0423: ; entrypt_str + DB $07 + DB $53,$54,$41,$52,$54,$3A,$20 +; 243: byte dup_id[] = "DUPLICATE IDENTIFIER" +D0431: ; dup_id + DB $14 + DB $44,$55,$50,$4C,$49,$43,$41,$54 + DB $45,$20,$49,$44,$45,$4E,$54,$49 + DB $46,$49,$45,$52 +; 244: byte undecl_id[] = "UNDECLARED IDENTIFIER" +D0452: ; undecl_id + DB $15 + DB $55,$4E,$44,$45,$43,$4C,$41,$52 + DB $45,$44,$20,$49,$44,$45,$4E,$54 + DB $49,$46,$49,$45,$52 +; 245: byte bad_cnst[] = "BAD CONSTANT" +D0474: ; bad_cnst + DB $0C + DB $42,$41,$44,$20,$43,$4F,$4E,$53 + DB $54,$41,$4E,$54 +; 246: byte bad_offset[] = "BAD STRUCT OFFSET" +D0487: ; bad_offset + DB $11 + DB $42,$41,$44,$20,$53,$54,$52,$55 + DB $43,$54,$20,$4F,$46,$46,$53,$45 + DB $54 +; 247: byte bad_decl[] = "BAD DECLARATION" +D0505: ; bad_decl + DB $0F + DB $42,$41,$44,$20,$44,$45,$43,$4C + DB $41,$52,$41,$54,$49,$4F,$4E +; 248: byte bad_op[] = "BAD OPERATION" +D0521: ; bad_op + DB $0D + DB $42,$41,$44,$20,$4F,$50,$45,$52 + DB $41,$54,$49,$4F,$4E +; 249: byte bad_stmnt[] = "BAD STATMENT" +D0535: ; bad_stmnt + DB $0C + DB $42,$41,$44,$20,$53,$54,$41,$54 + DB $4D,$45,$4E,$54 +; 250: byte bad_expr[] = "BAD EXPRESSION" +D0548: ; bad_expr + DB $0E + DB $42,$41,$44,$20,$45,$58,$50,$52 + DB $45,$53,$53,$49,$4F,$4E +; 251: byte bad_syntax[] = "BAD SYNTAX" +D0563: ; bad_syntax + DB $0A + DB $42,$41,$44,$20,$53,$59,$4E,$54 + DB $41,$58 +; 252: byte estk_overflw[] = "EVAL STACK OVERFLOW" +D0574: ; estk_overflw + DB $13 + DB $45,$56,$41,$4C,$20,$53,$54,$41 + DB $43,$4B,$20,$4F,$56,$45,$52,$46 + DB $4C,$4F,$57 +; 253: byte estk_underflw[] = "EVAL STACK UNDERFLOW" +D0594: ; estk_underflw + DB $14 + DB $45,$56,$41,$4C,$20,$53,$54,$41 + DB $43,$4B,$20,$55,$4E,$44,$45,$52 + DB $46,$4C,$4F,$57 +; 254: byte local_overflw[] = "LOCAL FRAME OVERFLOW" +D0615: ; local_overflw + DB $14 + DB $4C,$4F,$43,$41,$4C,$20,$46,$52 + DB $41,$4D,$45,$20,$4F,$56,$45,$52 + DB $46,$4C,$4F,$57 +; 255: byte global_sym_overflw[] = "GLOBAL SYMBOL TABLE OVERFLOW" +D0636: ; global_sym_overflw + DB $1C + DB $47,$4C,$4F,$42,$41,$4C,$20,$53 + DB $59,$4D,$42,$4F,$4C,$20,$54,$41 + DB $42,$4C,$45,$20,$4F,$56,$45,$52 + DB $46,$4C,$4F,$57 +; 256: byte local_sym_overflw[] = "LOCAL SYMBOL TABLE OVERFLOW" +D0665: ; local_sym_overflw + DB $1B + DB $4C,$4F,$43,$41,$4C,$20,$53,$59 + DB $4D,$42,$4F,$4C,$20,$54,$41,$42 + DB $4C,$45,$20,$4F,$56,$45,$52,$46 + DB $4C,$4F,$57 +; 257: byte ctag_full[] = "CODE LABEL OVERFLOW" +D0693: ; ctag_full + DB $13 + DB $43,$4F,$44,$45,$20,$4C,$41,$42 + DB $45,$4C,$20,$4F,$56,$45,$52,$46 + DB $4C,$4F,$57 +; 258: byte no_close_paren[] = "MISSING CLOSING PAREN" +D0713: ; no_close_paren + DB $15 + DB $4D,$49,$53,$53,$49,$4E,$47,$20 + DB $43,$4C,$4F,$53,$49,$4E,$47,$20 + DB $50,$41,$52,$45,$4E +; 259: byte no_close_bracket[] = "MISSING CLOSING BRACKET" +D0735: ; no_close_bracket + DB $17 + DB $4D,$49,$53,$53,$49,$4E,$47,$20 + DB $43,$4C,$4F,$53,$49,$4E,$47,$20 + DB $42,$52,$41,$43,$4B,$45,$54 +; 260: byte missing_op[] = "MISSING OPERAND" +D0759: ; missing_op + DB $0F + DB $4D,$49,$53,$53,$49,$4E,$47,$20 + DB $4F,$50,$45,$52,$41,$4E,$44 +; 261: byte no_fin[] = "MISSING FIN" +D0775: ; no_fin + DB $0B + DB $4D,$49,$53,$53,$49,$4E,$47,$20 + DB $46,$49,$4E +; 262: byte no_loop[] = "MISSING LOOP" +D0787: ; no_loop + DB $0C + DB $4D,$49,$53,$53,$49,$4E,$47,$20 + DB $4C,$4F,$4F,$50 +; 263: byte no_until[] = "MISSING UNTIL" +D0800: ; no_until + DB $0D + DB $4D,$49,$53,$53,$49,$4E,$47,$20 + DB $55,$4E,$54,$49,$4C +; 264: byte no_done[] = "MISSING DONE" +D0814: ; no_done + DB $0C + DB $4D,$49,$53,$53,$49,$4E,$47,$20 + DB $44,$4F,$4E,$45 +; 265: byte no_local_init[] = "NO INITIALIZED LOCALS" +D0827: ; no_local_init + DB $15 + DB $4E,$4F,$20,$49,$4E,$49,$54,$49 + DB $41,$4C,$49,$5A,$45,$44,$20,$4C + DB $4F,$43,$41,$4C,$53 +; 266: ; +; 267: ; Runtime functions +; 268: ; +; 269: byte runtime0[] = "romcall" +D0849: ; runtime0 + DB $07 + DB $72,$6F,$6D,$63,$61,$6C,$6C +; 270: byte RUNTIME0[] = "ROMCALL" +D0857: ; RUNTIME0 + DB $07 + DB $52,$4F,$4D,$43,$41,$4C,$4C +; 271: byte runtime1[] = "syscall" +D0865: ; runtime1 + DB $07 + DB $73,$79,$73,$63,$61,$6C,$6C +; 272: byte RUNTIME1[] = "SYSCALL" +D0873: ; RUNTIME1 + DB $07 + DB $53,$59,$53,$43,$41,$4C,$4C +; 273: byte runtime2[] = "memset" +D0881: ; runtime2 + DB $06 + DB $6D,$65,$6D,$73,$65,$74 +; 274: byte RUNTIME2[] = "MEMSET" +D0888: ; RUNTIME2 + DB $06 + DB $4D,$45,$4D,$53,$45,$54 +; 275: byte runtime3[] = "memcpy" +D0895: ; runtime3 + DB $06 + DB $6D,$65,$6D,$63,$70,$79 +; 276: byte RUNTIME3[] = "MEMCPY" +D0902: ; RUNTIME3 + DB $06 + DB $4D,$45,$4D,$43,$50,$59 +; 277: byte runtime4[] = "cout" +D0909: ; runtime4 + DB $04 + DB $63,$6F,$75,$74 +; 278: byte RUNTIME4[] = "COUT" +D0914: ; RUNTIME4 + DB $04 + DB $43,$4F,$55,$54 +; 279: byte runtime5[] = "cin" +D0919: ; runtime5 + DB $03 + DB $63,$69,$6E +; 280: byte RUNTIME5[] = "CIN" +D0923: ; RUNTIME5 + DB $03 + DB $43,$49,$4E +; 281: byte runtime6[] = "prstr" +D0927: ; runtime6 + DB $05 + DB $70,$72,$73,$74,$72 +; 282: byte RUNTIME6[] = "PRSTR" +D0933: ; RUNTIME6 + DB $05 + DB $50,$52,$53,$54,$52 +; 283: byte runtime7[] = "rdstr" +D0939: ; runtime7 + DB $05 + DB $72,$64,$73,$74,$72 +; 284: byte RUNTIME7[] = "RDSTR" +D0945: ; RUNTIME7 + DB $05 + DB $52,$44,$53,$54,$52 +; 285: ; +; 286: ; Parser variables +; 287: ; +; 288: byte infunc = 0 +D0951: ; infunc + DB $00 +; 289: byte stack_loop = 0 +D0952: ; stack_loop + DB $00 +; 290: byte prevstmnt = 0 +D0953: ; prevstmnt + DB $00 +; 291: word retfunc_tag = 0 +D0954: ; retfunc_tag + DW $0000 +; 292: word break_tag = 0 +D0956: ; break_tag + DW $0000 +; 293: func parse_expr_01, parse_module_01 +; 294: ; +; 295: ; Defines for ASM routines +; 296: ; +; 297: asm equates +C0002: ; equates() +; 298: TMP EQU $F0 + TMP EQU $F0 +; 299: TMPL EQU TMP + TMPL EQU TMP +; 300: TMPH EQU TMP+1 + TMPH EQU TMP+1 +; 301: SRC EQU TMP + SRC EQU TMP +; 302: SRCL EQU SRC + SRCL EQU SRC +; 303: SRCH EQU SRC+1 + SRCH EQU SRC+1 +; 304: DST EQU SRC+2 + DST EQU SRC+2 +; 305: DSTL EQU DST + DSTL EQU DST +; 306: DSTH EQU DST+1 + DSTH EQU DST+1 +; 307: ESP EQU DST+2 + ESP EQU DST+2 +; 308: SAVEESP EQU ESP+1 + SAVEESP EQU ESP+1 +; 309: SAVESP EQU SAVEESP+1 + SAVESP EQU SAVEESP+1 +; 310: SAVEFP EQU SAVESP+1 + SAVEFP EQU SAVESP+1 +; 311: SAVETMR EQU SAVEFP+2 + SAVETMR EQU SAVEFP+2 +; 312: SAVEINT EQU SAVETMR+2 + SAVEINT EQU SAVETMR+2 +; 313: TMRVEC EQU $03E8 + TMRVEC EQU $03E8 +; 314: INTVEC EQU $03EA + INTVEC EQU $03EA +; 315: JMPTMP: JMP (TMP) +JMPTMP: JMP (TMP) +; 316: STKOVFLW: +STKOVFLW: +; 317: LDY #$02 + LDY #$02 +; 318: JMP EXECRET + JMP EXECRET +; 319: BRKCHK: +BRKCHK: +; 320: LDA $C000 + LDA $C000 +; 321: CMP #$83 ; CTRL-C + CMP #$83 ; CTRL-C +; 322: BNE :+ + BNE :+ +; 323: BIT $C010 + BIT $C010 +; 324: LDY #$01 + LDY #$01 +; 325: JMP EXECRET + JMP EXECRET +; 326: : +: +; 327: end + RTS +; 328: ; +; 329: ; ENTER MODULE UNDER TEST +; 330: ; +; 331: asm execentry +C0004: ; execentry() +; 332: LDA ESTKL,X + LDA ESTKL,X +; 333: STA TMPL + STA TMPL +; 334: LDA ESTKH,X + LDA ESTKH,X +; 335: STA TMPH + STA TMPH +; 336: STX SAVEESP + STX SAVEESP +; 337: TSX + TSX +; 338: STX SAVESP + STX SAVESP +; 339: LDA FRMPL + LDA FRMPL +; 340: STA SAVEFP + STA SAVEFP +; 341: LDA FRMPH + LDA FRMPH +; 342: STA SAVEFP+1 + STA SAVEFP+1 +; 343: LDA TMRVEC + LDA TMRVEC +; 344: STA SAVETMR + STA SAVETMR +; 345: LDA TMRVEC+1 + LDA TMRVEC+1 +; 346: STA SAVETMR+1 + STA SAVETMR+1 +; 347: LDA INTVEC + LDA INTVEC +; 348: STA SAVEINT + STA SAVEINT +; 349: LDA INTVEC+1 + LDA INTVEC+1 +; 350: STA SAVEINT+1 + STA SAVEINT+1 +; 351: LDA #BRKCHK + LDA #>BRKCHK +; 354: STA TMRVEC+1 + STA TMRVEC+1 +; 355: LDA #STKOVFLW + LDA #>STKOVFLW +; 358: STA INTVEC+1 + STA INTVEC+1 +; 359: LDX #ESTKSZ/2 + LDX #ESTKSZ/2 +; 360: JSR JMPTMP + JSR JMPTMP +; 361: LDY #$00 + LDY #$00 +; 362: EXECRET: +EXECRET: +; 363: STY TMP + STY TMP +; 364: BIT ROMIN + BIT ROMIN +; 365: BIT $C054 + BIT $C054 +; 366: BIT $C051 + BIT $C051 +; 367: BIT $C058 + BIT $C058 +; 368: JSR $FB39 ; SET TEXT MODE + JSR $FB39 ; SET TEXT MODE +; 369: BIT LCBNK2 + BIT LCBNK2 +; 370: LDA SAVEFP + LDA SAVEFP +; 371: STA FRMPL + STA FRMPL +; 372: LDA SAVEFP+1 + LDA SAVEFP+1 +; 373: STA FRMPH + STA FRMPH +; 374: LDA SAVETMR + LDA SAVETMR +; 375: STA TMRVEC + STA TMRVEC +; 376: LDA SAVETMR+1 + LDA SAVETMR+1 +; 377: STA TMRVEC+1 + STA TMRVEC+1 +; 378: LDA SAVEINT + LDA SAVEINT +; 379: STA INTVEC + STA INTVEC +; 380: LDA SAVEINT+1 + LDA SAVEINT+1 +; 381: STA INTVEC+1 + STA INTVEC+1 +; 382: LDX SAVESP + LDX SAVESP +; 383: TXS + TXS +; 384: LDX SAVEESP + LDX SAVEESP +; 385: LDY TMP + LDY TMP +; 386: STY ESTKL,X + STY ESTKL,X +; 387: LDY #$00 + LDY #$00 +; 388: STY ESTKH,X + STY ESTKH,X +; 389: end + RTS +; 390: ; +; 391: ; CALL 6502 ROUTINE +; 392: ; ROMCALL(AREG, XREG, YREG, STATUS, ADDR) +; 393: ; +; 394: asm romcall +C0006: ; romcall() +; 395: PHP + PHP +; 396: LDA ESTKL,X + LDA ESTKL,X +; 397: STA TMPL + STA TMPL +; 398: LDA ESTKH,X + LDA ESTKH,X +; 399: STA TMPH + STA TMPH +; 400: INX + INX +; 401: LDA ESTKL,X + LDA ESTKL,X +; 402: PHA + PHA +; 403: INX + INX +; 404: LDA ESTKL,X + LDA ESTKL,X +; 405: TAY + TAY +; 406: INX + INX +; 407: LDA ESTKL+1,X + LDA ESTKL+1,X +; 408: PHA + PHA +; 409: LDA ESTKL,X + LDA ESTKL,X +; 410: INX + INX +; 411: STX ESP + STX ESP +; 412: TAX + TAX +; 413: PLA + PLA +; 414: BIT ROMIN + BIT ROMIN +; 415: PLP + PLP +; 416: JSR JMPTMP + JSR JMPTMP +; 417: PHP + PHP +; 418: BIT LCBNK2 + BIT LCBNK2 +; 419: STA REGVALS+0 + STA REGVALS+0 +; 420: STX REGVALS+1 + STX REGVALS+1 +; 421: STY REGVALS+2 + STY REGVALS+2 +; 422: PLA + PLA +; 423: STA REGVALS+3 + STA REGVALS+3 +; 424: LDX ESP + LDX ESP +; 425: LDA #REGVALS + LDY #>REGVALS +; 427: STA ESTKL,X + STA ESTKL,X +; 428: STY ESTKH,X + STY ESTKH,X +; 429: PLP + PLP +; 430: RTS + RTS +; 431: REGVALS: DS 4 +REGVALS: DS 4 +; 432: end + RTS +; 433: ; +; 434: ; BREAK INTO MONITOR +; 435: ; +; 436: asm monitor +C0008: ; monitor() +; 437: STX ESP + STX ESP +; 438: LDA #$4C + LDA #$4C +; 439: STA $03F8 + STA $03F8 +; 440: LDA #REENTER + LDA #>REENTER +; 443: STA $03FA + STA $03FA +; 444: TSX + TSX +; 445: TXA + TXA +; 446: PHA + PHA +; 447: BIT ROMIN + BIT ROMIN +; 448: JMP $FF69 + JMP $FF69 +; 449: REENTER: PLA +REENTER: PLA +; 450: TAX + TAX +; 451: TXS + TXS +; 452: LDX ESP + LDX ESP +; 453: BIT LCBNK2 + BIT LCBNK2 +; 454: end + RTS +; 455: ; +; 456: ; RETURN EVAL STACK POINTER +; 457: ; +; 458: ;asm estk +; 459: ; TXA +; 460: ; DEX +; 461: ; STA ESTKL,X +; 462: ; LDA #$00 +; 463: ; STA ESTKH,X +; 464: ;end +; 465: ; +; 466: ; ASSERT EVAL STACK POINTER VALUE +; 467: ; +; 468: ;asm assert_estk +; 469: ; INX +; 470: ; TXA +; 471: ; CMP ESTKL-1,X +; 472: ; BEQ :+ +; 473: ; BRK +; 474: ;: +; 475: ;end +; 476: ; +; 477: ; CALL PRODOS +; 478: ; SYSCALL(CMD, PARAMS) +; 479: ; +; 480: asm syscall +C0010: ; syscall() +; 481: LDA ESTKL,X + LDA ESTKL,X +; 482: LDY ESTKH,X + LDY ESTKH,X +; 483: STA PARAMS + STA PARAMS +; 484: STY PARAMS+1 + STY PARAMS+1 +; 485: INX + INX +; 486: LDA ESTKL,X + LDA ESTKL,X +; 487: STA CMD + STA CMD +; 488: STX ESP + STX ESP +; 489: BIT ROMIN + BIT ROMIN +; 490: JSR $BF00 + JSR $BF00 +; 491: CMD: DB 00 +CMD: DB 00 +; 492: PARAMS: DW 0000 +PARAMS: DW 0000 +; 493: BIT LCBNK2 + BIT LCBNK2 +; 494: LDX ESP + LDX ESP +; 495: STA ESTKL,X + STA ESTKL,X +; 496: LDY #$00 + LDY #$00 +; 497: STY ESTKH,X + STY ESTKH,X +; 498: end + RTS +; 499: ; +; 500: ; SET MEMORY TO VALUE +; 501: ; MEMSET(VALUE, ADDR, SIZE) +; 502: ; +; 503: asm memset +C0012: ; memset() +; 504: LDY #$00 + LDY #$00 +; 505: LDA ESTKL+1,X + LDA ESTKL+1,X +; 506: STA DSTL + STA DSTL +; 507: LDA ESTKH+1,X + LDA ESTKH+1,X +; 508: STA DSTH + STA DSTH +; 509: INC ESTKL,X + INC ESTKL,X +; 510: INC ESTKH,X + INC ESTKH,X +; 511: SETMEM: DEC ESTKL,X +SETMEM: DEC ESTKL,X +; 512: BNE :+ + BNE :+ +; 513: DEC ESTKH,X + DEC ESTKH,X +; 514: BEQ MEMEXIT + BEQ MEMEXIT +; 515: : LDA ESTKL+2,X +: LDA ESTKL+2,X +; 516: STA (DST),Y + STA (DST),Y +; 517: INY + INY +; 518: BNE :+ + BNE :+ +; 519: INC DSTH + INC DSTH +; 520: : DEC ESTKL,X +: DEC ESTKL,X +; 521: BNE :+ + BNE :+ +; 522: DEC ESTKH,X + DEC ESTKH,X +; 523: BEQ MEMEXIT + BEQ MEMEXIT +; 524: : LDA ESTKH+2,X +: LDA ESTKH+2,X +; 525: STA (DST),Y + STA (DST),Y +; 526: INY + INY +; 527: BNE SETMEM + BNE SETMEM +; 528: INC DSTH + INC DSTH +; 529: BNE SETMEM + BNE SETMEM +; 530: MEMEXIT: INX +MEMEXIT: INX +; 531: INX + INX +; 532: INX + INX +; 533: end + RTS +; 534: ; +; 535: ; COPY MEMORY +; 536: ; MEMCPY(SRCADDR, DSTADDR, SIZE) +; 537: ; +; 538: asm memcpy +C0014: ; memcpy() +; 539: LDY #$00 + LDY #$00 +; 540: LDA ESTKL,X + LDA ESTKL,X +; 541: BNE :+ + BNE :+ +; 542: LDA ESTKH,X + LDA ESTKH,X +; 543: BEQ MEMEXIT + BEQ MEMEXIT +; 544: : LDA ESTKL+1,X +: LDA ESTKL+1,X +; 545: STA DSTL + STA DSTL +; 546: LDA ESTKH+1,X + LDA ESTKH+1,X +; 547: STA DSTH + STA DSTH +; 548: LDA ESTKL+2,X + LDA ESTKL+2,X +; 549: STA SRCL + STA SRCL +; 550: LDA ESTKH+2,X + LDA ESTKH+2,X +; 551: STA SRCH + STA SRCH +; 552: CMP DSTH + CMP DSTH +; 553: BCC REVCPY + BCC REVCPY +; 554: BNE FORCPY + BNE FORCPY +; 555: LDA SRCL + LDA SRCL +; 556: CMP DSTL + CMP DSTL +; 557: BCS FORCPY + BCS FORCPY +; 558: REVCPY: ; REVERSE DIRECTION COPY +REVCPY: ; REVERSE DIRECTION COPY +; 559: ; CLC +; 560: LDA ESTKL,X + LDA ESTKL,X +; 561: ADC DSTL + ADC DSTL +; 562: STA DSTL + STA DSTL +; 563: LDA ESTKH,X + LDA ESTKH,X +; 564: ADC DSTH + ADC DSTH +; 565: STA DSTH + STA DSTH +; 566: CLC + CLC +; 567: LDA ESTKL,X + LDA ESTKL,X +; 568: ADC SRCL + ADC SRCL +; 569: STA SRCL + STA SRCL +; 570: LDA ESTKH,X + LDA ESTKH,X +; 571: ADC SRCH + ADC SRCH +; 572: STA SRCH + STA SRCH +; 573: INC ESTKH,X + INC ESTKH,X +; 574: REVCPYLP: +REVCPYLP: +; 575: LDA DSTL + LDA DSTL +; 576: BNE :+ + BNE :+ +; 577: DEC DSTH + DEC DSTH +; 578: : DEC DSTL +: DEC DSTL +; 579: LDA SRCL + LDA SRCL +; 580: BNE :+ + BNE :+ +; 581: DEC SRCH + DEC SRCH +; 582: : DEC SRCL +: DEC SRCL +; 583: LDA (SRC),Y + LDA (SRC),Y +; 584: STA (DST),Y + STA (DST),Y +; 585: DEC ESTKL,X + DEC ESTKL,X +; 586: BNE REVCPYLP + BNE REVCPYLP +; 587: DEC ESTKH,X + DEC ESTKH,X +; 588: BNE REVCPYLP + BNE REVCPYLP +; 589: BEQ MEMEXIT + BEQ MEMEXIT +; 590: FORCPY: INC ESTKH,X +FORCPY: INC ESTKH,X +; 591: FORCPYLP: +FORCPYLP: +; 592: LDA (SRC),Y + LDA (SRC),Y +; 593: STA (DST),Y + STA (DST),Y +; 594: INC DSTL + INC DSTL +; 595: BNE :+ + BNE :+ +; 596: INC DSTH + INC DSTH +; 597: : INC SRCL +: INC SRCL +; 598: BNE :+ + BNE :+ +; 599: INC SRCH + INC SRCH +; 600: : DEC ESTKL,X +: DEC ESTKL,X +; 601: BNE FORCPYLP + BNE FORCPYLP +; 602: DEC ESTKH,X + DEC ESTKH,X +; 603: BNE FORCPYLP + BNE FORCPYLP +; 604: BEQ MEMEXIT + BEQ MEMEXIT +; 605: end + RTS +; 606: ; +; 607: ; CHAR OUT +; 608: ; COUT(CHAR) +; 609: ; +; 610: asm cout +C0016: ; cout() +; 611: LDA ESTKL,X + LDA ESTKL,X +; 612: INX + INX +; 613: ORA #$80 + ORA #$80 +; 614: BIT ROMIN + BIT ROMIN +; 615: JSR $FDED + JSR $FDED +; 616: BIT LCBNK2 + BIT LCBNK2 +; 617: end + RTS +; 618: ; +; 619: ; CHAR IN +; 620: ; RDKEY() +; 621: ; +; 622: asm cin +C0018: ; cin() +; 623: BIT ROMIN + BIT ROMIN +; 624: STX ESP + STX ESP +; 625: JSR $FD0C + JSR $FD0C +; 626: LDX ESP + LDX ESP +; 627: BIT LCBNK2 + BIT LCBNK2 +; 628: DEX + DEX +; 629: AND #$7F + AND #$7F +; 630: STA ESTKL,X + STA ESTKL,X +; 631: LDY #$00 + LDY #$00 +; 632: STY ESTKH,X + STY ESTKH,X +; 633: end + RTS +; 634: ; +; 635: ; PRINT STRING +; 636: ; PRSTR(STR) +; 637: ; +; 638: asm prstr +C0020: ; prstr() +; 639: LDY #$00 + LDY #$00 +; 640: LDA ESTKL,X + LDA ESTKL,X +; 641: STA SRCL + STA SRCL +; 642: LDA ESTKH,X + LDA ESTKH,X +; 643: STA SRCH + STA SRCH +; 644: BIT ROMIN + BIT ROMIN +; 645: LDA (SRC),Y + LDA (SRC),Y +; 646: STA ESTKL,X + STA ESTKL,X +; 647: BEQ :+ + BEQ :+ +; 648: _PRS1: INY +_PRS1: INY +; 649: LDA (SRC),Y + LDA (SRC),Y +; 650: ORA #$80 + ORA #$80 +; 651: JSR $FDED + JSR $FDED +; 652: TYA + TYA +; 653: CMP ESTKL,X + CMP ESTKL,X +; 654: BNE _PRS1 + BNE _PRS1 +; 655: : INX +: INX +; 656: BIT LCBNK2 + BIT LCBNK2 +; 657: end + RTS +; 658: ; +; 659: ; READ STRING +; 660: ; STR = RDSTR(PROMPTCHAR) +; 661: ; +; 662: asm rdstr +C0022: ; rdstr() +; 663: LDA ESTKL,X + LDA ESTKL,X +; 664: STA $33 + STA $33 +; 665: STX ESP + STX ESP +; 666: BIT ROMIN + BIT ROMIN +; 667: JSR $FD6A + JSR $FD6A +; 668: BIT LCBNK2 + BIT LCBNK2 +; 669: STX $01FF + STX $01FF +; 670: : LDA $01FF,X +: LDA $01FF,X +; 671: AND #$7F + AND #$7F +; 672: STA $01FF,X + STA $01FF,X +; 673: DEX + DEX +; 674: BPL :- + BPL :- +; 675: LDX ESP + LDX ESP +; 676: LDA #$FF + LDA #$FF +; 677: STA ESTKL,X + STA ESTKL,X +; 678: LDA #$01 + LDA #$01 +; 679: STA ESTKH,X + STA ESTKH,X +; 680: end + RTS +; 681: ;def toupper_11(c) +; 682: ; if c >= 'a' +; 683: ; if c <= 'z' +; 684: ; return c - $20 +; 685: ; fin +; 686: ; fin +; 687: ; return c +; 688: ;end +; 689: asm toupper_11 +C0024: ; toupper_11() +; 690: LDA ESTKL,X + LDA ESTKL,X +; 691: CMP #'a' + CMP #'a' +; 692: BCC :+ + BCC :+ +; 693: CMP #'z'+1 + CMP #'z'+1 +; 694: BCS :+ + BCS :+ +; 695: SEC + SEC +; 696: SBC #$20 + SBC #$20 +; 697: STA ESTKL,X + STA ESTKL,X +; 698: : +: +; 699: end + RTS +; 700: ; +; 701: ; EXIT +; 702: ; +; 703: asm exit +C0026: ; exit() +; 704: JSR $BF00 + JSR $BF00 +; 705: DB $65 + DB $65 +; 706: DW EXITTBL + DW EXITTBL +; 707: EXITTBL: +EXITTBL: +; 708: DB 4 + DB 4 +; 709: DB 0 + DB 0 +; 710: end + RTS +; 711: ; +; 712: ; ProDOS routines +; 713: ; +; 714: def getpfx_11(path) +C0028: ; getpfx_11() + ; path = 2 +; 715: byte params[3] + ; params = 4 +; 716: +; 717: ^path = 0 + JSR INTERP + DB $58,$07,$01 ; ENTER 7,1 + DB $66,$02 ; LLW 2 + DB $00 ; ZERO + DB $70 ; SB +; 718: params.0 = 1 + DB $28,$04 ; LLA 4 + DB $2A,$01 ; CB 1 + DB $70 ; SB +; 719: params:1 = path + DB $28,$05 ; LLA 5 + DB $66,$02 ; LLW 2 + DB $72 ; SW +; 720: perr = syscall($C7, @params) + DB $2A,$C7 ; CB 199 + DB $28,$04 ; LLA 4 + DB $54,C0010 ; CALL C0010 + DB $78,D0019 ; SAB D0019 +; 721: return path + DB $66,$02 ; LLW 2 + DB $5A ; LEAVE +; 722: end +; 723: def setpfx_11(path) +C0030: ; setpfx_11() + ; path = 2 +; 724: byte params[3] + ; params = 4 +; 725: +; 726: params.0 = 1 + JSR INTERP + DB $58,$07,$01 ; ENTER 7,1 + DB $28,$04 ; LLA 4 + DB $2A,$01 ; CB 1 + DB $70 ; SB +; 727: params:1 = path + DB $28,$05 ; LLA 5 + DB $66,$02 ; LLW 2 + DB $72 ; SW +; 728: perr = syscall($C6, @params) + DB $2A,$C6 ; CB 198 + DB $28,$04 ; LLA 4 + DB $54,C0010 ; CALL C0010 + DB $78,D0019 ; SAB D0019 +; 729: return path + DB $66,$02 ; LLW 2 + DB $5A ; LEAVE +; 730: end +; 731: def open_21(path, buff) +C0032: ; open_21() + ; path = 2 + ; buff = 4 +; 732: byte params[6] + ; params = 6 +; 733: +; 734: params.0 = 3 + JSR INTERP + DB $58,$0C,$02 ; ENTER 12,2 + DB $28,$06 ; LLA 6 + DB $2A,$03 ; CB 3 + DB $70 ; SB +; 735: params:1 = path + DB $28,$07 ; LLA 7 + DB $66,$02 ; LLW 2 + DB $72 ; SW +; 736: params:3 = buff + DB $28,$09 ; LLA 9 + DB $66,$04 ; LLW 4 + DB $72 ; SW +; 737: params.5 = 0 + DB $28,$0B ; LLA 11 + DB $00 ; ZERO + DB $70 ; SB +; 738: perr = syscall($C8, @params) + DB $2A,$C8 ; CB 200 + DB $28,$06 ; LLA 6 + DB $54,C0010 ; CALL C0010 + DB $78,D0019 ; SAB D0019 +; 739: return params.5 + DB $28,$0B ; LLA 11 + DB $60 ; LB + DB $5A ; LEAVE +; 740: end +; 741: def close_11(refnum) +C0034: ; close_11() + ; refnum = 2 +; 742: byte params[2] + ; params = 4 +; 743: +; 744: params.0 = 1 + JSR INTERP + DB $58,$06,$01 ; ENTER 6,1 + DB $28,$04 ; LLA 4 + DB $2A,$01 ; CB 1 + DB $70 ; SB +; 745: params.1 = refnum + DB $28,$05 ; LLA 5 + DB $66,$02 ; LLW 2 + DB $70 ; SB +; 746: perr = syscall($CC, @params) + DB $2A,$CC ; CB 204 + DB $28,$04 ; LLA 4 + DB $54,C0010 ; CALL C0010 + DB $78,D0019 ; SAB D0019 +; 747: return perr + DB $68,D0019 ; LAB D0019 + DB $5A ; LEAVE +; 748: end +; 749: def read_31(refnum, buff, len) +C0036: ; read_31() + ; refnum = 2 + ; buff = 4 + ; len = 6 +; 750: byte params[8] + ; params = 8 +; 751: +; 752: params.0 = 4 + JSR INTERP + DB $58,$10,$03 ; ENTER 16,3 + DB $28,$08 ; LLA 8 + DB $2A,$04 ; CB 4 + DB $70 ; SB +; 753: params.1 = refnum + DB $28,$09 ; LLA 9 + DB $66,$02 ; LLW 2 + DB $70 ; SB +; 754: params:2 = buff + DB $28,$0A ; LLA 10 + DB $66,$04 ; LLW 4 + DB $72 ; SW +; 755: params:4 = len + DB $28,$0C ; LLA 12 + DB $66,$06 ; LLW 6 + DB $72 ; SW +; 756: params:6 = 0 + DB $28,$0E ; LLA 14 + DB $00 ; ZERO + DB $72 ; SW +; 757: perr = syscall($CA, @params) + DB $2A,$CA ; CB 202 + DB $28,$08 ; LLA 8 + DB $54,C0010 ; CALL C0010 + DB $78,D0019 ; SAB D0019 +; 758: return params:6 + DB $28,$0E ; LLA 14 + DB $62 ; LW + DB $5A ; LEAVE +; 759: end +; 760: def write_31(refnum, buff, len) +C0038: ; write_31() + ; refnum = 2 + ; buff = 4 + ; len = 6 +; 761: byte params[8] + ; params = 8 +; 762: +; 763: params.0 = 4 + JSR INTERP + DB $58,$10,$03 ; ENTER 16,3 + DB $28,$08 ; LLA 8 + DB $2A,$04 ; CB 4 + DB $70 ; SB +; 764: params.1 = refnum + DB $28,$09 ; LLA 9 + DB $66,$02 ; LLW 2 + DB $70 ; SB +; 765: params:2 = buff + DB $28,$0A ; LLA 10 + DB $66,$04 ; LLW 4 + DB $72 ; SW +; 766: params:4 = len + DB $28,$0C ; LLA 12 + DB $66,$06 ; LLW 6 + DB $72 ; SW +; 767: params:6 = 0 + DB $28,$0E ; LLA 14 + DB $00 ; ZERO + DB $72 ; SW +; 768: perr = syscall($CB, @params) + DB $2A,$CB ; CB 203 + DB $28,$08 ; LLA 8 + DB $54,C0010 ; CALL C0010 + DB $78,D0019 ; SAB D0019 +; 769: return params:6 + DB $28,$0E ; LLA 14 + DB $62 ; LW + DB $5A ; LEAVE +; 770: end +; 771: def create_41(path, access, type, aux) +C0040: ; create_41() + ; path = 2 + ; access = 4 + ; type = 6 + ; aux = 8 +; 772: byte params[12] + ; params = 10 +; 773: +; 774: params.0 = 7 + JSR INTERP + DB $58,$16,$04 ; ENTER 22,4 + DB $28,$0A ; LLA 10 + DB $2A,$07 ; CB 7 + DB $70 ; SB +; 775: params:1 = path + DB $28,$0B ; LLA 11 + DB $66,$02 ; LLW 2 + DB $72 ; SW +; 776: params.3 = access + DB $28,$0D ; LLA 13 + DB $66,$04 ; LLW 4 + DB $70 ; SB +; 777: params.4 = type + DB $28,$0E ; LLA 14 + DB $66,$06 ; LLW 6 + DB $70 ; SB +; 778: params:5 = aux + DB $28,$0F ; LLA 15 + DB $66,$08 ; LLW 8 + DB $72 ; SW +; 779: params.7 = $1 + DB $28,$11 ; LLA 17 + DB $2A,$01 ; CB 1 + DB $70 ; SB +; 780: params:8 = 0 + DB $28,$12 ; LLA 18 + DB $00 ; ZERO + DB $72 ; SW +; 781: params:10 = 0 + DB $28,$14 ; LLA 20 + DB $00 ; ZERO + DB $72 ; SW +; 782: perr = syscall($C0, @params) + DB $2A,$C0 ; CB 192 + DB $28,$0A ; LLA 10 + DB $54,C0010 ; CALL C0010 + DB $78,D0019 ; SAB D0019 +; 783: return perr + DB $68,D0019 ; LAB D0019 + DB $5A ; LEAVE +; 784: end +; 785: def destroy_11(path) +C0042: ; destroy_11() + ; path = 2 +; 786: byte params[12] + ; params = 4 +; 787: +; 788: params.0 = 1 + JSR INTERP + DB $58,$10,$01 ; ENTER 16,1 + DB $28,$04 ; LLA 4 + DB $2A,$01 ; CB 1 + DB $70 ; SB +; 789: params:1 = path + DB $28,$05 ; LLA 5 + DB $66,$02 ; LLW 2 + DB $72 ; SW +; 790: perr = syscall($C1, @params) + DB $2A,$C1 ; CB 193 + DB $28,$04 ; LLA 4 + DB $54,C0010 ; CALL C0010 + DB $78,D0019 ; SAB D0019 +; 791: return perr + DB $68,D0019 ; LAB D0019 + DB $5A ; LEAVE +; 792: end +; 793: def newline_31(refnum, emask, nlchar) +C0044: ; newline_31() + ; refnum = 2 + ; emask = 4 + ; nlchar = 6 +; 794: byte params[4] + ; params = 8 +; 795: +; 796: params.0 = 3 + JSR INTERP + DB $58,$0C,$03 ; ENTER 12,3 + DB $28,$08 ; LLA 8 + DB $2A,$03 ; CB 3 + DB $70 ; SB +; 797: params.1 = refnum + DB $28,$09 ; LLA 9 + DB $66,$02 ; LLW 2 + DB $70 ; SB +; 798: params.2 = emask + DB $28,$0A ; LLA 10 + DB $66,$04 ; LLW 4 + DB $70 ; SB +; 799: params.3 = nlchar + DB $28,$0B ; LLA 11 + DB $66,$06 ; LLW 6 + DB $70 ; SB +; 800: perr = syscall($C9, @params) + DB $2A,$C9 ; CB 201 + DB $28,$08 ; LLA 8 + DB $54,C0010 ; CALL C0010 + DB $78,D0019 ; SAB D0019 +; 801: return perr + DB $68,D0019 ; LAB D0019 + DB $5A ; LEAVE +; 802: end +; 803: def crout +C0046: ; crout() +; 804: cout($0D) + JSR INTERP + DB $2A,$0D ; CB 13 + DB $54,C0016 ; CALL C0016 +; 805: end + DB $5C ; RET +; 806: def prbyte_10(h) +C0048: ; prbyte_10() + ; h = 2 +; 807: cout('$') + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$24 ; CB 36 + DB $54,C0016 ; CALL C0016 +; 808: drop romcall(h, 0, 0, 0, $FDDA) + DB $66,$02 ; LLW 2 + DB $00 ; ZERO + DB $00 ; ZERO + DB $00 ; ZERO + DB $2C,$DA,$FD ; CW 64986 + DB $54,C0006 ; CALL C0006 + DB $30 ; DROP +; 809: end + DB $5A ; LEAVE +; 810: def prword_10(h) +C0050: ; prword_10() + ; h = 2 +; 811: cout('$') + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$24 ; CB 36 + DB $54,C0016 ; CALL C0016 +; 812: drop romcall(h >> 8, h, 0, 0, $F941) + DB $66,$02 ; LLW 2 + DB $2A,$08 ; CB 8 + DB $1C ; SHR + DB $66,$02 ; LLW 2 + DB $00 ; ZERO + DB $00 ; ZERO + DB $2C,$41,$F9 ; CW 63809 + DB $54,C0006 ; CALL C0006 + DB $30 ; DROP +; 813: end + DB $5A ; LEAVE +; 814: def print_10(i) +C0052: ; print_10() + ; i = 2 +; 815: byte numstr[7] + ; numstr = 4 +; 816: byte place, sign + ; place = 11 + ; sign = 12 +; 817: +; 818: place = 6 + JSR INTERP + DB $58,$0D,$01 ; ENTER 13,1 + DB $2A,$06 ; CB 6 + DB $74,$0B ; SLB 11 +; 819: if i < 0 + DB $66,$02 ; LLW 2 + DB $00 ; ZERO + DB $46 ; ISLT + DB $4C,C0054 ; SKPFLS C0054 +; 820: sign = 1 + DB $2A,$01 ; CB 1 + DB $74,$0C ; SLB 12 +; 821: i = -i + DB $66,$02 ; LLW 2 + DB $10 ; NEG + DB $76,$02 ; SLW 2 +; 822: else + DB $50,C0055 ; SKIP C0055 +C0054: +; 823: sign = 0 + DB $00 ; ZERO + DB $74,$0C ; SLB 12 +; 824: fin +C0055: +; 825: while i >= 10 +C0056: + DB $66,$02 ; LLW 2 + DB $2A,$0A ; CB 10 + DB $48 ; ISGE + DB $4C,C0057 ; SKPFLS C0057 +; 826: i =, numstr[place] = i % 10 + '0' + DB $28,$04 ; LLA 4 + DB $64,$0B ; LLB 11 + DB $02 ; IDXB + DB $34 ; PUSH + DB $66,$02 ; LLW 2 + DB $2A,$0A ; CB 10 + DB $0A ; DIV,MOD + DB $2A,$30 ; CB 48 + DB $02 ; ADD + DB $36 ; PULL + DB $2E ; SWAP + DB $70 ; SB + DB $76,$02 ; SLW 2 +; 827: place = place - 1 + DB $64,$0B ; LLB 11 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $74,$0B ; SLB 11 +; 828: loop + DB $50,C0056 ; SKIP C0056 +C0057: +; 829: numstr[place] = i + '0' + DB $28,$04 ; LLA 4 + DB $64,$0B ; LLB 11 + DB $02 ; IDXB + DB $66,$02 ; LLW 2 + DB $2A,$30 ; CB 48 + DB $02 ; ADD + DB $70 ; SB +; 830: place = place - 1 + DB $64,$0B ; LLB 11 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $74,$0B ; SLB 11 +; 831: if sign + DB $64,$0C ; LLB 12 + DB $4C,C0058 ; SKPFLS C0058 +; 832: numstr[place] = '-' + DB $28,$04 ; LLA 4 + DB $64,$0B ; LLB 11 + DB $02 ; IDXB + DB $2A,$2D ; CB 45 + DB $70 ; SB +; 833: place = place - 1 + DB $64,$0B ; LLB 11 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $74,$0B ; SLB 11 +; 834: fin +C0058: +C0059: +; 835: numstr[place] = 6 - place + DB $28,$04 ; LLA 4 + DB $64,$0B ; LLB 11 + DB $02 ; IDXB + DB $2A,$06 ; CB 6 + DB $64,$0B ; LLB 11 + DB $04 ; SUB + DB $70 ; SB +; 836: prstr(@numstr[place]) + DB $28,$04 ; LLA 4 + DB $64,$0B ; LLB 11 + DB $02 ; IDXB + DB $54,C0020 ; CALL C0020 +; 837: end + DB $5A ; LEAVE +; 838: def nametostr_30(namestr, len, strptr) +C0060: ; nametostr_30() + ; namestr = 2 + ; len = 4 + ; strptr = 6 +; 839: ^strptr = len + JSR INTERP + DB $58,$08,$03 ; ENTER 8,3 + DB $66,$06 ; LLW 6 + DB $66,$04 ; LLW 4 + DB $70 ; SB +; 840: memcpy(namestr, strptr + 1, len) + DB $66,$02 ; LLW 2 + DB $66,$06 ; LLW 6 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $66,$04 ; LLW 4 + DB $54,C0014 ; CALL C0014 +; 841: end + DB $5A ; LEAVE +; 842: +; 843: ;===================================== +; 844: ; +; 845: ; PLASMA Compiler +; 846: ; +; 847: ;===================================== +; 848: +; 849: ; +; 850: ; Error handler +; 851: ; +; 852: def parse_err_11(err) +C0062: ; parse_err_11() + ; err = 2 +; 853: word i + ; i = 4 +; 854: +; 855: drop close_11(0) + JSR INTERP + DB $58,$06,$01 ; ENTER 6,1 + DB $00 ; ZERO + DB $54,C0034 ; CALL C0034 + DB $30 ; DROP +; 856: crout() + DB $54,C0046 ; CALL C0046 +; 857: print_10(lineno) + DB $6A,D0421 ; LAW D0421 + DB $54,C0052 ; CALL C0052 +; 858: cout(':') + DB $2A,$3A ; CB 58 + DB $54,C0016 ; CALL C0016 +; 859: prstr(err) + DB $66,$02 ; LLW 2 + DB $54,C0020 ; CALL C0020 +; 860: crout() + DB $54,C0046 ; CALL C0046 +; 861: prstr(instr) + DB $2C,$FF,$01 ; CW 511 + DB $54,C0020 ; CALL C0020 +; 862: crout() + DB $54,C0046 ; CALL C0046 +; 863: for i = inbuff to tknptr - 1 + DB $2C,$00,$02 ; CW 512 +C0065: + DB $6E,$04 ; DLW 4 + DB $6A,D0417 ; LAW D0417 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $3A,C0064 ; SKPGT C0064 + DB $0C ; INCR +; 864: cout(' ') + DB $2A,$20 ; CB 32 + DB $54,C0016 ; CALL C0016 +; 865: next + DB $50,C0065 ; SKIP C0065 +C0064: + DB $30 ; DROP +; 866: cout('^') + DB $2A,$5E ; CB 94 + DB $54,C0016 ; CALL C0016 +; 867: cin() + DB $54,C0018 ; CALL C0018 +; 868: exit() + DB $54,C0026 ; CALL C0026 +; 869: return ERR_TKN + DB $00 ; ZERO + DB $5A ; LEAVE +; 870: end +; 871: ; +; 872: ; Emit bytecode +; 873: ; +; 874: def ctag_new_01 +C0066: ; ctag_new_01() +; 875: if codetag >= ctag_max + JSR INTERP + DB $6A,D0012 ; LAW D0012 + DB $2C,$00,$03 ; CW 768 + DB $48 ; ISGE + DB $4C,C0068 ; SKPFLS C0068 +; 876: return parse_err_11(@ctag_full) + DB $26,D0693 ; LA D0693 + DB $54,C0062 ; CALL C0062 + DB $5C ; RET +; 877: fin +C0068: +C0069: +; 878: codetag = codetag + 1 + DB $6A,D0012 ; LAW D0012 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $7A,D0012 ; SAW D0012 +; 879: ctag_value:[codetag] = 0 + DB $2C,$00,$1A ; CW 6656 + DB $6A,D0012 ; LAW D0012 + DB $1E ; IDXW + DB $00 ; ZERO + DB $72 ; SW +; 880: ctag_flags.[codetag] = 0 + DB $2C,$00,$0D ; CW 3328 + DB $6A,D0012 ; LAW D0012 + DB $02 ; IDXB + DB $00 ; ZERO + DB $70 ; SB +; 881: return codetag ? is_ctag + DB $6A,D0012 ; LAW D0012 + DB $2C,$00,$80 ; CW 32768 + DB $16 ; IOR + DB $5C ; RET +; 882: end +; 883: defopt ctag_resolve_21(tag, addr) +C0070: ; ctag_resolve_21() + ; tag = 2 + ; addr = 4 +; 884: word updtptr, nextptr + ; updtptr = 6 + ; nextptr = 8 +; 885: +; 886: tag = tag & mask_ctag + LDY #10 + LDA #2 + JSR ENTER + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$FF + STA ESTKL,X + LDA #$7F + STA ESTKH,X + JSR BAND + LDY #$02 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 887: if ctag_flags.[tag] & resolved + LDY #$00 + STY ESTKL,X + LDA #$0D + STA ESTKH,X + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JSR ADD + LDY #$00 + JSR LB + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR BAND + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0072 +: +; 888: return parse_err_11(@dup_id) + DEX + LDA #D0431 + STA ESTKH,X + JSR C0062 + JMP LEAVE +; 889: fin +C0072: +C0073: +; 890: updtptr = ctag_value:[tag] + DEX + LDY #$00 + STY ESTKL,X + LDA #$1A + STA ESTKH,X + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JSR IDXW + LDY #$00 + JSR LW + LDY #$06 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 891: while updtptr + INX +C0074: + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0075 +: +; 892: ; +; 893: ; Update list of addresses needing resolution +; 894: ; +; 895: nextptr = *updtptr + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR LW + LDY #$08 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 896: *updtptr = addr + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR SW +; 897: updtptr = nextptr + DEX + LDY #$08 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$06 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 898: loop + INX + JMP C0074 +C0075: +; 899: ctag_value:[tag] = addr + DEX + LDY #$00 + STY ESTKL,X + LDA #$1A + STA ESTKH,X + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JSR IDXW + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR SW +; 900: ctag_flags.[tag] = ctag_flags.[tag] ? resolved + DEX + LDY #$00 + STY ESTKL,X + LDA #$0D + STA ESTKH,X + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JSR ADD + DEX + LDY #$00 + STY ESTKL,X + LDA #$0D + STA ESTKH,X + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JSR ADD + LDY #$00 + JSR LB + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR IOR + JSR SB +; 901: return 0 + DEX + STY ESTKL,X + STY ESTKH,X + JMP LEAVE +; 902: end +; 903: defopt emit_byte_10(bval) +C0076: ; emit_byte_10() + ; bval = 2 +; 904: ^codeptr = bval + LDY #4 + LDA #1 + JSR ENTER + DEX + LDA D0014 + STA ESTKL,X + LDA D0014+1 + STA ESTKH,X + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR SB +; 905: codeptr = codeptr + 1 + DEX + LDA D0014 + STA ESTKL,X + LDA D0014+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0014 + LDA ESTKH,X + STA D0014+1 +; 906: end + INX + JMP LEAVE +; 907: defopt emit_word_10(wval) +C0078: ; emit_word_10() + ; wval = 2 +; 908: *codeptr = wval + LDY #4 + LDA #1 + JSR ENTER + DEX + LDA D0014 + STA ESTKL,X + LDA D0014+1 + STA ESTKH,X + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR SW +; 909: codeptr = codeptr + 2 + DEX + LDA D0014 + STA ESTKL,X + LDA D0014+1 + STA ESTKH,X + DEX + LDA #$02 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0014 + LDA ESTKH,X + STA D0014+1 +; 910: end + INX + JMP LEAVE +; 911: def emit_fill_10(size) +C0080: ; emit_fill_10() + ; size = 2 +; 912: memset(0, codeptr, size) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $00 ; ZERO + DB $6A,D0014 ; LAW D0014 + DB $66,$02 ; LLW 2 + DB $54,C0012 ; CALL C0012 +; 913: codeptr = codeptr + size + DB $6A,D0014 ; LAW D0014 + DB $66,$02 ; LLW 2 + DB $02 ; ADD + DB $7A,D0014 ; SAW D0014 +; 914: end + DB $5A ; LEAVE +; 915: def emit_codetag_10(tag) +C0082: ; emit_codetag_10() + ; tag = 2 +; 916: drop ctag_resolve_21(tag, codeptr) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $66,$02 ; LLW 2 + DB $6A,D0014 ; LAW D0014 + DB $54,C0070 ; CALL C0070 + DB $30 ; DROP +; 917: end + DB $5A ; LEAVE +; 918: defopt emit_op_10(op) +C0084: ; emit_op_10() + ; op = 2 +; 919: lastop = op + LDY #4 + LDA #1 + JSR ENTER + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDA ESTKL,X + STA D0018 +; 920: ^codeptr = op + LDA D0014 + STA ESTKL,X + LDA D0014+1 + STA ESTKH,X + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR SB +; 921: codeptr = codeptr + 1 + DEX + LDA D0014 + STA ESTKL,X + LDA D0014+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0014 + LDA ESTKH,X + STA D0014+1 +; 922: end + INX + JMP LEAVE +; 923: def emit_tag_10(tag) +C0086: ; emit_tag_10() + ; tag = 2 +; 924: word updtptr + ; updtptr = 4 +; 925: +; 926: if tag & is_ctag + JSR INTERP + DB $58,$06,$01 ; ENTER 6,1 + DB $66,$02 ; LLW 2 + DB $2C,$00,$80 ; CW 32768 + DB $14 ; BAND + DB $4C,C0088 ; SKPFLS C0088 +; 927: tag = tag & mask_ctag + DB $66,$02 ; LLW 2 + DB $2C,$FF,$7F ; CW 32767 + DB $14 ; BAND + DB $76,$02 ; SLW 2 +; 928: updtptr = ctag_value:[tag] + DB $2C,$00,$1A ; CW 6656 + DB $66,$02 ; LLW 2 + DB $1E ; IDXW + DB $62 ; LW + DB $76,$04 ; SLW 4 +; 929: if !(ctag_flags.[tag] & resolved) + DB $2C,$00,$0D ; CW 3328 + DB $66,$02 ; LLW 2 + DB $02 ; IDXB + DB $60 ; LB + DB $2A,$01 ; CB 1 + DB $14 ; BAND + DB $20 ; NOT + DB $4C,C0090 ; SKPFLS C0090 +; 930: ; +; 931: ; Add to list of tags needing resolution +; 932: ; +; 933: ctag_value:[tag] = codeptr + DB $2C,$00,$1A ; CW 6656 + DB $66,$02 ; LLW 2 + DB $1E ; IDXW + DB $6A,D0014 ; LAW D0014 + DB $72 ; SW +; 934: fin +C0090: +C0091: +; 935: emit_word_10(updtptr) + DB $66,$04 ; LLW 4 + DB $54,C0078 ; CALL C0078 +; 936: else + DB $50,C0089 ; SKIP C0089 +C0088: +; 937: emit_word_10(tag + codebuff) + DB $66,$02 ; LLW 2 + DB $2C,$00,$60 ; CW 24576 + DB $02 ; ADD + DB $54,C0078 ; CALL C0078 +; 938: fin +C0089: +; 939: end + DB $5A ; LEAVE +; 940: def emit_iddata_30(value, size, namestr) +C0092: ; emit_iddata_30() + ; value = 2 + ; size = 4 + ; namestr = 6 +; 941: emit_fill_10(size) + JSR INTERP + DB $58,$08,$03 ; ENTER 8,3 + DB $66,$04 ; LLW 4 + DB $54,C0080 ; CALL C0080 +; 942: end + DB $5A ; LEAVE +; 943: def emit_data_41(vartype, consttype, constval, constsize) +C0094: ; emit_data_41() + ; vartype = 2 + ; consttype = 4 + ; constval = 6 + ; constsize = 8 +; 944: byte i + ; i = 10 +; 945: word size, chrptr + ; size = 11 + ; chrptr = 13 +; 946: +; 947: if consttype == 0 + JSR INTERP + DB $58,$0F,$04 ; ENTER 15,4 + DB $66,$04 ; LLW 4 + DB $00 ; ZERO + DB $40 ; ISEQ + DB $4C,C0096 ; SKPFLS C0096 +; 948: size = constsize + DB $66,$08 ; LLW 8 + DB $76,$0B ; SLW 11 +; 949: emit_fill_10(constsize) + DB $66,$08 ; LLW 8 + DB $54,C0080 ; CALL C0080 +; 950: elsif consttype == STR_TYPE + DB $50,C0097 ; SKIP C0097 +C0096: + DB $66,$04 ; LLW 4 + DB $2A,$80 ; CB 128 + DB $40 ; ISEQ + DB $4C,C0098 ; SKPFLS C0098 +; 951: size = constsize + DB $66,$08 ; LLW 8 + DB $76,$0B ; SLW 11 +; 952: chrptr = constval + DB $66,$06 ; LLW 6 + DB $76,$0D ; SLW 13 +; 953: constsize = constsize - 1 + DB $66,$08 ; LLW 8 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $76,$08 ; SLW 8 +; 954: emit_byte_10(constsize) + DB $66,$08 ; LLW 8 + DB $54,C0076 ; CALL C0076 +; 955: while constsize > 0 +C0099: + DB $66,$08 ; LLW 8 + DB $00 ; ZERO + DB $44 ; ISGT + DB $4C,C0100 ; SKPFLS C0100 +; 956: emit_byte_10(^chrptr) + DB $66,$0D ; LLW 13 + DB $60 ; LB + DB $54,C0076 ; CALL C0076 +; 957: chrptr = chrptr + 1 + DB $66,$0D ; LLW 13 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $76,$0D ; SLW 13 +; 958: constsize = constsize - 1 + DB $66,$08 ; LLW 8 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $76,$08 ; SLW 8 +; 959: loop + DB $50,C0099 ; SKIP C0099 +C0100: +; 960: else + DB $50,C0097 ; SKIP C0097 +C0098: +; 961: if vartype == WORD_TYPE + DB $66,$02 ; LLW 2 + DB $2A,$04 ; CB 4 + DB $40 ; ISEQ + DB $4C,C0101 ; SKPFLS C0101 +; 962: size = 2 + DB $2A,$02 ; CB 2 + DB $76,$0B ; SLW 11 +; 963: emit_word_10(constval) + DB $66,$06 ; LLW 6 + DB $54,C0078 ; CALL C0078 +; 964: else + DB $50,C0102 ; SKIP C0102 +C0101: +; 965: size = 1 + DB $2A,$01 ; CB 1 + DB $76,$0B ; SLW 11 +; 966: emit_byte_10(constval) + DB $66,$06 ; LLW 6 + DB $54,C0076 ; CALL C0076 +; 967: fin +C0102: +; 968: fin +C0097: +; 969: return size + DB $66,$0B ; LLW 11 + DB $5A ; LEAVE +; 970: end +; 971: def emit_const_10(cval) +C0103: ; emit_const_10() + ; cval = 2 +; 972: if cval == 0 + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $66,$02 ; LLW 2 + DB $00 ; ZERO + DB $40 ; ISEQ + DB $4C,C0105 ; SKPFLS C0105 +; 973: emit_op_10($00) + DB $00 ; ZERO + DB $54,C0084 ; CALL C0084 +; 974: elsif cval > 0 and cval < 256 + DB $50,C0106 ; SKIP C0106 +C0105: + DB $66,$02 ; LLW 2 + DB $00 ; ZERO + DB $44 ; ISGT + DB $66,$02 ; LLW 2 + DB $2C,$00,$01 ; CW 256 + DB $46 ; ISLT + DB $24 ; LAND + DB $4C,C0107 ; SKPFLS C0107 +; 975: emit_op_10($2A) + DB $2A,$2A ; CB 42 + DB $54,C0084 ; CALL C0084 +; 976: emit_byte_10(cval) + DB $66,$02 ; LLW 2 + DB $54,C0076 ; CALL C0076 +; 977: else + DB $50,C0106 ; SKIP C0106 +C0107: +; 978: emit_op_10($2C) + DB $2A,$2C ; CB 44 + DB $54,C0084 ; CALL C0084 +; 979: emit_word_10(cval) + DB $66,$02 ; LLW 2 + DB $54,C0078 ; CALL C0078 +; 980: fin +C0106: +; 981: end + DB $5A ; LEAVE +; 982: def emit_lb +C0108: ; emit_lb() +; 983: emit_op_10($60) + JSR INTERP + DB $2A,$60 ; CB 96 + DB $54,C0084 ; CALL C0084 +; 984: end + DB $5C ; RET +; 985: def emit_lw +C0110: ; emit_lw() +; 986: emit_op_10($62) + JSR INTERP + DB $2A,$62 ; CB 98 + DB $54,C0084 ; CALL C0084 +; 987: end + DB $5C ; RET +; 988: def emit_llb_10(index) +C0112: ; emit_llb_10() + ; index = 2 +; 989: emit_op_10($64) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$64 ; CB 100 + DB $54,C0084 ; CALL C0084 +; 990: emit_byte_10(index) + DB $66,$02 ; LLW 2 + DB $54,C0076 ; CALL C0076 +; 991: end + DB $5A ; LEAVE +; 992: def emit_llw_10(index) +C0114: ; emit_llw_10() + ; index = 2 +; 993: emit_op_10($66) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$66 ; CB 102 + DB $54,C0084 ; CALL C0084 +; 994: emit_byte_10(index) + DB $66,$02 ; LLW 2 + DB $54,C0076 ; CALL C0076 +; 995: end + DB $5A ; LEAVE +; 996: def emit_lab_10(tag) +C0116: ; emit_lab_10() + ; tag = 2 +; 997: emit_op_10($68) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$68 ; CB 104 + DB $54,C0084 ; CALL C0084 +; 998: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0086 ; CALL C0086 +; 999: end + DB $5A ; LEAVE +; 1000: def emit_law_10(tag) +C0118: ; emit_law_10() + ; tag = 2 +; 1001: emit_op_10($6A) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$6A ; CB 106 + DB $54,C0084 ; CALL C0084 +; 1002: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0086 ; CALL C0086 +; 1003: end + DB $5A ; LEAVE +; 1004: def emit_sb +C0120: ; emit_sb() +; 1005: emit_op_10($70) + JSR INTERP + DB $2A,$70 ; CB 112 + DB $54,C0084 ; CALL C0084 +; 1006: end + DB $5C ; RET +; 1007: def emit_sw +C0122: ; emit_sw() +; 1008: emit_op_10($72) + JSR INTERP + DB $2A,$72 ; CB 114 + DB $54,C0084 ; CALL C0084 +; 1009: end + DB $5C ; RET +; 1010: def emit_slb_10(index) +C0124: ; emit_slb_10() + ; index = 2 +; 1011: emit_op_10($74) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$74 ; CB 116 + DB $54,C0084 ; CALL C0084 +; 1012: emit_byte_10(index) + DB $66,$02 ; LLW 2 + DB $54,C0076 ; CALL C0076 +; 1013: end + DB $5A ; LEAVE +; 1014: def emit_slw_10(index) +C0126: ; emit_slw_10() + ; index = 2 +; 1015: emit_op_10($76) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$76 ; CB 118 + DB $54,C0084 ; CALL C0084 +; 1016: emit_byte_10(index) + DB $66,$02 ; LLW 2 + DB $54,C0076 ; CALL C0076 +; 1017: end + DB $5A ; LEAVE +; 1018: def emit_dlb_10(index) +C0128: ; emit_dlb_10() + ; index = 2 +; 1019: emit_op_10($6C) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$6C ; CB 108 + DB $54,C0084 ; CALL C0084 +; 1020: emit_byte_10(index) + DB $66,$02 ; LLW 2 + DB $54,C0076 ; CALL C0076 +; 1021: end + DB $5A ; LEAVE +; 1022: def emit_dlw_10(index) +C0130: ; emit_dlw_10() + ; index = 2 +; 1023: emit_op_10($6E) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$6E ; CB 110 + DB $54,C0084 ; CALL C0084 +; 1024: emit_byte_10(index) + DB $66,$02 ; LLW 2 + DB $54,C0076 ; CALL C0076 +; 1025: end + DB $5A ; LEAVE +; 1026: def emit_sab_10(tag) +C0132: ; emit_sab_10() + ; tag = 2 +; 1027: emit_op_10($78) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$78 ; CB 120 + DB $54,C0084 ; CALL C0084 +; 1028: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0086 ; CALL C0086 +; 1029: end + DB $5A ; LEAVE +; 1030: def emit_saw_10(tag) +C0134: ; emit_saw_10() + ; tag = 2 +; 1031: emit_op_10($7A) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$7A ; CB 122 + DB $54,C0084 ; CALL C0084 +; 1032: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0086 ; CALL C0086 +; 1033: end + DB $5A ; LEAVE +; 1034: def emit_dab_10(tag) +C0136: ; emit_dab_10() + ; tag = 2 +; 1035: emit_op_10($7C) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$7C ; CB 124 + DB $54,C0084 ; CALL C0084 +; 1036: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0086 ; CALL C0086 +; 1037: end + DB $5A ; LEAVE +; 1038: def emit_daw_10(tag) +C0138: ; emit_daw_10() + ; tag = 2 +; 1039: emit_op_10($7E) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$7E ; CB 126 + DB $54,C0084 ; CALL C0084 +; 1040: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0086 ; CALL C0086 +; 1041: end + DB $5A ; LEAVE +; 1042: def emit_call_10(tag) +C0140: ; emit_call_10() + ; tag = 2 +; 1043: emit_op_10($54) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$54 ; CB 84 + DB $54,C0084 ; CALL C0084 +; 1044: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0086 ; CALL C0086 +; 1045: end + DB $5A ; LEAVE +; 1046: def emit_ical +C0142: ; emit_ical() +; 1047: emit_op_10($56) + JSR INTERP + DB $2A,$56 ; CB 86 + DB $54,C0084 ; CALL C0084 +; 1048: end + DB $5C ; RET +; 1049: def emit_push +C0144: ; emit_push() +; 1050: emit_op_10($34) + JSR INTERP + DB $2A,$34 ; CB 52 + DB $54,C0084 ; CALL C0084 +; 1051: end + DB $5C ; RET +; 1052: def emit_pull +C0146: ; emit_pull() +; 1053: ; +; 1054: ; Skip if last op was push +; 1055: ; +; 1056: if lastop == $34 + JSR INTERP + DB $68,D0018 ; LAB D0018 + DB $2A,$34 ; CB 52 + DB $40 ; ISEQ + DB $4C,C0148 ; SKPFLS C0148 +; 1057: codeptr = codeptr - 1 + DB $6A,D0014 ; LAW D0014 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $7A,D0014 ; SAW D0014 +; 1058: lastop = $FF + DB $2A,$FF ; CB 255 + DB $78,D0018 ; SAB D0018 +; 1059: else + DB $50,C0149 ; SKIP C0149 +C0148: +; 1060: emit_op_10($36) + DB $2A,$36 ; CB 54 + DB $54,C0084 ; CALL C0084 +; 1061: fin +C0149: +; 1062: end + DB $5C ; RET +; 1063: def emit_localaddr_10(index) +C0150: ; emit_localaddr_10() + ; index = 2 +; 1064: emit_op_10($28) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$28 ; CB 40 + DB $54,C0084 ; CALL C0084 +; 1065: emit_byte_10(index) + DB $66,$02 ; LLW 2 + DB $54,C0076 ; CALL C0076 +; 1066: end + DB $5A ; LEAVE +; 1067: def emit_globaladdr_10(tag) +C0152: ; emit_globaladdr_10() + ; tag = 2 +; 1068: emit_op_10($26) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$26 ; CB 38 + DB $54,C0084 ; CALL C0084 +; 1069: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0086 ; CALL C0086 +; 1070: end + DB $5A ; LEAVE +; 1071: def emit_indexbyte +C0154: ; emit_indexbyte() +; 1072: emit_op_10($02) + JSR INTERP + DB $2A,$02 ; CB 2 + DB $54,C0084 ; CALL C0084 +; 1073: end + DB $5C ; RET +; 1074: def emit_indexword +C0156: ; emit_indexword() +; 1075: emit_op_10($1E) + JSR INTERP + DB $2A,$1E ; CB 30 + DB $54,C0084 ; CALL C0084 +; 1076: end + DB $5C ; RET +; 1077: defopt emit_unaryop_11(op) +C0158: ; emit_unaryop_11() + ; op = 2 +; 1078: when op + LDY #4 + LDA #1 + JSR ENTER + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X +; 1079: is NEG_TKN + DEX + LDA #$AD + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0161 +: +; 1080: emit_op_10($10) + DEX + LDA #$10 + STA ESTKL,X + STY ESTKH,X + JSR C0084 +; 1081: is COMP_TKN + JMP C0160 +C0161: + DEX + LDA #$A3 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0162 +: +; 1082: emit_op_10($12) + DEX + LDA #$12 + STA ESTKL,X + STY ESTKH,X + JSR C0084 +; 1083: is LOGIC_NOT_TKN + JMP C0160 +C0162: + DEX + LDA #$A1 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0163 +: +; 1084: emit_op_10($20) + DEX + LDA #$20 + STA ESTKL,X + STY ESTKH,X + JSR C0084 +; 1085: is INC_TKN + JMP C0160 +C0163: + DEX + LDA #$C1 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0164 +: +; 1086: emit_op_10($0C) + DEX + LDA #$0C + STA ESTKL,X + STY ESTKH,X + JSR C0084 +; 1087: is DEC_TKN + JMP C0160 +C0164: + DEX + LDA #$C4 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0165 +: +; 1088: emit_op_10($0E) + DEX + LDA #$0E + STA ESTKL,X + STY ESTKH,X + JSR C0084 +; 1089: is BPTR_TKN + JMP C0160 +C0165: + DEX + LDA #$DE + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0166 +: +; 1090: emit_op_10($60) + DEX + LDA #$60 + STA ESTKL,X + STY ESTKH,X + JSR C0084 +; 1091: is WPTR_TKN + JMP C0160 +C0166: + DEX + LDA #$AA + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0167 +: +; 1092: emit_op_10($62) + DEX + LDA #$62 + STA ESTKL,X + STY ESTKH,X + JSR C0084 +; 1093: otherwise + JMP C0160 +C0167: +; 1094: return FALSE + LDY #$00 + STY ESTKL,X + STY ESTKH,X + JMP LEAVE +; 1095: wend +C0160: +; 1096: return TRUE + LDA #$FF + STA ESTKL,X + STA ESTKH,X + JMP LEAVE +; 1097: end +; 1098: defopt emit_binaryop_11(op) +C0169: ; emit_binaryop_11() + ; op = 2 +; 1099: when op + LDY #4 + LDA #1 + JSR ENTER + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X +; 1100: is MUL_TKN + DEX + LDA #$AA + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0172 +: +; 1101: ; +; 1102: ; Replace MUL 2 with SHL 1 +; 1103: ; +; 1104: if lastop == $2A and ^(codeptr - 1) == 2 ; CB 2 + DEX + LDA D0018 + STA ESTKL,X + STY ESTKH,X + DEX + LDA #$2A + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + DEX + LDA D0014 + STA ESTKL,X + LDA D0014+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SUB + JSR LB + DEX + LDA #$02 + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + JSR LAND + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0173 +: +; 1105: codeptr = codeptr - 1 + DEX + LDA D0014 + STA ESTKL,X + LDA D0014+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SUB + LDA ESTKL,X + STA D0014 + LDA ESTKH,X + STA D0014+1 +; 1106: emit_byte_10(1) ; CB 1 + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR C0076 +; 1107: emit_op_10($1A) ; SHL + DEX + LDA #$1A + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR C0084 +; 1108: else + JMP C0174 +C0173: +; 1109: emit_op_10($06) + DEX + LDA #$06 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR C0084 +; 1110: fin +C0174: +; 1111: is DIV_TKN + JMP C0171 +C0172: + DEX + LDA #$AF + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0175 +: +; 1112: ; +; 1113: ; Replace DIV 2 with SHR 1 +; 1114: ; +; 1115: if lastop == $2A and ^(codeptr - 1) == 2 ; CB 2 + DEX + LDA D0018 + STA ESTKL,X + STY ESTKH,X + DEX + LDA #$2A + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + DEX + LDA D0014 + STA ESTKL,X + LDA D0014+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SUB + JSR LB + DEX + LDA #$02 + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + JSR LAND + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0176 +: +; 1116: codeptr = codeptr - 1 + DEX + LDA D0014 + STA ESTKL,X + LDA D0014+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SUB + LDA ESTKL,X + STA D0014 + LDA ESTKH,X + STA D0014+1 +; 1117: emit_byte_10(1) ; CB 1 + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR C0076 +; 1118: emit_op_10($1C) ; SHR + DEX + LDA #$1C + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR C0084 +; 1119: else + JMP C0177 +C0176: +; 1120: emit_op_10($08) + DEX + LDA #$08 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR C0084 +; 1121: fin +C0177: +; 1122: is MOD_TKN + JMP C0171 +C0175: + DEX + LDA #$A5 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0178 +: +; 1123: emit_op_10($0A) + DEX + LDA #$0A + STA ESTKL,X + STY ESTKH,X + JSR C0084 +; 1124: is ADD_TKN + JMP C0171 +C0178: + DEX + LDA #$AB + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0179 +: +; 1125: ; +; 1126: ; Replace ADD 1 with INCR +; 1127: ; +; 1128: if lastop == $2A and ^(codeptr - 1) == 1 ; CB 1 + DEX + LDA D0018 + STA ESTKL,X + STY ESTKH,X + DEX + LDA #$2A + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + DEX + LDA D0014 + STA ESTKL,X + LDA D0014+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SUB + JSR LB + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + JSR LAND + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0180 +: +; 1129: codeptr = codeptr - 2 + DEX + LDA D0014 + STA ESTKL,X + LDA D0014+1 + STA ESTKH,X + DEX + LDA #$02 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SUB + LDA ESTKL,X + STA D0014 + LDA ESTKH,X + STA D0014+1 +; 1130: emit_op_10($0C) ; INC_OP + LDA #$0C + STA ESTKL,X + STY ESTKH,X + JSR C0084 +; 1131: else + JMP C0181 +C0180: +; 1132: emit_op_10($02) + DEX + LDA #$02 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR C0084 +; 1133: fin +C0181: +; 1134: is SUB_TKN + JMP C0171 +C0179: + DEX + LDA #$AD + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0182 +: +; 1135: ; +; 1136: ; Replace SUB 1 with DECR +; 1137: ; +; 1138: if lastop == $2A and ^(codeptr - 1) == 1 ; CB 1 + DEX + LDA D0018 + STA ESTKL,X + STY ESTKH,X + DEX + LDA #$2A + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + DEX + LDA D0014 + STA ESTKL,X + LDA D0014+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SUB + JSR LB + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + JSR LAND + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0183 +: +; 1139: codeptr = codeptr - 2 + DEX + LDA D0014 + STA ESTKL,X + LDA D0014+1 + STA ESTKH,X + DEX + LDA #$02 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SUB + LDA ESTKL,X + STA D0014 + LDA ESTKH,X + STA D0014+1 +; 1140: emit_op_10($0E) ; DEC_OP + LDA #$0E + STA ESTKL,X + STY ESTKH,X + JSR C0084 +; 1141: else + JMP C0184 +C0183: +; 1142: emit_op_10($04) + DEX + LDA #$04 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR C0084 +; 1143: fin +C0184: +; 1144: is SHL_TKN + JMP C0171 +C0182: + DEX + LDA #$CC + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0185 +: +; 1145: emit_op_10($1A) + DEX + LDA #$1A + STA ESTKL,X + STY ESTKH,X + JSR C0084 +; 1146: is SHR_TKN + JMP C0171 +C0185: + DEX + LDA #$D2 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0186 +: +; 1147: emit_op_10($1C) + DEX + LDA #$1C + STA ESTKL,X + STY ESTKH,X + JSR C0084 +; 1148: is AND_TKN + JMP C0171 +C0186: + DEX + LDA #$A6 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0187 +: +; 1149: emit_op_10($14) + DEX + LDA #$14 + STA ESTKL,X + STY ESTKH,X + JSR C0084 +; 1150: is OR_TKN + JMP C0171 +C0187: + DEX + LDA #$BF + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0188 +: +; 1151: emit_op_10($16) + DEX + LDA #$16 + STA ESTKL,X + STY ESTKH,X + JSR C0084 +; 1152: is EOR_TKN + JMP C0171 +C0188: + DEX + LDA #$DE + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0189 +: +; 1153: emit_op_10($18) + DEX + LDA #$18 + STA ESTKL,X + STY ESTKH,X + JSR C0084 +; 1154: is EQ_TKN + JMP C0171 +C0189: + DEX + LDA #$C5 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0190 +: +; 1155: emit_op_10($40) + DEX + LDA #$40 + STA ESTKL,X + STY ESTKH,X + JSR C0084 +; 1156: is NE_TKN + JMP C0171 +C0190: + DEX + LDA #$D5 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0191 +: +; 1157: emit_op_10($42) + DEX + LDA #$42 + STA ESTKL,X + STY ESTKH,X + JSR C0084 +; 1158: is GE_TKN + JMP C0171 +C0191: + DEX + LDA #$C8 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0192 +: +; 1159: emit_op_10($48) + DEX + LDA #$48 + STA ESTKL,X + STY ESTKH,X + JSR C0084 +; 1160: is LT_TKN + JMP C0171 +C0192: + DEX + LDA #$BC + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0193 +: +; 1161: emit_op_10($46) + DEX + LDA #$46 + STA ESTKL,X + STY ESTKH,X + JSR C0084 +; 1162: is GT_TKN + JMP C0171 +C0193: + DEX + LDA #$BE + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0194 +: +; 1163: emit_op_10($44) + DEX + LDA #$44 + STA ESTKL,X + STY ESTKH,X + JSR C0084 +; 1164: is LE_TKN + JMP C0171 +C0194: + DEX + LDA #$C2 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0195 +: +; 1165: emit_op_10($4A) + DEX + LDA #$4A + STA ESTKL,X + STY ESTKH,X + JSR C0084 +; 1166: is LOGIC_OR_TKN + JMP C0171 +C0195: + DEX + LDA #$CF + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0196 +: +; 1167: emit_op_10($22) + DEX + LDA #$22 + STA ESTKL,X + STY ESTKH,X + JSR C0084 +; 1168: is LOGIC_AND_TKN + JMP C0171 +C0196: + DEX + LDA #$CE + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0197 +: +; 1169: emit_op_10($24) + DEX + LDA #$24 + STA ESTKL,X + STY ESTKH,X + JSR C0084 +; 1170: is COMMA_TKN + JMP C0171 +C0197: + DEX + LDA #$AC + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0198 +: +; 1171: ; Do nothing except move to next stanza in expression +; 1172: otherwise + JMP C0171 +C0198: +; 1173: return FALSE + LDY #$00 + STY ESTKL,X + STY ESTKH,X + JMP LEAVE +; 1174: wend +C0171: +; 1175: return TRUE + LDA #$FF + STA ESTKL,X + STA ESTKH,X + JMP LEAVE +; 1176: end +; 1177: def emit_brtru_10(tag) +C0200: ; emit_brtru_10() + ; tag = 2 +; 1178: emit_op_10($4E) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$4E ; CB 78 + DB $54,C0084 ; CALL C0084 +; 1179: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0086 ; CALL C0086 +; 1180: end + DB $5A ; LEAVE +; 1181: def emit_brfls_10(tag) +C0202: ; emit_brfls_10() + ; tag = 2 +; 1182: emit_op_10($4C) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$4C ; CB 76 + DB $54,C0084 ; CALL C0084 +; 1183: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0086 ; CALL C0086 +; 1184: end + DB $5A ; LEAVE +; 1185: def emit_brgt_10(tag) +C0204: ; emit_brgt_10() + ; tag = 2 +; 1186: emit_op_10($3A) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$3A ; CB 58 + DB $54,C0084 ; CALL C0084 +; 1187: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0086 ; CALL C0086 +; 1188: end + DB $5A ; LEAVE +; 1189: def emit_brlt_10(tag) +C0206: ; emit_brlt_10() + ; tag = 2 +; 1190: emit_op_10($38) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$38 ; CB 56 + DB $54,C0084 ; CALL C0084 +; 1191: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0086 ; CALL C0086 +; 1192: end + DB $5A ; LEAVE +; 1193: def emit_brne_10(tag) +C0208: ; emit_brne_10() + ; tag = 2 +; 1194: emit_op_10($3E) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$3E ; CB 62 + DB $54,C0084 ; CALL C0084 +; 1195: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0086 ; CALL C0086 +; 1196: end + DB $5A ; LEAVE +; 1197: def emit_jump_10(tag) +C0210: ; emit_jump_10() + ; tag = 2 +; 1198: emit_op_10($50) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$50 ; CB 80 + DB $54,C0084 ; CALL C0084 +; 1199: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0086 ; CALL C0086 +; 1200: end + DB $5A ; LEAVE +; 1201: def emit_drop +C0212: ; emit_drop() +; 1202: emit_op_10($30) + JSR INTERP + DB $2A,$30 ; CB 48 + DB $54,C0084 ; CALL C0084 +; 1203: end + DB $5C ; RET +; 1204: def emit_swap +C0214: ; emit_swap() +; 1205: emit_op_10($2E) + JSR INTERP + DB $2A,$2E ; CB 46 + DB $54,C0084 ; CALL C0084 +; 1206: end + DB $5C ; RET +; 1207: def emit_leave_10(framesize) +C0216: ; emit_leave_10() + ; framesize = 2 +; 1208: if framesize > 2 + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $66,$02 ; LLW 2 + DB $2A,$02 ; CB 2 + DB $44 ; ISGT + DB $4C,C0218 ; SKPFLS C0218 +; 1209: emit_op_10($5A) + DB $2A,$5A ; CB 90 + DB $54,C0084 ; CALL C0084 +; 1210: else + DB $50,C0219 ; SKIP C0219 +C0218: +; 1211: emit_op_10($5C) + DB $2A,$5C ; CB 92 + DB $54,C0084 ; CALL C0084 +; 1212: fin +C0219: +; 1213: end + DB $5A ; LEAVE +; 1214: def emit_enter_20(framesize, cparams) +C0220: ; emit_enter_20() + ; framesize = 2 + ; cparams = 4 +; 1215: emit_byte_10(emit_enter_20.[0]) + JSR INTERP + DB $58,$06,$02 ; ENTER 6,2 + DB $26,C0220 ; LA C0220 + DB $00 ; ZERO + DB $02 ; IDXB + DB $60 ; LB + DB $54,C0076 ; CALL C0076 +; 1216: emit_byte_10(emit_enter_20.[1]) + DB $26,C0220 ; LA C0220 + DB $2A,$01 ; CB 1 + DB $02 ; IDXB + DB $60 ; LB + DB $54,C0076 ; CALL C0076 +; 1217: emit_byte_10(emit_enter_20.[2]) + DB $26,C0220 ; LA C0220 + DB $2A,$02 ; CB 2 + DB $02 ; IDXB + DB $60 ; LB + DB $54,C0076 ; CALL C0076 +; 1218: if framesize > 2 + DB $66,$02 ; LLW 2 + DB $2A,$02 ; CB 2 + DB $44 ; ISGT + DB $4C,C0222 ; SKPFLS C0222 +; 1219: emit_op_10($58) + DB $2A,$58 ; CB 88 + DB $54,C0084 ; CALL C0084 +; 1220: emit_byte_10(framesize) + DB $66,$02 ; LLW 2 + DB $54,C0076 ; CALL C0076 +; 1221: emit_byte_10(cparams) + DB $66,$04 ; LLW 4 + DB $54,C0076 ; CALL C0076 +; 1222: fin +C0222: +C0223: +; 1223: end + DB $5A ; LEAVE +; 1224: def emit_start +C0224: ; emit_start() +; 1225: ; +; 1226: ; Save address +; 1227: ; +; 1228: entrypoint = codeptr + JSR INTERP + DB $6A,D0014 ; LAW D0014 + DB $7A,D0016 ; SAW D0016 +; 1229: emit_byte_10(emit_start.[0]) + DB $26,C0224 ; LA C0224 + DB $00 ; ZERO + DB $02 ; IDXB + DB $60 ; LB + DB $54,C0076 ; CALL C0076 +; 1230: emit_byte_10(emit_start.[1]) + DB $26,C0224 ; LA C0224 + DB $2A,$01 ; CB 1 + DB $02 ; IDXB + DB $60 ; LB + DB $54,C0076 ; CALL C0076 +; 1231: emit_byte_10(emit_start.[2]) + DB $26,C0224 ; LA C0224 + DB $2A,$02 ; CB 2 + DB $02 ; IDXB + DB $60 ; LB + DB $54,C0076 ; CALL C0076 +; 1232: end + DB $5C ; RET +; 1233: def emit_exit +C0226: ; emit_exit() +; 1234: emit_op_10($00) + JSR INTERP + DB $00 ; ZERO + DB $54,C0084 ; CALL C0084 +; 1235: emit_op_10($5C) + DB $2A,$5C ; CB 92 + DB $54,C0084 ; CALL C0084 +; 1236: end + DB $5C ; RET +; 1237: ; +; 1238: ; Lexical anaylzer +; 1239: ; +; 1240: ;def isalpha_11(c) +; 1241: ; if c >= 'A' and c <= 'Z' +; 1242: ; return TRUE +; 1243: ; elsif c >= 'a' and c <= 'z' +; 1244: ; return TRUE +; 1245: ; elsif c == '_' +; 1246: ; return TRUE +; 1247: ; fin +; 1248: ; return FALSE +; 1249: ;end +; 1250: asm isalpha_11 +C0228: ; isalpha_11() +; 1251: LDY #$00 + LDY #$00 +; 1252: LDA ESTKL,X + LDA ESTKL,X +; 1253: CMP #'A' + CMP #'A' +; 1254: BCC ISALRET + BCC ISALRET +; 1255: CMP #'Z'+1 + CMP #'Z'+1 +; 1256: BCS :+ + BCS :+ +; 1257: DEY + DEY +; 1258: BNE ISALRET + BNE ISALRET +; 1259: : CMP #'a' +: CMP #'a' +; 1260: BCC ISALRET + BCC ISALRET +; 1261: CMP #'z'+1 + CMP #'z'+1 +; 1262: BCS :+ + BCS :+ +; 1263: DEY + DEY +; 1264: BNE ISALRET + BNE ISALRET +; 1265: : CMP #'_' +: CMP #'_' +; 1266: BNE ISALRET + BNE ISALRET +; 1267: DEY + DEY +; 1268: ISALRET: +ISALRET: +; 1269: STY ESTKL,X + STY ESTKL,X +; 1270: STY ESTKH,X + STY ESTKH,X +; 1271: RTS + RTS +; 1272: end + RTS +; 1273: ;def isnum_11(c) +; 1274: ; if c >= '0' and c <= '9' +; 1275: ; return TRUE +; 1276: ; fin +; 1277: ; return FALSE +; 1278: ;end +; 1279: asm isnum_11 +C0230: ; isnum_11() +; 1280: LDY #$00 + LDY #$00 +; 1281: LDA ESTKL,X + LDA ESTKL,X +; 1282: CMP #'0' + CMP #'0' +; 1283: BCC :+ + BCC :+ +; 1284: CMP #'9'+1 + CMP #'9'+1 +; 1285: BCS :+ + BCS :+ +; 1286: DEY + DEY +; 1287: : STY ESTKL,X +: STY ESTKL,X +; 1288: STY ESTKH,X + STY ESTKH,X +; 1289: RTS + RTS +; 1290: end + RTS +; 1291: ;def isalphanum_11(c) +; 1292: ; if c >= 'A' and c <= 'Z' +; 1293: ; return TRUE +; 1294: ; elsif c >= '0' and c <= '9' +; 1295: ; return TRUE +; 1296: ; elsif c >= 'a' and c <= 'z' +; 1297: ; return TRUE +; 1298: ; elsif c == '_' +; 1299: ; return TRUE +; 1300: ; fin +; 1301: ; return FALSE +; 1302: ;end +; 1303: asm isalphanum_11 +C0232: ; isalphanum_11() +; 1304: LDY #$00 + LDY #$00 +; 1305: LDA ESTKL,X + LDA ESTKL,X +; 1306: CMP #'0' + CMP #'0' +; 1307: BCC ISANRET + BCC ISANRET +; 1308: CMP #'9'+1 + CMP #'9'+1 +; 1309: BCS :+ + BCS :+ +; 1310: DEY + DEY +; 1311: BNE ISANRET + BNE ISANRET +; 1312: : CMP #'A' +: CMP #'A' +; 1313: BCC ISANRET + BCC ISANRET +; 1314: CMP #'Z'+1 + CMP #'Z'+1 +; 1315: BCS :+ + BCS :+ +; 1316: DEY + DEY +; 1317: BNE ISANRET + BNE ISANRET +; 1318: : CMP #'a' +: CMP #'a' +; 1319: BCC :+ + BCC :+ +; 1320: CMP #'z'+1 + CMP #'z'+1 +; 1321: BCS ISANRET + BCS ISANRET +; 1322: DEY + DEY +; 1323: BNE ISANRET + BNE ISANRET +; 1324: : CMP #'_' +: CMP #'_' +; 1325: BNE ISANRET + BNE ISANRET +; 1326: DEY + DEY +; 1327: ISANRET: +ISANRET: +; 1328: STY ESTKL,X + STY ESTKL,X +; 1329: STY ESTKH,X + STY ESTKH,X +; 1330: RTS + RTS +; 1331: end + RTS +; 1332: defopt keymatch_21(chrptr, len) +C0234: ; keymatch_21() + ; chrptr = 2 + ; len = 4 +; 1333: byte i, keypos + ; i = 6 + ; keypos = 7 +; 1334: +; 1335: keypos = 0 + LDY #8 + LDA #2 + JSR ENTER + DEX + STY ESTKL,X + STY ESTKH,X + LDY #$07 + LDA ESTKL,X + STA (FRMP),Y +; 1336: while keywrds[keypos] < len + INX +C0236: + DEX + LDA #D0148 + STA ESTKH,X + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR ISLT + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0237 +: +; 1337: keypos = keypos + keywrds[keypos] + 2 + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA #D0148 + STA ESTKH,X + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + JSR ADD + DEX + LDA #$02 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDY #$07 + LDA ESTKL,X + STA (FRMP),Y +; 1338: loop + INX + JMP C0236 +C0237: +; 1339: while keywrds[keypos] == len +C0238: + DEX + LDA #D0148 + STA ESTKH,X + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0239 +: +; 1340: for i = 1 to len + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X +C0241: + LDY #$06 + LDA ESTKL,X + STA (FRMP),Y + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + LDA ESTKH-1,X + SBC ESTKH,X + BPL :+ + JMP C0240 +: + INC ESTKL,X + BNE :+ + INC ESTKH,X +: +; 1341: if toupper_11((chrptr).[i - 1]) <> keywrds[keypos + i] + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR SUB + JSR ADD + JSR LB + JSR C0024 + DEX + LDA #D0148 + STA ESTKH,X + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR ADD + JSR LB + JSR ISNE + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0242 +: +; 1342: break + JMP C0240 +; 1343: fin +C0242: +C0243: +; 1344: next + JMP C0241 +C0240: +; 1345: if i > len + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR ISGT + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0244 +: +; 1346: return keywrds[keypos + keywrds[keypos] + 1] + DEX + LDA #D0148 + STA ESTKH,X + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA #D0148 + STA ESTKH,X + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + JSR ADD + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ADD + JSR ADD + JSR LB + JMP LEAVE +; 1347: fin +C0244: +C0245: +; 1348: keypos = keypos + keywrds[keypos] + 2 + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA #D0148 + STA ESTKH,X + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + JSR ADD + DEX + LDA #$02 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDY #$07 + LDA ESTKL,X + STA (FRMP),Y +; 1349: loop + INX + JMP C0238 +C0239: +; 1350: return ID_TKN + DEX + LDA #$D6 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JMP LEAVE +; 1351: end +; 1352: defopt scan_01 +C0246: ; scan_01() +; 1353: ; +; 1354: ; Scan for token based on first character +; 1355: ; +; 1356: while ^scanptr and ^scanptr <= ' ' +C0248: + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + LDY #$00 + JSR LB + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + JSR LB + DEX + LDA #$20 + STA ESTKL,X + STY ESTKH,X + JSR ISLE + JSR LAND + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0249 +: +; 1357: scanptr = scanptr + 1 + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0415 + LDA ESTKH,X + STA D0415+1 +; 1358: loop + INX + JMP C0248 +C0249: +; 1359: tknptr = scanptr + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + LDA ESTKL,X + STA D0417 + LDA ESTKH,X + STA D0417+1 +; 1360: if !^scanptr or ^scanptr == ';' + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + LDY #$00 + JSR LB + JSR NOT + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + JSR LB + DEX + LDA #$3B + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + JSR LOR + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0250 +: +; 1361: if token <> EOF_TKN + DEX + LDA D0413 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ISNE + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0252 +: +; 1362: token = EOL_TKN + DEX + LDA #$02 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDA ESTKL,X + STA D0413 +; 1363: fin + INX +C0252: +C0253: +; 1364: elsif isalpha_11(^scanptr) + JMP C0251 +C0250: + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + LDY #$00 + JSR LB + JSR C0228 + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0254 +: +; 1365: ; +; 1366: ; ID, either variable name or reserved word +; 1367: ; +; 1368: repeat +C0256: +; 1369: scanptr = scanptr + 1 + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0415 + LDA ESTKH,X + STA D0415+1 +; 1370: until !isalphanum_11(^scanptr) + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + JSR LB + JSR C0232 + LDY #$00 + JSR NOT + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0256 +: +C0255: +; 1371: tknlen = scanptr - tknptr; + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA D0417 + STA ESTKL,X + LDA D0417+1 + STA ESTKH,X + JSR SUB + LDA ESTKL,X + STA D0414 +; 1372: token = keymatch_21(tknptr, tknlen) + LDA D0417 + STA ESTKL,X + LDA D0417+1 + STA ESTKH,X + DEX + LDA D0414 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR C0234 + LDA ESTKL,X + STA D0413 +; 1373: elsif isnum_11(^scanptr) + INX + JMP C0251 +C0254: + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + LDY #$00 + JSR LB + JSR C0230 + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0257 +: +; 1374: ; +; 1375: ; Number constant +; 1376: ; +; 1377: token = INT_TKN + DEX + LDA #$C9 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDA ESTKL,X + STA D0413 +; 1378: constval = 0 + STY ESTKL,X + STY ESTKH,X + LDA ESTKL,X + STA D0419 + LDA ESTKH,X + STA D0419+1 +; 1379: repeat + INX +C0259: +; 1380: constval = constval * 10 + ^scanptr - '0' + DEX + LDA D0419 + STA ESTKL,X + LDA D0419+1 + STA ESTKH,X + DEX + LDA #$0A + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR MUL + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + JSR LB + JSR ADD + DEX + LDA #$30 + STA ESTKL,X + STY ESTKH,X + JSR SUB + LDA ESTKL,X + STA D0419 + LDA ESTKH,X + STA D0419+1 +; 1381: scanptr = scanptr + 1 + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0415 + LDA ESTKH,X + STA D0415+1 +; 1382: until !isnum_11(^scanptr) + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + JSR LB + JSR C0230 + LDY #$00 + JSR NOT + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0259 +: +C0258: +; 1383: elsif ^scanptr == '$' + JMP C0251 +C0257: + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + LDY #$00 + JSR LB + DEX + LDA #$24 + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0260 +: +; 1384: ; +; 1385: ; Hexadecimal constant +; 1386: ; +; 1387: token = INT_TKN; + DEX + LDA #$C9 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDA ESTKL,X + STA D0413 +; 1388: constval = 0 + STY ESTKL,X + STY ESTKH,X + LDA ESTKL,X + STA D0419 + LDA ESTKH,X + STA D0419+1 +; 1389: repeat + INX +C0262: +; 1390: scanptr = scanptr + 1 + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0415 + LDA ESTKH,X + STA D0415+1 +; 1391: if ^scanptr >= '0' and ^scanptr <= '9' + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + JSR LB + DEX + LDA #$30 + STA ESTKL,X + STY ESTKH,X + JSR ISGE + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + LDY #$00 + JSR LB + DEX + LDA #$39 + STA ESTKL,X + STY ESTKH,X + JSR ISLE + JSR LAND + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0263 +: +; 1392: constval = (constval << 4) + ^scanptr - '0' + DEX + LDA D0419 + STA ESTKL,X + LDA D0419+1 + STA ESTKH,X + DEX + LDA #$04 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SHL + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + JSR LB + JSR ADD + DEX + LDA #$30 + STA ESTKL,X + STY ESTKH,X + JSR SUB + LDA ESTKL,X + STA D0419 + LDA ESTKH,X + STA D0419+1 +; 1393: elsif ^scanptr >= 'A' and ^scanptr <= 'F' + INX + JMP C0264 +C0263: + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + LDY #$00 + JSR LB + DEX + LDA #$41 + STA ESTKL,X + STY ESTKH,X + JSR ISGE + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + LDY #$00 + JSR LB + DEX + LDA #$46 + STA ESTKL,X + STY ESTKH,X + JSR ISLE + JSR LAND + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0265 +: +; 1394: constval = (constval << 4) + ^scanptr - '7'; 'A'-10 + DEX + LDA D0419 + STA ESTKL,X + LDA D0419+1 + STA ESTKH,X + DEX + LDA #$04 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SHL + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + JSR LB + JSR ADD + DEX + LDA #$37 + STA ESTKL,X + STY ESTKH,X + JSR SUB + LDA ESTKL,X + STA D0419 + LDA ESTKH,X + STA D0419+1 +; 1395: elsif ^scanptr >= 'a' and ^scanptr <= 'f' + INX + JMP C0264 +C0265: + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + LDY #$00 + JSR LB + DEX + LDA #$61 + STA ESTKL,X + STY ESTKH,X + JSR ISGE + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + LDY #$00 + JSR LB + DEX + LDA #$66 + STA ESTKL,X + STY ESTKH,X + JSR ISLE + JSR LAND + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0266 +: +; 1396: constval = (constval << 4) + ^scanptr - 'W'; 'a'-10 + DEX + LDA D0419 + STA ESTKL,X + LDA D0419+1 + STA ESTKH,X + DEX + LDA #$04 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SHL + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + JSR LB + JSR ADD + DEX + LDA #$57 + STA ESTKL,X + STY ESTKH,X + JSR SUB + LDA ESTKL,X + STA D0419 + LDA ESTKH,X + STA D0419+1 +; 1397: else + INX + JMP C0264 +C0266: +; 1398: break; + JMP C0261 +; 1399: fin +C0264: +; 1400: until !^scanptr + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + LDY #$00 + JSR LB + JSR NOT + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0262 +: +C0261: +; 1401: elsif ^scanptr == $27 ; ' + JMP C0251 +C0260: + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + LDY #$00 + JSR LB + DEX + LDA #$27 + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0267 +: +; 1402: ; +; 1403: ; Character constant +; 1404: ; +; 1405: token = CHR_TKN + DEX + LDA #$C3 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDA ESTKL,X + STA D0413 +; 1406: if ^(scanptr + 1) <> $5C ; \ + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDA #$5C + STA ESTKL,X + STY ESTKH,X + JSR ISNE + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0268 +: +; 1407: constval = ^(scanptr + 1) + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + LDA ESTKL,X + STA D0419 + LDA ESTKH,X + STA D0419+1 +; 1408: if ^(scanptr + 2) <> $27 ; ' + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA #$02 + STA ESTKL,X + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDA #$27 + STA ESTKL,X + STY ESTKH,X + JSR ISNE + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0270 +: +; 1409: return parse_err_11(@bad_cnst) + DEX + LDA #D0474 + STA ESTKH,X + JSR C0062 + RTS +; 1410: fin +C0270: +C0271: +; 1411: scanptr = scanptr + 3 + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA #$03 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0415 + LDA ESTKH,X + STA D0415+1 +; 1412: else + INX + JMP C0269 +C0268: +; 1413: when ^(scanptr + 2) + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA #$02 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB +; 1414: is 'n' + DEX + LDA #$6E + STA ESTKL,X + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0273 +: +; 1415: constval = $0D + DEX + LDA #$0D + STA ESTKL,X + STY ESTKH,X + LDA ESTKL,X + STA D0419 + LDA ESTKH,X + STA D0419+1 +; 1416: is 'r' + INX + JMP C0272 +C0273: + DEX + LDA #$72 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0274 +: +; 1417: constval = $0A + DEX + LDA #$0A + STA ESTKL,X + STY ESTKH,X + LDA ESTKL,X + STA D0419 + LDA ESTKH,X + STA D0419+1 +; 1418: is 't' + INX + JMP C0272 +C0274: + DEX + LDA #$74 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0275 +: +; 1419: constval = $09 + DEX + LDA #$09 + STA ESTKL,X + STY ESTKH,X + LDA ESTKL,X + STA D0419 + LDA ESTKH,X + STA D0419+1 +; 1420: otherwise + INX + JMP C0272 +C0275: +; 1421: constval = ^(scanptr + 2) + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA #$02 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + LDA ESTKL,X + STA D0419 + LDA ESTKH,X + STA D0419+1 +; 1422: wend + INX +C0272: +; 1423: if ^(scanptr + 3) <> $27 ; ' + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA #$03 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDA #$27 + STA ESTKL,X + STY ESTKH,X + JSR ISNE + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0277 +: +; 1424: return parse_err_11(@bad_cnst) + DEX + LDA #D0474 + STA ESTKH,X + JSR C0062 + RTS +; 1425: fin +C0277: +C0278: +; 1426: scanptr = scanptr + 4 + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA #$04 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0415 + LDA ESTKH,X + STA D0415+1 +; 1427: fin + INX +C0269: +; 1428: elsif ^scanptr == '"' + JMP C0251 +C0267: + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + LDY #$00 + JSR LB + DEX + LDA #$22 + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0279 +: +; 1429: ; +; 1430: ; String constant +; 1431: ; +; 1432: token = STR_TKN + DEX + LDA #$D3 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDA ESTKL,X + STA D0413 +; 1433: scanptr = scanptr + 1 + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0415 + LDA ESTKH,X + STA D0415+1 +; 1434: constval = scanptr + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + LDA ESTKL,X + STA D0419 + LDA ESTKH,X + STA D0419+1 +; 1435: while ^scanptr and ^scanptr <> '"' + INX +C0280: + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + LDY #$00 + JSR LB + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + JSR LB + DEX + LDA #$22 + STA ESTKL,X + STY ESTKH,X + JSR ISNE + JSR LAND + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0281 +: +; 1436: scanptr = scanptr + 1 + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0415 + LDA ESTKH,X + STA D0415+1 +; 1437: loop + INX + JMP C0280 +C0281: +; 1438: if !^scanptr + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + LDY #$00 + JSR LB + JSR NOT + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0282 +: +; 1439: return parse_err_11(@bad_cnst) + DEX + LDA #D0474 + STA ESTKH,X + JSR C0062 + RTS +; 1440: fin +C0282: +C0283: +; 1441: scanptr = scanptr + 1 + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0415 + LDA ESTKH,X + STA D0415+1 +; 1442: else + INX + JMP C0251 +C0279: +; 1443: ; +; 1444: ; Potential two and three character tokens +; 1445: ; +; 1446: when ^scanptr + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + LDY #$00 + JSR LB +; 1447: is '>' + DEX + LDA #$3E + STA ESTKL,X + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0285 +: +; 1448: if ^(scanptr + 1) == '>' + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDA #$3E + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0286 +: +; 1449: token = SHR_TKN + DEX + LDA #$D2 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDA ESTKL,X + STA D0413 +; 1450: scanptr = scanptr + 2 + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA #$02 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0415 + LDA ESTKH,X + STA D0415+1 +; 1451: elsif ^(scanptr + 1) == '=' + INX + JMP C0287 +C0286: + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDA #$3D + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0288 +: +; 1452: token = GE_TKN + DEX + LDA #$C8 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDA ESTKL,X + STA D0413 +; 1453: scanptr = scanptr + 2 + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA #$02 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0415 + LDA ESTKH,X + STA D0415+1 +; 1454: else + INX + JMP C0287 +C0288: +; 1455: token = GT_TKN + DEX + LDA #$BE + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDA ESTKL,X + STA D0413 +; 1456: scanptr = scanptr + 1 + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0415 + LDA ESTKH,X + STA D0415+1 +; 1457: fin + INX +C0287: +; 1458: is '<' + JMP C0284 +C0285: + DEX + LDA #$3C + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0289 +: +; 1459: if ^(scanptr + 1) == '<' + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDA #$3C + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0290 +: +; 1460: token = SHL_TKN + DEX + LDA #$CC + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDA ESTKL,X + STA D0413 +; 1461: scanptr = scanptr + 2 + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA #$02 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0415 + LDA ESTKH,X + STA D0415+1 +; 1462: elsif ^(scanptr + 1) == '=' + INX + JMP C0291 +C0290: + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDA #$3D + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0292 +: +; 1463: token = LE_TKN + DEX + LDA #$C2 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDA ESTKL,X + STA D0413 +; 1464: scanptr = scanptr + 2 + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA #$02 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0415 + LDA ESTKH,X + STA D0415+1 +; 1465: elsif ^(scanptr + 1) == '>' + INX + JMP C0291 +C0292: + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDA #$3E + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0293 +: +; 1466: token = NE_TKN + DEX + LDA #$D5 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDA ESTKL,X + STA D0413 +; 1467: scanptr = scanptr + 2 + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA #$02 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0415 + LDA ESTKH,X + STA D0415+1 +; 1468: else + INX + JMP C0291 +C0293: +; 1469: token = LT_TKN + DEX + LDA #$BC + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDA ESTKL,X + STA D0413 +; 1470: scanptr = scanptr + 1 + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0415 + LDA ESTKH,X + STA D0415+1 +; 1471: fin + INX +C0291: +; 1472: is '=' + JMP C0284 +C0289: + DEX + LDA #$3D + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0294 +: +; 1473: if ^(scanptr + 1) == '=' + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDA #$3D + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0295 +: +; 1474: token = EQ_TKN + DEX + LDA #$C5 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDA ESTKL,X + STA D0413 +; 1475: scanptr = scanptr + 2; + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA #$02 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0415 + LDA ESTKH,X + STA D0415+1 +; 1476: elsif ^(scanptr + 1) == ',' + INX + JMP C0296 +C0295: + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDA #$2C + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0297 +: +; 1477: token = SETLIST_TKN + DEX + LDA #$B9 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDA ESTKL,X + STA D0413 +; 1478: scanptr = scanptr + 2; + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA #$02 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0415 + LDA ESTKH,X + STA D0415+1 +; 1479: else + INX + JMP C0296 +C0297: +; 1480: token = SET_TKN; + DEX + LDA #$BD + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDA ESTKL,X + STA D0413 +; 1481: scanptr = scanptr + 1 + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0415 + LDA ESTKH,X + STA D0415+1 +; 1482: fin + INX +C0296: +; 1483: otherwise + JMP C0284 +C0294: +; 1484: ; +; 1485: ; Simple single character tokens +; 1486: ; +; 1487: token = ^scanptr ? $80 + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + LDY #$00 + JSR LB + DEX + LDA #$80 + STA ESTKL,X + STY ESTKH,X + JSR IOR + LDA ESTKL,X + STA D0413 +; 1488: scanptr = scanptr + 1 + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0415 + LDA ESTKH,X + STA D0415+1 +; 1489: wend + INX +C0284: +; 1490: fin + INX +C0251: +; 1491: tknlen = scanptr - tknptr + DEX + LDA D0415 + STA ESTKL,X + LDA D0415+1 + STA ESTKH,X + DEX + LDA D0417 + STA ESTKL,X + LDA D0417+1 + STA ESTKH,X + JSR SUB + LDA ESTKL,X + STA D0414 +; 1492: return token + LDA D0413 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + RTS +; 1493: end +; 1494: def rewind_10(ptr) +C0299: ; rewind_10() + ; ptr = 2 +; 1495: scanptr = ptr + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $66,$02 ; LLW 2 + DB $7A,D0415 ; SAW D0415 +; 1496: end + DB $5A ; LEAVE +; 1497: ; +; 1498: ; Get next line of input +; 1499: ; +; 1500: def nextln_01 +C0301: ; nextln_01() +; 1501: byte i, chr + ; i = 2 + ; chr = 3 +; 1502: +; 1503: scanptr = inbuff + JSR INTERP + DB $58,$04,$00 ; ENTER 4,0 + DB $2C,$00,$02 ; CW 512 + DB $7A,D0415 ; SAW D0415 +; 1504: ^instr = read_31(inref, inbuff, $7F) + DB $2C,$FF,$01 ; CW 511 + DB $68,D0000 ; LAB D0000 + DB $2C,$00,$02 ; CW 512 + DB $2A,$7F ; CB 127 + DB $54,C0036 ; CALL C0036 + DB $70 ; SB +; 1505: inbuff[^instr] = $00 + DB $2C,$00,$02 ; CW 512 + DB $2C,$FF,$01 ; CW 511 + DB $60 ; LB + DB $02 ; IDXB + DB $00 ; ZERO + DB $70 ; SB +; 1506: if ^instr + DB $2C,$FF,$01 ; CW 511 + DB $60 ; LB + DB $4C,C0303 ; SKPFLS C0303 +; 1507: lineno = lineno + 1 + DB $6A,D0421 ; LAW D0421 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $7A,D0421 ; SAW D0421 +; 1508: if !(lineno & $0F) + DB $6A,D0421 ; LAW D0421 + DB $2A,$0F ; CB 15 + DB $14 ; BAND + DB $20 ; NOT + DB $4C,C0305 ; SKPFLS C0305 +; 1509: cout('.') + DB $2A,$2E ; CB 46 + DB $54,C0016 ; CALL C0016 +; 1510: fin +C0305: +C0306: +; 1511: ; cout('>') +; 1512: ; prstr(instr) +; 1513: ; crout +; 1514: drop scan_01() + DB $54,C0246 ; CALL C0246 + DB $30 ; DROP +; 1515: else + DB $50,C0304 ; SKIP C0304 +C0303: +; 1516: ^instr = 0 + DB $2C,$FF,$01 ; CW 511 + DB $00 ; ZERO + DB $70 ; SB +; 1517: ^inbuff = $00 + DB $2C,$00,$02 ; CW 512 + DB $00 ; ZERO + DB $70 ; SB +; 1518: token = DONE_TKN + DB $2A,$98 ; CB 152 + DB $78,D0413 ; SAB D0413 +; 1519: fin +C0304: +; 1520: return ^instr + DB $2C,$FF,$01 ; CW 511 + DB $60 ; LB + DB $5A ; LEAVE +; 1521: end +; 1522: ; +; 1523: ; Alebraic op to stack op +; 1524: ; +; 1525: def push_op_21(op, prec) +C0307: ; push_op_21() + ; op = 2 + ; prec = 4 +; 1526: opsp = opsp + 1 + JSR INTERP + DB $58,$06,$02 ; ENTER 6,2 + DB $6A,D0411 ; LAW D0411 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $7A,D0411 ; SAW D0411 +; 1527: if opsp == 16 + DB $6A,D0411 ; LAW D0411 + DB $2A,$10 ; CB 16 + DB $40 ; ISEQ + DB $4C,C0309 ; SKPFLS C0309 +; 1528: return parse_err_11(@estk_overflw) + DB $26,D0574 ; LA D0574 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 1529: fin +C0309: +C0310: +; 1530: opstack[opsp] = op + DB $26,D0379 ; LA D0379 + DB $6A,D0411 ; LAW D0411 + DB $02 ; IDXB + DB $66,$02 ; LLW 2 + DB $70 ; SB +; 1531: precstack[opsp] = prec + DB $26,D0395 ; LA D0395 + DB $6A,D0411 ; LAW D0411 + DB $02 ; IDXB + DB $66,$04 ; LLW 4 + DB $70 ; SB +; 1532: return 0 + DB $00 ; ZERO + DB $5A ; LEAVE +; 1533: end +; 1534: def pop_op_01 +C0311: ; pop_op_01() +; 1535: if opsp < 0 + JSR INTERP + DB $6A,D0411 ; LAW D0411 + DB $00 ; ZERO + DB $46 ; ISLT + DB $4C,C0313 ; SKPFLS C0313 +; 1536: return parse_err_11(@estk_underflw) + DB $26,D0594 ; LA D0594 + DB $54,C0062 ; CALL C0062 + DB $5C ; RET +; 1537: fin +C0313: +C0314: +; 1538: opsp = opsp - 1 + DB $6A,D0411 ; LAW D0411 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $7A,D0411 ; SAW D0411 +; 1539: return opstack[opsp + 1] + DB $26,D0379 ; LA D0379 + DB $6A,D0411 ; LAW D0411 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $02 ; IDXB + DB $60 ; LB + DB $5C ; RET +; 1540: end +; 1541: def tos_op_01 +C0315: ; tos_op_01() +; 1542: if opsp < 0 + JSR INTERP + DB $6A,D0411 ; LAW D0411 + DB $00 ; ZERO + DB $46 ; ISLT + DB $4C,C0317 ; SKPFLS C0317 +; 1543: return 0 + DB $00 ; ZERO + DB $5C ; RET +; 1544: fin +C0317: +C0318: +; 1545: return opstack[opsp] + DB $26,D0379 ; LA D0379 + DB $6A,D0411 ; LAW D0411 + DB $02 ; IDXB + DB $60 ; LB + DB $5C ; RET +; 1546: end +; 1547: def tos_op_prec_11(tos) +C0319: ; tos_op_prec_11() + ; tos = 2 +; 1548: if opsp <= tos + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $6A,D0411 ; LAW D0411 + DB $66,$02 ; LLW 2 + DB $4A ; ISLE + DB $4C,C0321 ; SKPFLS C0321 +; 1549: return 100 + DB $2A,$64 ; CB 100 + DB $5A ; LEAVE +; 1550: fin +C0321: +C0322: +; 1551: return precstack[opsp] + DB $26,D0395 ; LA D0395 + DB $6A,D0411 ; LAW D0411 + DB $02 ; IDXB + DB $60 ; LB + DB $5A ; LEAVE +; 1552: end +; 1553: ; +; 1554: ; Symbol table +; 1555: ; +; 1556: defopt idmatch_41(nameptr, len, idptr, idcnt) +C0323: ; idmatch_41() + ; nameptr = 2 + ; len = 4 + ; idptr = 6 + ; idcnt = 8 +; 1557: byte i + ; i = 10 +; 1558: +; 1559: while idcnt + LDY #11 + LDA #4 + JSR ENTER +C0325: + DEX + LDY #$08 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0326 +: +; 1560: if len == (idptr).idname + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$03 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0327 +: +; 1561: for i = 1 to len + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X +C0330: + LDY #$0A + LDA ESTKL,X + STA (FRMP),Y + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + LDA ESTKH-1,X + SBC ESTKH,X + BPL :+ + JMP C0329 +: + INC ESTKL,X + BNE :+ + INC ESTKH,X +: +; 1562: if (nameptr).[i - 1] <> (idptr).idname.[i] + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$0A + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR SUB + JSR ADD + JSR LB + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$03 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + DEX + LDY #$0A + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + JSR ISNE + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0331 +: +; 1563: break + JMP C0329 +; 1564: fin +C0331: +C0332: +; 1565: next + JMP C0330 +C0329: +; 1566: if i > len + LDY #$0A + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR ISGT + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0333 +: +; 1567: return idptr + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JMP LEAVE +; 1568: fin +C0333: +C0334: +; 1569: fin +C0327: +C0328: +; 1570: idptr = idptr + (idptr).idname + idrecsz + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$03 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + JSR ADD + DEX + LDA #$04 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDY #$06 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 1571: idcnt = idcnt - 1 + LDY #$08 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SUB + LDY #$08 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 1572: loop + INX + JMP C0325 +C0326: +; 1573: return 0 + DEX + LDY #$00 + STY ESTKL,X + STY ESTKH,X + JMP LEAVE +; 1574: end +; 1575: ;def dumpsym_20(idptr, idcnt) +; 1576: ; while idcnt +; 1577: ; prword_10((idptr):idval) +; 1578: ; cout(' ') +; 1579: ; prbyte_10((idptr).idtype) +; 1580: ; cout(' ') +; 1581: ; prstr(@(idptr).idname) +; 1582: ; cout('=') +; 1583: ; if (idptr).idtype & ADDR_TYPE +; 1584: ; if (idptr):idval & is_ctag +; 1585: ; prword_10(ctag_value:[(idptr):idval & mask_ctag]) +; 1586: ; else +; 1587: ; prword_10((idptr):idval + codebuff) +; 1588: ; fin +; 1589: ; else +; 1590: ; prword_10((idptr):idval) +; 1591: ; fin +; 1592: ; crout() +; 1593: ; idptr = idptr + (idptr).idname + idrecsz +; 1594: ; idcnt = idcnt - 1 +; 1595: ; loop +; 1596: ;end +; 1597: def id_lookup_21(nameptr, len) +C0335: ; id_lookup_21() + ; nameptr = 2 + ; len = 4 +; 1598: word idptr + ; idptr = 6 +; 1599: +; 1600: idptr = idmatch_41(nameptr, len, idlocal_tbl, locals) + JSR INTERP + DB $58,$08,$02 ; ENTER 8,2 + DB $66,$02 ; LLW 2 + DB $66,$04 ; LLW 4 + DB $2C,$00,$18 ; CW 6144 + DB $68,D0007 ; LAB D0007 + DB $54,C0323 ; CALL C0323 + DB $76,$06 ; SLW 6 +; 1601: if idptr + DB $66,$06 ; LLW 6 + DB $4C,C0337 ; SKPFLS C0337 +; 1602: return idptr + DB $66,$06 ; LLW 6 + DB $5A ; LEAVE +; 1603: fin +C0337: +C0338: +; 1604: idptr = idmatch_41(nameptr, len, idglobal_tbl, globals) + DB $66,$02 ; LLW 2 + DB $66,$04 ; LLW 4 + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0001 ; LAW D0001 + DB $54,C0323 ; CALL C0323 + DB $76,$06 ; SLW 6 +; 1605: if idptr + DB $66,$06 ; LLW 6 + DB $4C,C0339 ; SKPFLS C0339 +; 1606: return idptr + DB $66,$06 ; LLW 6 + DB $5A ; LEAVE +; 1607: fin +C0339: +C0340: +; 1608: return parse_err_11(@undecl_id) + DB $26,D0452 ; LA D0452 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 1609: end +; 1610: def idglobal_lookup_21(nameptr, len) +C0341: ; idglobal_lookup_21() + ; nameptr = 2 + ; len = 4 +; 1611: return idmatch_41(nameptr, len, idglobal_tbl, globals) + JSR INTERP + DB $58,$06,$02 ; ENTER 6,2 + DB $66,$02 ; LLW 2 + DB $66,$04 ; LLW 4 + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0001 ; LAW D0001 + DB $54,C0323 ; CALL C0323 + DB $5A ; LEAVE +; 1612: end +; 1613: def idlocal_add_41(namestr, len, type, size) +C0343: ; idlocal_add_41() + ; namestr = 2 + ; len = 4 + ; type = 6 + ; size = 8 +; 1614: if idmatch_41(namestr, len, @idlocal_tbl, locals) + JSR INTERP + DB $58,$0A,$04 ; ENTER 10,4 + DB $66,$02 ; LLW 2 + DB $66,$04 ; LLW 4 + DB $2C,$00,$18 ; CW 6144 + DB $68,D0007 ; LAB D0007 + DB $54,C0323 ; CALL C0323 + DB $4C,C0345 ; SKPFLS C0345 +; 1615: return parse_err_11(@dup_id) + DB $26,D0431 ; LA D0431 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 1616: fin +C0345: +C0346: +; 1617: (lastlocal):idval = framesize + DB $6A,D0010 ; LAW D0010 + DB $6A,D0008 ; LAW D0008 + DB $72 ; SW +; 1618: (lastlocal).idtype = type ? LOCAL_TYPE + DB $6A,D0010 ; LAW D0010 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $66,$06 ; LLW 6 + DB $2A,$10 ; CB 16 + DB $16 ; IOR + DB $70 ; SB +; 1619: nametostr_30(namestr, len, lastlocal + idname) + DB $66,$02 ; LLW 2 + DB $66,$04 ; LLW 4 + DB $6A,D0010 ; LAW D0010 + DB $2A,$03 ; CB 3 + DB $02 ; ADD + DB $54,C0060 ; CALL C0060 +; 1620: locals = locals + 1 + DB $68,D0007 ; LAB D0007 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $78,D0007 ; SAB D0007 +; 1621: lastlocal = lastlocal + idrecsz + len + DB $6A,D0010 ; LAW D0010 + DB $2A,$04 ; CB 4 + DB $02 ; ADD + DB $66,$04 ; LLW 4 + DB $02 ; ADD + DB $7A,D0010 ; SAW D0010 +; 1622: if lastlocal > idlocal_tbl + idlocal_tblsz + DB $6A,D0010 ; LAW D0010 + DB $2C,$00,$18 ; CW 6144 + DB $2C,$00,$02 ; CW 512 + DB $02 ; ADD + DB $44 ; ISGT + DB $4C,C0347 ; SKPFLS C0347 +; 1623: prstr(@local_sym_overflw) + DB $26,D0665 ; LA D0665 + DB $54,C0020 ; CALL C0020 +; 1624: exit + DB $54,C0026 ; CALL C0026 +; 1625: fin +C0347: +C0348: +; 1626: framesize = framesize + size + DB $6A,D0008 ; LAW D0008 + DB $66,$08 ; LLW 8 + DB $02 ; ADD + DB $7A,D0008 ; SAW D0008 +; 1627: if framesize > 255 + DB $6A,D0008 ; LAW D0008 + DB $2A,$FF ; CB 255 + DB $44 ; ISGT + DB $4C,C0349 ; SKPFLS C0349 +; 1628: prstr(@local_overflw) + DB $26,D0615 ; LA D0615 + DB $54,C0020 ; CALL C0020 +; 1629: return FALSE + DB $00 ; ZERO + DB $5A ; LEAVE +; 1630: fin +C0349: +C0350: +; 1631: return TRUE + DB $2C,$FF,$FF ; CW -1 + DB $5A ; LEAVE +; 1632: end +; 1633: def iddata_add_41(namestr, len, type, size) +C0351: ; iddata_add_41() + ; namestr = 2 + ; len = 4 + ; type = 6 + ; size = 8 +; 1634: if idmatch_41(namestr, len, idglobal_tbl, globals) + JSR INTERP + DB $58,$0A,$04 ; ENTER 10,4 + DB $66,$02 ; LLW 2 + DB $66,$04 ; LLW 4 + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0001 ; LAW D0001 + DB $54,C0323 ; CALL C0323 + DB $4C,C0353 ; SKPFLS C0353 +; 1635: return parse_err_11(@dup_id) + DB $26,D0431 ; LA D0431 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 1636: fin +C0353: +C0354: +; 1637: (lastglobal):idval = datasize + DB $6A,D0005 ; LAW D0005 + DB $6A,D0003 ; LAW D0003 + DB $72 ; SW +; 1638: (lastglobal).idtype = type + DB $6A,D0005 ; LAW D0005 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $66,$06 ; LLW 6 + DB $70 ; SB +; 1639: nametostr_30(namestr, len, lastglobal + idname) + DB $66,$02 ; LLW 2 + DB $66,$04 ; LLW 4 + DB $6A,D0005 ; LAW D0005 + DB $2A,$03 ; CB 3 + DB $02 ; ADD + DB $54,C0060 ; CALL C0060 +; 1640: emit_iddata_30(datasize, size, lastglobal + idname) + DB $6A,D0003 ; LAW D0003 + DB $66,$08 ; LLW 8 + DB $6A,D0005 ; LAW D0005 + DB $2A,$03 ; CB 3 + DB $02 ; ADD + DB $54,C0092 ; CALL C0092 +; 1641: globals = globals + 1 + DB $6A,D0001 ; LAW D0001 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $7A,D0001 ; SAW D0001 +; 1642: lastglobal = lastglobal + idrecsz + len + DB $6A,D0005 ; LAW D0005 + DB $2A,$04 ; CB 4 + DB $02 ; ADD + DB $66,$04 ; LLW 4 + DB $02 ; ADD + DB $7A,D0005 ; SAW D0005 +; 1643: if lastglobal > idglobal_tbl + idglobal_tblsz + DB $6A,D0005 ; LAW D0005 + DB $2C,$00,$10 ; CW 4096 + DB $2C,$00,$08 ; CW 2048 + DB $02 ; ADD + DB $44 ; ISGT + DB $4C,C0355 ; SKPFLS C0355 +; 1644: prstr(@global_sym_overflw) + DB $26,D0636 ; LA D0636 + DB $54,C0020 ; CALL C0020 +; 1645: exit + DB $54,C0026 ; CALL C0026 +; 1646: fin +C0355: +C0356: +; 1647: datasize = datasize + size + DB $6A,D0003 ; LAW D0003 + DB $66,$08 ; LLW 8 + DB $02 ; ADD + DB $7A,D0003 ; SAW D0003 +; 1648: return TRUE + DB $2C,$FF,$FF ; CW -1 + DB $5A ; LEAVE +; 1649: end +; 1650: def iddata_size_30(type, varsize, initsize) +C0357: ; iddata_size_30() + ; type = 2 + ; varsize = 4 + ; initsize = 6 +; 1651: if varsize > initsize + JSR INTERP + DB $58,$08,$03 ; ENTER 8,3 + DB $66,$04 ; LLW 4 + DB $66,$06 ; LLW 6 + DB $44 ; ISGT + DB $4C,C0359 ; SKPFLS C0359 +; 1652: datasize = datasize + emit_data_41(0, 0, 0, varsize - initsize) + DB $6A,D0003 ; LAW D0003 + DB $00 ; ZERO + DB $00 ; ZERO + DB $00 ; ZERO + DB $66,$04 ; LLW 4 + DB $66,$06 ; LLW 6 + DB $04 ; SUB + DB $54,C0094 ; CALL C0094 + DB $02 ; ADD + DB $7A,D0003 ; SAW D0003 +; 1653: else + DB $50,C0360 ; SKIP C0360 +C0359: +; 1654: datasize = datasize + initsize + DB $6A,D0003 ; LAW D0003 + DB $66,$06 ; LLW 6 + DB $02 ; ADD + DB $7A,D0003 ; SAW D0003 +; 1655: fin +C0360: +; 1656: ; if datasize <> codeptr - codebuff +; 1657: ; prstr(@emiterr) +; 1658: ; keyin_01() +; 1659: ; fin +; 1660: end + DB $5A ; LEAVE +; 1661: def idglobal_add_41(namestr, len, type, value) +C0361: ; idglobal_add_41() + ; namestr = 2 + ; len = 4 + ; type = 6 + ; value = 8 +; 1662: if idmatch_41(namestr, len, idglobal_tbl, globals) + JSR INTERP + DB $58,$0A,$04 ; ENTER 10,4 + DB $66,$02 ; LLW 2 + DB $66,$04 ; LLW 4 + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0001 ; LAW D0001 + DB $54,C0323 ; CALL C0323 + DB $4C,C0363 ; SKPFLS C0363 +; 1663: return parse_err_11(@dup_id) + DB $26,D0431 ; LA D0431 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 1664: fin +C0363: +C0364: +; 1665: (lastglobal):idval = value + DB $6A,D0005 ; LAW D0005 + DB $66,$08 ; LLW 8 + DB $72 ; SW +; 1666: (lastglobal).idtype = type + DB $6A,D0005 ; LAW D0005 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $66,$06 ; LLW 6 + DB $70 ; SB +; 1667: nametostr_30(namestr, len, lastglobal + idname) + DB $66,$02 ; LLW 2 + DB $66,$04 ; LLW 4 + DB $6A,D0005 ; LAW D0005 + DB $2A,$03 ; CB 3 + DB $02 ; ADD + DB $54,C0060 ; CALL C0060 +; 1668: globals = globals + 1 + DB $6A,D0001 ; LAW D0001 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $7A,D0001 ; SAW D0001 +; 1669: lastglobal = lastglobal + idrecsz + len + DB $6A,D0005 ; LAW D0005 + DB $2A,$04 ; CB 4 + DB $02 ; ADD + DB $66,$04 ; LLW 4 + DB $02 ; ADD + DB $7A,D0005 ; SAW D0005 +; 1670: if lastglobal > idglobal_tbl + idglobal_tblsz + DB $6A,D0005 ; LAW D0005 + DB $2C,$00,$10 ; CW 4096 + DB $2C,$00,$08 ; CW 2048 + DB $02 ; ADD + DB $44 ; ISGT + DB $4C,C0365 ; SKPFLS C0365 +; 1671: prstr(@global_sym_overflw) + DB $26,D0636 ; LA D0636 + DB $54,C0020 ; CALL C0020 +; 1672: exit + DB $54,C0026 ; CALL C0026 +; 1673: fin +C0365: +C0366: +; 1674: return TRUE + DB $2C,$FF,$FF ; CW -1 + DB $5A ; LEAVE +; 1675: end +; 1676: def idfunc_add_31(namestr, len, tag) +C0367: ; idfunc_add_31() + ; namestr = 2 + ; len = 4 + ; tag = 6 +; 1677: return idglobal_add_41(namestr, len, FUNC_TYPE, tag) + JSR INTERP + DB $58,$08,$03 ; ENTER 8,3 + DB $66,$02 ; LLW 2 + DB $66,$04 ; LLW 4 + DB $2A,$08 ; CB 8 + DB $66,$06 ; LLW 6 + DB $54,C0361 ; CALL C0361 + DB $5A ; LEAVE +; 1678: end +; 1679: def idconst_add_31(namestr, len, value) +C0369: ; idconst_add_31() + ; namestr = 2 + ; len = 4 + ; value = 6 +; 1680: return idglobal_add_41(namestr, len, CONST_TYPE, value) + JSR INTERP + DB $58,$08,$03 ; ENTER 8,3 + DB $66,$02 ; LLW 2 + DB $66,$04 ; LLW 4 + DB $2A,$01 ; CB 1 + DB $66,$06 ; LLW 6 + DB $54,C0361 ; CALL C0361 + DB $5A ; LEAVE +; 1681: end +; 1682: def idglobal_init +C0371: ; idglobal_init() +; 1683: word ctag + ; ctag = 2 +; 1684: +; 1685: lineno = 0 + JSR INTERP + DB $58,$04,$00 ; ENTER 4,0 + DB $00 ; ZERO + DB $7A,D0421 ; SAW D0421 +; 1686: codeptr = codebuff + DB $2C,$00,$60 ; CW 24576 + DB $7A,D0014 ; SAW D0014 +; 1687: lastop = $FF + DB $2A,$FF ; CB 255 + DB $78,D0018 ; SAB D0018 +; 1688: entrypoint = 0 + DB $00 ; ZERO + DB $7A,D0016 ; SAW D0016 +; 1689: datasize = 0 + DB $00 ; ZERO + DB $7A,D0003 ; SAW D0003 +; 1690: globals = 0 + DB $00 ; ZERO + DB $7A,D0001 ; SAW D0001 +; 1691: lastglobal = idglobal_tbl + DB $2C,$00,$10 ; CW 4096 + DB $7A,D0005 ; SAW D0005 +; 1692: codetag = -1 + DB $2C,$FF,$FF ; CW -1 + DB $7A,D0012 ; SAW D0012 +; 1693: ctag = ctag_new_01() + DB $54,C0066 ; CALL C0066 + DB $76,$02 ; SLW 2 +; 1694: drop idfunc_add_31(@runtime0 + 1, runtime0, ctag) + DB $26,D0849 ; LA D0849 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0849 ; LAB D0849 + DB $66,$02 ; LLW 2 + DB $54,C0367 ; CALL C0367 + DB $30 ; DROP +; 1695: drop idfunc_add_31(@RUNTIME0 + 1, RUNTIME0, ctag) + DB $26,D0857 ; LA D0857 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0857 ; LAB D0857 + DB $66,$02 ; LLW 2 + DB $54,C0367 ; CALL C0367 + DB $30 ; DROP +; 1696: drop ctag_resolve_21(ctag, @romcall) + DB $66,$02 ; LLW 2 + DB $26,C0006 ; LA C0006 + DB $54,C0070 ; CALL C0070 + DB $30 ; DROP +; 1697: ctag = ctag_new_01() + DB $54,C0066 ; CALL C0066 + DB $76,$02 ; SLW 2 +; 1698: drop idfunc_add_31(@runtime1 + 1, runtime1, ctag) + DB $26,D0865 ; LA D0865 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0865 ; LAB D0865 + DB $66,$02 ; LLW 2 + DB $54,C0367 ; CALL C0367 + DB $30 ; DROP +; 1699: drop idfunc_add_31(@RUNTIME1 + 1, RUNTIME1, ctag) + DB $26,D0873 ; LA D0873 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0873 ; LAB D0873 + DB $66,$02 ; LLW 2 + DB $54,C0367 ; CALL C0367 + DB $30 ; DROP +; 1700: drop ctag_resolve_21(ctag, @syscall) + DB $66,$02 ; LLW 2 + DB $26,C0010 ; LA C0010 + DB $54,C0070 ; CALL C0070 + DB $30 ; DROP +; 1701: ctag = ctag_new_01() + DB $54,C0066 ; CALL C0066 + DB $76,$02 ; SLW 2 +; 1702: drop idfunc_add_31(@runtime2 + 1, runtime2, ctag) + DB $26,D0881 ; LA D0881 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0881 ; LAB D0881 + DB $66,$02 ; LLW 2 + DB $54,C0367 ; CALL C0367 + DB $30 ; DROP +; 1703: drop idfunc_add_31(@RUNTIME2 + 1, RUNTIME2, ctag) + DB $26,D0888 ; LA D0888 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0888 ; LAB D0888 + DB $66,$02 ; LLW 2 + DB $54,C0367 ; CALL C0367 + DB $30 ; DROP +; 1704: drop ctag_resolve_21(ctag, @memset) + DB $66,$02 ; LLW 2 + DB $26,C0012 ; LA C0012 + DB $54,C0070 ; CALL C0070 + DB $30 ; DROP +; 1705: ctag = ctag_new_01() + DB $54,C0066 ; CALL C0066 + DB $76,$02 ; SLW 2 +; 1706: drop idfunc_add_31(@runtime3 + 1, runtime3, ctag) + DB $26,D0895 ; LA D0895 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0895 ; LAB D0895 + DB $66,$02 ; LLW 2 + DB $54,C0367 ; CALL C0367 + DB $30 ; DROP +; 1707: drop idfunc_add_31(@RUNTIME3 + 1, RUNTIME3, ctag) + DB $26,D0902 ; LA D0902 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0902 ; LAB D0902 + DB $66,$02 ; LLW 2 + DB $54,C0367 ; CALL C0367 + DB $30 ; DROP +; 1708: drop ctag_resolve_21(ctag, @memcpy) + DB $66,$02 ; LLW 2 + DB $26,C0014 ; LA C0014 + DB $54,C0070 ; CALL C0070 + DB $30 ; DROP +; 1709: ctag = ctag_new_01() + DB $54,C0066 ; CALL C0066 + DB $76,$02 ; SLW 2 +; 1710: drop idfunc_add_31(@runtime4 + 1, runtime4, ctag) + DB $26,D0909 ; LA D0909 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0909 ; LAB D0909 + DB $66,$02 ; LLW 2 + DB $54,C0367 ; CALL C0367 + DB $30 ; DROP +; 1711: drop idfunc_add_31(@RUNTIME4 + 1, RUNTIME4, ctag) + DB $26,D0914 ; LA D0914 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0914 ; LAB D0914 + DB $66,$02 ; LLW 2 + DB $54,C0367 ; CALL C0367 + DB $30 ; DROP +; 1712: drop ctag_resolve_21(ctag, @cout) + DB $66,$02 ; LLW 2 + DB $26,C0016 ; LA C0016 + DB $54,C0070 ; CALL C0070 + DB $30 ; DROP +; 1713: ctag = ctag_new_01() + DB $54,C0066 ; CALL C0066 + DB $76,$02 ; SLW 2 +; 1714: drop idfunc_add_31(@runtime5 + 1, runtime5, ctag) + DB $26,D0919 ; LA D0919 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0919 ; LAB D0919 + DB $66,$02 ; LLW 2 + DB $54,C0367 ; CALL C0367 + DB $30 ; DROP +; 1715: drop idfunc_add_31(@RUNTIME5 + 1, RUNTIME5, ctag) + DB $26,D0923 ; LA D0923 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0923 ; LAB D0923 + DB $66,$02 ; LLW 2 + DB $54,C0367 ; CALL C0367 + DB $30 ; DROP +; 1716: drop ctag_resolve_21(ctag, @cin) + DB $66,$02 ; LLW 2 + DB $26,C0018 ; LA C0018 + DB $54,C0070 ; CALL C0070 + DB $30 ; DROP +; 1717: ctag = ctag_new_01() + DB $54,C0066 ; CALL C0066 + DB $76,$02 ; SLW 2 +; 1718: drop idfunc_add_31(@runtime6 + 1, runtime6, ctag) + DB $26,D0927 ; LA D0927 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0927 ; LAB D0927 + DB $66,$02 ; LLW 2 + DB $54,C0367 ; CALL C0367 + DB $30 ; DROP +; 1719: drop idfunc_add_31(@RUNTIME6 + 1, RUNTIME6, ctag) + DB $26,D0933 ; LA D0933 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0933 ; LAB D0933 + DB $66,$02 ; LLW 2 + DB $54,C0367 ; CALL C0367 + DB $30 ; DROP +; 1720: drop ctag_resolve_21(ctag, @prstr) + DB $66,$02 ; LLW 2 + DB $26,C0020 ; LA C0020 + DB $54,C0070 ; CALL C0070 + DB $30 ; DROP +; 1721: ctag = ctag_new_01() + DB $54,C0066 ; CALL C0066 + DB $76,$02 ; SLW 2 +; 1722: drop idfunc_add_31(@runtime7 + 1, runtime7, ctag) + DB $26,D0939 ; LA D0939 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0939 ; LAB D0939 + DB $66,$02 ; LLW 2 + DB $54,C0367 ; CALL C0367 + DB $30 ; DROP +; 1723: drop idfunc_add_31(@RUNTIME7 + 1, RUNTIME7, ctag) + DB $26,D0945 ; LA D0945 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0945 ; LAB D0945 + DB $66,$02 ; LLW 2 + DB $54,C0367 ; CALL C0367 + DB $30 ; DROP +; 1724: drop ctag_resolve_21(ctag, @rdstr) + DB $66,$02 ; LLW 2 + DB $26,C0022 ; LA C0022 + DB $54,C0070 ; CALL C0070 + DB $30 ; DROP +; 1725: end + DB $5A ; LEAVE +; 1726: def idlocal_init +C0373: ; idlocal_init() +; 1727: locals = 0 + JSR INTERP + DB $00 ; ZERO + DB $78,D0007 ; SAB D0007 +; 1728: framesize = 2 + DB $2A,$02 ; CB 2 + DB $7A,D0008 ; SAW D0008 +; 1729: lastlocal = idlocal_tbl + DB $2C,$00,$18 ; CW 6144 + DB $7A,D0010 ; SAW D0010 +; 1730: end + DB $5C ; RET +; 1731: ; +; 1732: ; Parser +; 1733: ; +; 1734: def parse_term_01 +C0375: ; parse_term_01() +; 1735: when scan_01() + JSR INTERP + DB $54,C0246 ; CALL C0246 +; 1736: is ID_TKN + DB $2A,$D6 ; CB 214 + DB $3E,C0378 ; SKPNE C0378 +; 1737: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5C ; RET +; 1738: is INT_TKN + DB $50,C0377 ; SKIP C0377 +C0378: + DB $2A,$C9 ; CB 201 + DB $3E,C0379 ; SKPNE C0379 +; 1739: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5C ; RET +; 1740: is CHR_TKN + DB $50,C0377 ; SKIP C0377 +C0379: + DB $2A,$C3 ; CB 195 + DB $3E,C0380 ; SKPNE C0380 +; 1741: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5C ; RET +; 1742: is STR_TKN + DB $50,C0377 ; SKIP C0377 +C0380: + DB $2A,$D3 ; CB 211 + DB $3E,C0381 ; SKPNE C0381 +; 1743: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5C ; RET +; 1744: is OPEN_PAREN_TKN + DB $50,C0377 ; SKIP C0377 +C0381: + DB $2A,$A8 ; CB 168 + DB $3E,C0382 ; SKPNE C0382 +; 1745: if !parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $20 ; NOT + DB $4C,C0383 ; SKPFLS C0383 +; 1746: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5C ; RET +; 1747: fin +C0383: +C0384: +; 1748: if token <> CLOSE_PAREN_TKN + DB $68,D0413 ; LAB D0413 + DB $2A,$A9 ; CB 169 + DB $42 ; ISNE + DB $4C,C0385 ; SKPFLS C0385 +; 1749: return parse_err_11(@no_close_paren) + DB $30 ; DROP + DB $26,D0713 ; LA D0713 + DB $54,C0062 ; CALL C0062 + DB $5C ; RET +; 1750: fin +C0385: +C0386: +; 1751: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5C ; RET +; 1752: wend + DB $50,C0377 ; SKIP C0377 +C0382: +C0377: + DB $30 ; DROP +; 1753: return FALSE + DB $00 ; ZERO + DB $5C ; RET +; 1754: end +; 1755: def parse_constval_21(valptr, sizeptr) +C0388: ; parse_constval_21() + ; valptr = 2 + ; sizeptr = 4 +; 1756: byte mod, type + ; mod = 6 + ; type = 7 +; 1757: word idptr + ; idptr = 8 +; 1758: +; 1759: mod = 0 + JSR INTERP + DB $58,$0A,$02 ; ENTER 10,2 + DB $00 ; ZERO + DB $74,$06 ; SLB 6 +; 1760: type = 0 + DB $00 ; ZERO + DB $74,$07 ; SLB 7 +; 1761: *valptr = 0 + DB $66,$02 ; LLW 2 + DB $00 ; ZERO + DB $72 ; SW +; 1762: while !parse_term_01() +C0390: + DB $54,C0375 ; CALL C0375 + DB $20 ; NOT + DB $4C,C0391 ; SKPFLS C0391 +; 1763: when token + DB $68,D0413 ; LAB D0413 +; 1764: is SUB_TKN + DB $2A,$AD ; CB 173 + DB $3E,C0393 ; SKPNE C0393 +; 1765: mod = mod ? 1 + DB $64,$06 ; LLB 6 + DB $2A,$01 ; CB 1 + DB $16 ; IOR + DB $74,$06 ; SLB 6 +; 1766: is COMP_TKN + DB $50,C0392 ; SKIP C0392 +C0393: + DB $2A,$A3 ; CB 163 + DB $3E,C0394 ; SKPNE C0394 +; 1767: mod = mod ? 2 + DB $64,$06 ; LLB 6 + DB $2A,$02 ; CB 2 + DB $16 ; IOR + DB $74,$06 ; SLB 6 +; 1768: is LOGIC_NOT_TKN + DB $50,C0392 ; SKIP C0392 +C0394: + DB $2A,$A1 ; CB 161 + DB $3E,C0395 ; SKPNE C0395 +; 1769: mod = mod ? 4 + DB $64,$06 ; LLB 6 + DB $2A,$04 ; CB 4 + DB $16 ; IOR + DB $74,$06 ; SLB 6 +; 1770: is AT_TKN + DB $50,C0392 ; SKIP C0392 +C0395: + DB $2A,$C0 ; CB 192 + DB $3E,C0396 ; SKPNE C0396 +; 1771: mod = mod ? 8 + DB $64,$06 ; LLB 6 + DB $2A,$08 ; CB 8 + DB $16 ; IOR + DB $74,$06 ; SLB 6 +; 1772: otherwise + DB $50,C0392 ; SKIP C0392 +C0396: +; 1773: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 1774: wend +C0392: + DB $30 ; DROP +; 1775: loop + DB $50,C0390 ; SKIP C0390 +C0391: +; 1776: when token + DB $68,D0413 ; LAB D0413 +; 1777: is STR_TKN + DB $2A,$D3 ; CB 211 + DB $3E,C0399 ; SKPNE C0399 +; 1778: *valptr = constval + DB $66,$02 ; LLW 2 + DB $6A,D0419 ; LAW D0419 + DB $72 ; SW +; 1779: ^sizeptr = tknlen - 1 + DB $66,$04 ; LLW 4 + DB $68,D0414 ; LAB D0414 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $70 ; SB +; 1780: type = STR_TYPE + DB $2A,$80 ; CB 128 + DB $74,$07 ; SLB 7 +; 1781: if mod + DB $64,$06 ; LLB 6 + DB $4C,C0400 ; SKPFLS C0400 +; 1782: return parse_err_11(@bad_op) + DB $30 ; DROP + DB $26,D0521 ; LA D0521 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 1783: fin +C0400: +C0401: +; 1784: is CHR_TKN + DB $50,C0398 ; SKIP C0398 +C0399: + DB $2A,$C3 ; CB 195 + DB $3E,C0402 ; SKPNE C0402 +; 1785: *valptr = constval + DB $66,$02 ; LLW 2 + DB $6A,D0419 ; LAW D0419 + DB $72 ; SW +; 1786: ^sizeptr = 1 + DB $66,$04 ; LLW 4 + DB $2A,$01 ; CB 1 + DB $70 ; SB +; 1787: type = BYTE_TYPE + DB $2A,$02 ; CB 2 + DB $74,$07 ; SLB 7 +; 1788: is INT_TKN + DB $50,C0398 ; SKIP C0398 +C0402: + DB $2A,$C9 ; CB 201 + DB $3E,C0403 ; SKPNE C0403 +; 1789: *valptr = constval + DB $66,$02 ; LLW 2 + DB $6A,D0419 ; LAW D0419 + DB $72 ; SW +; 1790: ^sizeptr = 2 + DB $66,$04 ; LLW 4 + DB $2A,$02 ; CB 2 + DB $70 ; SB +; 1791: type = WORD_TYPE + DB $2A,$04 ; CB 4 + DB $74,$07 ; SLB 7 +; 1792: is ID_TKN + DB $50,C0398 ; SKIP C0398 +C0403: + DB $2A,$D6 ; CB 214 + DB $3E,C0404 ; SKPNE C0404 +; 1793: ^sizeptr = 2 + DB $66,$04 ; LLW 4 + DB $2A,$02 ; CB 2 + DB $70 ; SB +; 1794: idptr = id_lookup_21(tknptr, tknlen) + DB $6A,D0417 ; LAW D0417 + DB $68,D0414 ; LAB D0414 + DB $54,C0335 ; CALL C0335 + DB $76,$08 ; SLW 8 +; 1795: if !idptr + DB $66,$08 ; LLW 8 + DB $20 ; NOT + DB $4C,C0405 ; SKPFLS C0405 +; 1796: return parse_err_11(@bad_cnst) + DB $30 ; DROP + DB $26,D0474 ; LA D0474 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 1797: fin +C0405: +C0406: +; 1798: type = (idptr).idtype + DB $66,$08 ; LLW 8 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $60 ; LB + DB $74,$07 ; SLB 7 +; 1799: *valptr = (idptr):idval + DB $66,$02 ; LLW 2 + DB $66,$08 ; LLW 8 + DB $62 ; LW + DB $72 ; SW +; 1800: if type & VAR_TYPE and !(mod & 8) + DB $64,$07 ; LLB 7 + DB $2A,$06 ; CB 6 + DB $14 ; BAND + DB $64,$06 ; LLB 6 + DB $2A,$08 ; CB 8 + DB $14 ; BAND + DB $20 ; NOT + DB $24 ; LAND + DB $4C,C0407 ; SKPFLS C0407 +; 1801: return parse_err_11(@bad_cnst) + DB $30 ; DROP + DB $26,D0474 ; LA D0474 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 1802: fin +C0407: +C0408: +; 1803: otherwise + DB $50,C0398 ; SKIP C0398 +C0404: +; 1804: return parse_err_11(@bad_cnst) + DB $30 ; DROP + DB $26,D0474 ; LA D0474 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 1805: wend +C0398: + DB $30 ; DROP +; 1806: if mod & 1 + DB $64,$06 ; LLB 6 + DB $2A,$01 ; CB 1 + DB $14 ; BAND + DB $4C,C0410 ; SKPFLS C0410 +; 1807: *valptr = -*valptr + DB $66,$02 ; LLW 2 + DB $66,$02 ; LLW 2 + DB $62 ; LW + DB $10 ; NEG + DB $72 ; SW +; 1808: fin +C0410: +C0411: +; 1809: if mod & 2 + DB $64,$06 ; LLB 6 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C0412 ; SKPFLS C0412 +; 1810: *valptr = #*valptr + DB $66,$02 ; LLW 2 + DB $66,$02 ; LLW 2 + DB $62 ; LW + DB $12 ; COMP + DB $72 ; SW +; 1811: fin +C0412: +C0413: +; 1812: if mod & 4 + DB $64,$06 ; LLB 6 + DB $2A,$04 ; CB 4 + DB $14 ; BAND + DB $4C,C0414 ; SKPFLS C0414 +; 1813: *valptr = !*valptr + DB $66,$02 ; LLW 2 + DB $66,$02 ; LLW 2 + DB $62 ; LW + DB $20 ; NOT + DB $72 ; SW +; 1814: fin +C0414: +C0415: +; 1815: return type + DB $64,$07 ; LLB 7 + DB $5A ; LEAVE +; 1816: end +; 1817: def ispostop_01 +C0416: ; ispostop_01() +; 1818: when token + JSR INTERP + DB $68,D0413 ; LAB D0413 +; 1819: is OPEN_PAREN_TKN + DB $2A,$A8 ; CB 168 + DB $3E,C0419 ; SKPNE C0419 +; 1820: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5C ; RET +; 1821: is OPEN_BRACKET_TKN + DB $50,C0418 ; SKIP C0418 +C0419: + DB $2A,$DB ; CB 219 + DB $3E,C0420 ; SKPNE C0420 +; 1822: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5C ; RET +; 1823: is DOT_TKN + DB $50,C0418 ; SKIP C0418 +C0420: + DB $2A,$AE ; CB 174 + DB $3E,C0421 ; SKPNE C0421 +; 1824: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5C ; RET +; 1825: is COLON_TKN + DB $50,C0418 ; SKIP C0418 +C0421: + DB $2A,$BA ; CB 186 + DB $3E,C0422 ; SKPNE C0422 +; 1826: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5C ; RET +; 1827: wend + DB $50,C0418 ; SKIP C0418 +C0422: +C0418: + DB $30 ; DROP +; 1828: return FALSE + DB $00 ; ZERO + DB $5C ; RET +; 1829: end +; 1830: def parse_value_11(rvalue) +C0424: ; parse_value_11() + ; rvalue = 2 +; 1831: byte cparams, deref, type, emit_val + ; cparams = 4 + ; deref = 5 + ; type = 6 + ; emit_val = 7 +; 1832: word optos, idptr, value + ; optos = 8 + ; idptr = 10 + ; value = 12 +; 1833: byte elem_type, elem_size + ; elem_type = 14 + ; elem_size = 15 +; 1834: word elem_offset + ; elem_offset = 16 +; 1835: +; 1836: deref = rvalue + JSR INTERP + DB $58,$12,$01 ; ENTER 18,1 + DB $66,$02 ; LLW 2 + DB $74,$05 ; SLB 5 +; 1837: optos = opsp + DB $6A,D0411 ; LAW D0411 + DB $76,$08 ; SLW 8 +; 1838: type = 0 + DB $00 ; ZERO + DB $74,$06 ; SLB 6 +; 1839: emit_val = 0 + DB $00 ; ZERO + DB $74,$07 ; SLB 7 +; 1840: value = 0 + DB $00 ; ZERO + DB $76,$0C ; SLW 12 +; 1841: +; 1842: ; +; 1843: ; Parse pre-ops +; 1844: ; +; 1845: while !parse_term_01() +C0426: + DB $54,C0375 ; CALL C0375 + DB $20 ; NOT + DB $4C,C0427 ; SKPFLS C0427 +; 1846: when token + DB $68,D0413 ; LAB D0413 +; 1847: is ADD_TKN + DB $2A,$AB ; CB 171 + DB $3E,C0429 ; SKPNE C0429 +; 1848: is BPTR_TKN + DB $50,C0428 ; SKIP C0428 +C0429: + DB $2A,$DE ; CB 222 + DB $3E,C0430 ; SKPNE C0430 +; 1849: if deref + DB $64,$05 ; LLB 5 + DB $4C,C0431 ; SKPFLS C0431 +; 1850: drop push_op_21(token, 0) + DB $68,D0413 ; LAB D0413 + DB $00 ; ZERO + DB $54,C0307 ; CALL C0307 + DB $30 ; DROP +; 1851: else + DB $50,C0432 ; SKIP C0432 +C0431: +; 1852: type = type ? BPTR_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$20 ; CB 32 + DB $16 ; IOR + DB $74,$06 ; SLB 6 +; 1853: deref = deref + 1 + DB $64,$05 ; LLB 5 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $74,$05 ; SLB 5 +; 1854: fin +C0432: +; 1855: is WPTR_TKN + DB $50,C0428 ; SKIP C0428 +C0430: + DB $2A,$AA ; CB 170 + DB $3E,C0433 ; SKPNE C0433 +; 1856: if deref + DB $64,$05 ; LLB 5 + DB $4C,C0434 ; SKPFLS C0434 +; 1857: drop push_op_21(token, 0) + DB $68,D0413 ; LAB D0413 + DB $00 ; ZERO + DB $54,C0307 ; CALL C0307 + DB $30 ; DROP +; 1858: else + DB $50,C0435 ; SKIP C0435 +C0434: +; 1859: type = type ? WPTR_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$40 ; CB 64 + DB $16 ; IOR + DB $74,$06 ; SLB 6 +; 1860: deref = deref + 1 + DB $64,$05 ; LLB 5 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $74,$05 ; SLB 5 +; 1861: fin +C0435: +; 1862: is AT_TKN + DB $50,C0428 ; SKIP C0428 +C0433: + DB $2A,$C0 ; CB 192 + DB $3E,C0436 ; SKPNE C0436 +; 1863: deref = deref - 1 + DB $64,$05 ; LLB 5 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $74,$05 ; SLB 5 +; 1864: is SUB_TKN + DB $50,C0428 ; SKIP C0428 +C0436: + DB $2A,$AD ; CB 173 + DB $3E,C0437 ; SKPNE C0437 +; 1865: drop push_op_21(token, 0) + DB $68,D0413 ; LAB D0413 + DB $00 ; ZERO + DB $54,C0307 ; CALL C0307 + DB $30 ; DROP +; 1866: is COMP_TKN + DB $50,C0428 ; SKIP C0428 +C0437: + DB $2A,$A3 ; CB 163 + DB $3E,C0438 ; SKPNE C0438 +; 1867: drop push_op_21(token, 0) + DB $68,D0413 ; LAB D0413 + DB $00 ; ZERO + DB $54,C0307 ; CALL C0307 + DB $30 ; DROP +; 1868: is LOGIC_NOT_TKN + DB $50,C0428 ; SKIP C0428 +C0438: + DB $2A,$A1 ; CB 161 + DB $3E,C0439 ; SKPNE C0439 +; 1869: drop push_op_21(token, 0) + DB $68,D0413 ; LAB D0413 + DB $00 ; ZERO + DB $54,C0307 ; CALL C0307 + DB $30 ; DROP +; 1870: otherwise + DB $50,C0428 ; SKIP C0428 +C0439: +; 1871: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 1872: wend +C0428: + DB $30 ; DROP +; 1873: loop + DB $50,C0426 ; SKIP C0426 +C0427: +; 1874: ; +; 1875: ; Determine terminal type +; 1876: ; +; 1877: when token + DB $68,D0413 ; LAB D0413 +; 1878: is INT_TKN + DB $2A,$C9 ; CB 201 + DB $3E,C0442 ; SKPNE C0442 +; 1879: type = type ? CONST_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$01 ; CB 1 + DB $16 ; IOR + DB $74,$06 ; SLB 6 +; 1880: value = constval + DB $6A,D0419 ; LAW D0419 + DB $76,$0C ; SLW 12 +; 1881: is CHR_TKN + DB $50,C0441 ; SKIP C0441 +C0442: + DB $2A,$C3 ; CB 195 + DB $3E,C0443 ; SKPNE C0443 +; 1882: type = type ? CONST_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$01 ; CB 1 + DB $16 ; IOR + DB $74,$06 ; SLB 6 +; 1883: value = constval + DB $6A,D0419 ; LAW D0419 + DB $76,$0C ; SLW 12 +; 1884: is ID_TKN + DB $50,C0441 ; SKIP C0441 +C0443: + DB $2A,$D6 ; CB 214 + DB $3E,C0444 ; SKPNE C0444 +; 1885: idptr = id_lookup_21(tknptr, tknlen) + DB $6A,D0417 ; LAW D0417 + DB $68,D0414 ; LAB D0414 + DB $54,C0335 ; CALL C0335 + DB $76,$0A ; SLW 10 +; 1886: if !idptr + DB $66,$0A ; LLW 10 + DB $20 ; NOT + DB $4C,C0445 ; SKPFLS C0445 +; 1887: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 1888: fin +C0445: +C0446: +; 1889: if !(idptr).idtype + DB $66,$0A ; LLW 10 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $60 ; LB + DB $20 ; NOT + DB $4C,C0447 ; SKPFLS C0447 +; 1890: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 1891: fin +C0447: +C0448: +; 1892: type = type ? (idptr).idtype + DB $64,$06 ; LLB 6 + DB $66,$0A ; LLW 10 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $60 ; LB + DB $16 ; IOR + DB $74,$06 ; SLB 6 +; 1893: value = (idptr):idval + DB $66,$0A ; LLW 10 + DB $62 ; LW + DB $76,$0C ; SLW 12 +; 1894: is CLOSE_PAREN_TKN + DB $50,C0441 ; SKIP C0441 +C0444: + DB $2A,$A9 ; CB 169 + DB $3E,C0449 ; SKPNE C0449 +; 1895: type = type ? WORD_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$04 ; CB 4 + DB $16 ; IOR + DB $74,$06 ; SLB 6 +; 1896: emit_val = 1 + DB $2A,$01 ; CB 1 + DB $74,$07 ; SLB 7 +; 1897: otherwise + DB $50,C0441 ; SKIP C0441 +C0449: +; 1898: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 1899: wend +C0441: + DB $30 ; DROP +; 1900: ; +; 1901: ; Constant optimizations +; 1902: ; +; 1903: if type & CONST_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$01 ; CB 1 + DB $14 ; BAND + DB $4C,C0451 ; SKPFLS C0451 +; 1904: cparams = TRUE + DB $2C,$FF,$FF ; CW -1 + DB $74,$04 ; SLB 4 +; 1905: while optos < opsp and cparams +C0453: + DB $66,$08 ; LLW 8 + DB $6A,D0411 ; LAW D0411 + DB $46 ; ISLT + DB $64,$04 ; LLB 4 + DB $24 ; LAND + DB $4C,C0454 ; SKPFLS C0454 +; 1906: when tos_op_01() + DB $54,C0315 ; CALL C0315 +; 1907: is NEG_TKN + DB $2A,$AD ; CB 173 + DB $3E,C0456 ; SKPNE C0456 +; 1908: drop pop_op_01() + DB $54,C0311 ; CALL C0311 + DB $30 ; DROP +; 1909: value = -value + DB $66,$0C ; LLW 12 + DB $10 ; NEG + DB $76,$0C ; SLW 12 +; 1910: is COMP_TKN + DB $50,C0455 ; SKIP C0455 +C0456: + DB $2A,$A3 ; CB 163 + DB $3E,C0457 ; SKPNE C0457 +; 1911: drop pop_op_01() + DB $54,C0311 ; CALL C0311 + DB $30 ; DROP +; 1912: value = #value + DB $66,$0C ; LLW 12 + DB $12 ; COMP + DB $76,$0C ; SLW 12 +; 1913: is LOGIC_NOT_TKN + DB $50,C0455 ; SKIP C0455 +C0457: + DB $2A,$A1 ; CB 161 + DB $3E,C0458 ; SKPNE C0458 +; 1914: drop pop_op_01() + DB $54,C0311 ; CALL C0311 + DB $30 ; DROP +; 1915: value = !value + DB $66,$0C ; LLW 12 + DB $20 ; NOT + DB $76,$0C ; SLW 12 +; 1916: otherwise + DB $50,C0455 ; SKIP C0455 +C0458: +; 1917: cparams = FALSE + DB $00 ; ZERO + DB $74,$04 ; SLB 4 +; 1918: wend +C0455: + DB $30 ; DROP +; 1919: loop + DB $50,C0453 ; SKIP C0453 +C0454: +; 1920: fin +C0451: +C0452: +; 1921: ; +; 1922: ; Parse post-ops +; 1923: ; +; 1924: drop scan_01() + DB $54,C0246 ; CALL C0246 + DB $30 ; DROP +; 1925: while ispostop_01() +C0460: + DB $54,C0416 ; CALL C0416 + DB $4C,C0461 ; SKPFLS C0461 +; 1926: if token == OPEN_BRACKET_TKN + DB $68,D0413 ; LAB D0413 + DB $2A,$DB ; CB 219 + DB $40 ; ISEQ + DB $4C,C0462 ; SKPFLS C0462 +; 1927: ; +; 1928: ; Array +; 1929: ; +; 1930: if !emit_val + DB $64,$07 ; LLB 7 + DB $20 ; NOT + DB $4C,C0464 ; SKPFLS C0464 +; 1931: if type & ADDR_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$0E ; CB 14 + DB $14 ; BAND + DB $4C,C0466 ; SKPFLS C0466 +; 1932: if type & LOCAL_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$10 ; CB 16 + DB $14 ; BAND + DB $4C,C0468 ; SKPFLS C0468 +; 1933: emit_localaddr_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0150 ; CALL C0150 +; 1934: else + DB $50,C0469 ; SKIP C0469 +C0468: +; 1935: emit_globaladdr_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0152 ; CALL C0152 +; 1936: fin +C0469: +; 1937: elsif type & CONST_TYPE + DB $50,C0467 ; SKIP C0467 +C0466: + DB $64,$06 ; LLB 6 + DB $2A,$01 ; CB 1 + DB $14 ; BAND + DB $4C,C0470 ; SKPFLS C0470 +; 1938: emit_const_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0103 ; CALL C0103 +; 1939: fin +C0470: +C0467: +; 1940: emit_val = 1 + DB $2A,$01 ; CB 1 + DB $74,$07 ; SLB 7 +; 1941: fin ; !emit_val +C0464: +C0465: +; 1942: if type & PTR_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$60 ; CB 96 + DB $14 ; BAND + DB $4C,C0471 ; SKPFLS C0471 +; 1943: emit_lw() + DB $54,C0110 ; CALL C0110 +; 1944: fin +C0471: +C0472: +; 1945: if !parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $20 ; NOT + DB $4C,C0473 ; SKPFLS C0473 +; 1946: return 0 + DB $00 ; ZERO + DB $5A ; LEAVE +; 1947: fin +C0473: +C0474: +; 1948: if token <> CLOSE_BRACKET_TKN + DB $68,D0413 ; LAB D0413 + DB $2A,$DD ; CB 221 + DB $42 ; ISNE + DB $4C,C0475 ; SKPFLS C0475 +; 1949: return parse_err_11(@no_close_bracket) + DB $26,D0735 ; LA D0735 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 1950: fin +C0475: +C0476: +; 1951: if type & WORD_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$04 ; CB 4 + DB $14 ; BAND + DB $4C,C0477 ; SKPFLS C0477 +; 1952: type = WPTR_TYPE + DB $2A,$40 ; CB 64 + DB $74,$06 ; SLB 6 +; 1953: emit_indexword() + DB $54,C0156 ; CALL C0156 +; 1954: else + DB $50,C0478 ; SKIP C0478 +C0477: +; 1955: type = BPTR_TYPE + DB $2A,$20 ; CB 32 + DB $74,$06 ; SLB 6 +; 1956: emit_indexbyte() + DB $54,C0154 ; CALL C0154 +; 1957: fin +C0478: +; 1958: drop scan_01() + DB $54,C0246 ; CALL C0246 + DB $30 ; DROP +; 1959: elsif token == DOT_TKN or token == COLON_TKN + DB $50,C0463 ; SKIP C0463 +C0462: + DB $68,D0413 ; LAB D0413 + DB $2A,$AE ; CB 174 + DB $40 ; ISEQ + DB $68,D0413 ; LAB D0413 + DB $2A,$BA ; CB 186 + DB $40 ; ISEQ + DB $22 ; LOR + DB $4C,C0479 ; SKPFLS C0479 +; 1960: ; +; 1961: ; Dot and Colon +; 1962: ; +; 1963: if token == DOT_TKN + DB $68,D0413 ; LAB D0413 + DB $2A,$AE ; CB 174 + DB $40 ; ISEQ + DB $4C,C0480 ; SKPFLS C0480 +; 1964: elem_type = BPTR_TYPE + DB $2A,$20 ; CB 32 + DB $74,$0E ; SLB 14 +; 1965: else + DB $50,C0481 ; SKIP C0481 +C0480: +; 1966: elem_type = WPTR_TYPE + DB $2A,$40 ; CB 64 + DB $74,$0E ; SLB 14 +; 1967: fin +C0481: +; 1968: if parse_constval_21(@elem_offset, @elem_size) + DB $28,$10 ; LLA 16 + DB $28,$0F ; LLA 15 + DB $54,C0388 ; CALL C0388 + DB $4C,C0482 ; SKPFLS C0482 +; 1969: ; +; 1970: ; Constant structure offset +; 1971: ; +; 1972: if !emit_val + DB $64,$07 ; LLB 7 + DB $20 ; NOT + DB $4C,C0484 ; SKPFLS C0484 +; 1973: if type & VAR_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$06 ; CB 6 + DB $14 ; BAND + DB $4C,C0486 ; SKPFLS C0486 +; 1974: if type & LOCAL_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$10 ; CB 16 + DB $14 ; BAND + DB $4C,C0488 ; SKPFLS C0488 +; 1975: emit_localaddr_10(value + elem_offset) + DB $66,$0C ; LLW 12 + DB $66,$10 ; LLW 16 + DB $02 ; ADD + DB $54,C0150 ; CALL C0150 +; 1976: else + DB $50,C0489 ; SKIP C0489 +C0488: +; 1977: ; emit_globaladdr_10(value + elem_offset) +; 1978: emit_globaladdr_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0152 ; CALL C0152 +; 1979: emit_const_10(elem_offset) + DB $66,$10 ; LLW 16 + DB $54,C0103 ; CALL C0103 +; 1980: drop emit_binaryop_11(ADD_TKN) + DB $2A,$AB ; CB 171 + DB $54,C0169 ; CALL C0169 + DB $30 ; DROP +; 1981: fin +C0489: +; 1982: elsif type & CONST_TYPE + DB $50,C0487 ; SKIP C0487 +C0486: + DB $64,$06 ; LLB 6 + DB $2A,$01 ; CB 1 + DB $14 ; BAND + DB $4C,C0490 ; SKPFLS C0490 +; 1983: value = value + elem_offset + DB $66,$0C ; LLW 12 + DB $66,$10 ; LLW 16 + DB $02 ; ADD + DB $76,$0C ; SLW 12 +; 1984: emit_const_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0103 ; CALL C0103 +; 1985: else ; FUNC_TYPE + DB $50,C0487 ; SKIP C0487 +C0490: +; 1986: emit_globaladdr_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0152 ; CALL C0152 +; 1987: emit_const_10(elem_offset) + DB $66,$10 ; LLW 16 + DB $54,C0103 ; CALL C0103 +; 1988: drop emit_binaryop_11(ADD_TKN) + DB $2A,$AB ; CB 171 + DB $54,C0169 ; CALL C0169 + DB $30 ; DROP +; 1989: fin +C0487: +; 1990: emit_val = 1 + DB $2A,$01 ; CB 1 + DB $74,$07 ; SLB 7 +; 1991: else + DB $50,C0485 ; SKIP C0485 +C0484: +; 1992: if elem_offset <> 0 + DB $66,$10 ; LLW 16 + DB $00 ; ZERO + DB $42 ; ISNE + DB $4C,C0491 ; SKPFLS C0491 +; 1993: emit_const_10(elem_offset) + DB $66,$10 ; LLW 16 + DB $54,C0103 ; CALL C0103 +; 1994: drop emit_binaryop_11(ADD_TKN) + DB $2A,$AB ; CB 171 + DB $54,C0169 ; CALL C0169 + DB $30 ; DROP +; 1995: fin +C0491: +C0492: +; 1996: fin ; !emit_val +C0485: +; 1997: drop scan_01() + DB $54,C0246 ; CALL C0246 + DB $30 ; DROP +; 1998: elsif token == OPEN_BRACKET_TKN + DB $50,C0483 ; SKIP C0483 +C0482: + DB $68,D0413 ; LAB D0413 + DB $2A,$DB ; CB 219 + DB $40 ; ISEQ + DB $4C,C0493 ; SKPFLS C0493 +; 1999: ; +; 2000: ; Array of arrays +; 2001: ; +; 2002: if !emit_val + DB $64,$07 ; LLB 7 + DB $20 ; NOT + DB $4C,C0494 ; SKPFLS C0494 +; 2003: if type & ADDR_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$0E ; CB 14 + DB $14 ; BAND + DB $4C,C0496 ; SKPFLS C0496 +; 2004: if type & LOCAL_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$10 ; CB 16 + DB $14 ; BAND + DB $4C,C0498 ; SKPFLS C0498 +; 2005: emit_localaddr_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0150 ; CALL C0150 +; 2006: else + DB $50,C0499 ; SKIP C0499 +C0498: +; 2007: emit_globaladdr_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0152 ; CALL C0152 +; 2008: fin +C0499: +; 2009: elsif type & CONST_TYPE + DB $50,C0497 ; SKIP C0497 +C0496: + DB $64,$06 ; LLB 6 + DB $2A,$01 ; CB 1 + DB $14 ; BAND + DB $4C,C0500 ; SKPFLS C0500 +; 2010: emit_const_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0103 ; CALL C0103 +; 2011: fin +C0500: +C0497: +; 2012: emit_val = 1 + DB $2A,$01 ; CB 1 + DB $74,$07 ; SLB 7 +; 2013: fin ; !emit_val +C0494: +C0495: +; 2014: repeat +C0502: +; 2015: if emit_val > 1 + DB $64,$07 ; LLB 7 + DB $2A,$01 ; CB 1 + DB $44 ; ISGT + DB $4C,C0503 ; SKPFLS C0503 +; 2016: emit_indexword() + DB $54,C0156 ; CALL C0156 +; 2017: emit_lw() + DB $54,C0110 ; CALL C0110 +; 2018: fin +C0503: +C0504: +; 2019: emit_val = emit_val + 1 + DB $64,$07 ; LLB 7 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $74,$07 ; SLB 7 +; 2020: if !parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $20 ; NOT + DB $4C,C0505 ; SKPFLS C0505 +; 2021: return parse_err_11(@bad_expr) + DB $26,D0548 ; LA D0548 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2022: fin +C0505: +C0506: +; 2023: if token <> CLOSE_BRACKET_TKN + DB $68,D0413 ; LAB D0413 + DB $2A,$DD ; CB 221 + DB $42 ; ISNE + DB $4C,C0507 ; SKPFLS C0507 +; 2024: return parse_err_11(@no_close_bracket) + DB $26,D0735 ; LA D0735 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2025: fin +C0507: +C0508: +; 2026: until scan_01() <> OPEN_BRACKET_TKN + DB $54,C0246 ; CALL C0246 + DB $2A,$DB ; CB 219 + DB $42 ; ISNE + DB $4C,C0502 ; SKPFLS C0502 +C0501: +; 2027: if elem_type & WPTR_TYPE + DB $64,$0E ; LLB 14 + DB $2A,$40 ; CB 64 + DB $14 ; BAND + DB $4C,C0509 ; SKPFLS C0509 +; 2028: emit_indexword() + DB $54,C0156 ; CALL C0156 +; 2029: else + DB $50,C0510 ; SKIP C0510 +C0509: +; 2030: emit_indexbyte() + DB $54,C0154 ; CALL C0154 +; 2031: fin +C0510: +; 2032: else + DB $50,C0483 ; SKIP C0483 +C0493: +; 2033: return parse_err_11(@bad_offset) + DB $26,D0487 ; LA D0487 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2034: fin +C0483: +; 2035: type = elem_type + DB $64,$0E ; LLB 14 + DB $74,$06 ; SLB 6 +; 2036: elsif token == OPEN_PAREN_TKN + DB $50,C0463 ; SKIP C0463 +C0479: + DB $68,D0413 ; LAB D0413 + DB $2A,$A8 ; CB 168 + DB $40 ; ISEQ + DB $4C,C0511 ; SKPFLS C0511 +; 2037: ; +; 2038: ; Function call +; 2039: ; +; 2040: if !emit_val and type & VAR_TYPE + DB $64,$07 ; LLB 7 + DB $20 ; NOT + DB $64,$06 ; LLB 6 + DB $2A,$06 ; CB 6 + DB $14 ; BAND + DB $24 ; LAND + DB $4C,C0512 ; SKPFLS C0512 +; 2041: if type & LOCAL_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$10 ; CB 16 + DB $14 ; BAND + DB $4C,C0514 ; SKPFLS C0514 +; 2042: emit_localaddr_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0150 ; CALL C0150 +; 2043: else + DB $50,C0515 ; SKIP C0515 +C0514: +; 2044: emit_globaladdr_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0152 ; CALL C0152 +; 2045: fin +C0515: +; 2046: fin +C0512: +C0513: +; 2047: if !(type & FUNC_CONST_TYPE) + DB $64,$06 ; LLB 6 + DB $2A,$09 ; CB 9 + DB $14 ; BAND + DB $20 ; NOT + DB $4C,C0516 ; SKPFLS C0516 +; 2048: emit_push() + DB $54,C0144 ; CALL C0144 +; 2049: fin +C0516: +C0517: +; 2050: drop parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $30 ; DROP +; 2051: if token <> CLOSE_PAREN_TKN + DB $68,D0413 ; LAB D0413 + DB $2A,$A9 ; CB 169 + DB $42 ; ISNE + DB $4C,C0518 ; SKPFLS C0518 +; 2052: return parse_err_11(@no_close_paren) + DB $26,D0713 ; LA D0713 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2053: fin +C0518: +C0519: +; 2054: if type & FUNC_CONST_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$09 ; CB 9 + DB $14 ; BAND + DB $4C,C0520 ; SKPFLS C0520 +; 2055: emit_call_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0140 ; CALL C0140 +; 2056: else + DB $50,C0521 ; SKIP C0521 +C0520: +; 2057: emit_pull() + DB $54,C0146 ; CALL C0146 +; 2058: emit_ical() + DB $54,C0142 ; CALL C0142 +; 2059: fin +C0521: +; 2060: emit_val = 1 + DB $2A,$01 ; CB 1 + DB $74,$07 ; SLB 7 +; 2061: type = WORD_TYPE + DB $2A,$04 ; CB 4 + DB $74,$06 ; SLB 6 +; 2062: drop scan_01() + DB $54,C0246 ; CALL C0246 + DB $30 ; DROP +; 2063: fin +C0511: +C0463: +; 2064: loop + DB $50,C0460 ; SKIP C0460 +C0461: +; 2065: if emit_val + DB $64,$07 ; LLB 7 + DB $4C,C0522 ; SKPFLS C0522 +; 2066: if rvalue + DB $66,$02 ; LLW 2 + DB $4C,C0524 ; SKPFLS C0524 +; 2067: if deref and type & PTR_TYPE + DB $64,$05 ; LLB 5 + DB $64,$06 ; LLB 6 + DB $2A,$60 ; CB 96 + DB $14 ; BAND + DB $24 ; LAND + DB $4C,C0526 ; SKPFLS C0526 +; 2068: if type & BPTR_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$20 ; CB 32 + DB $14 ; BAND + DB $4C,C0528 ; SKPFLS C0528 +; 2069: emit_lb() + DB $54,C0108 ; CALL C0108 +; 2070: else + DB $50,C0529 ; SKIP C0529 +C0528: +; 2071: emit_lw() + DB $54,C0110 ; CALL C0110 +; 2072: fin +C0529: +; 2073: fin +C0526: +C0527: +; 2074: fin +C0524: +C0525: +; 2075: else ; emit_val + DB $50,C0523 ; SKIP C0523 +C0522: +; 2076: if type & CONST_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$01 ; CB 1 + DB $14 ; BAND + DB $4C,C0530 ; SKPFLS C0530 +; 2077: emit_const_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0103 ; CALL C0103 +; 2078: elsif deref + DB $50,C0531 ; SKIP C0531 +C0530: + DB $64,$05 ; LLB 5 + DB $4C,C0532 ; SKPFLS C0532 +; 2079: if type & FUNC_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$08 ; CB 8 + DB $14 ; BAND + DB $4C,C0533 ; SKPFLS C0533 +; 2080: emit_call_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0140 ; CALL C0140 +; 2081: elsif type & VAR_TYPE + DB $50,C0534 ; SKIP C0534 +C0533: + DB $64,$06 ; LLB 6 + DB $2A,$06 ; CB 6 + DB $14 ; BAND + DB $4C,C0535 ; SKPFLS C0535 +; 2082: if type & LOCAL_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$10 ; CB 16 + DB $14 ; BAND + DB $4C,C0536 ; SKPFLS C0536 +; 2083: if type & BYTE_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C0538 ; SKPFLS C0538 +; 2084: emit_llb_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0112 ; CALL C0112 +; 2085: else + DB $50,C0539 ; SKIP C0539 +C0538: +; 2086: emit_llw_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0114 ; CALL C0114 +; 2087: fin +C0539: +; 2088: else + DB $50,C0537 ; SKIP C0537 +C0536: +; 2089: if type & BYTE_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C0540 ; SKPFLS C0540 +; 2090: emit_lab_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0116 ; CALL C0116 +; 2091: else + DB $50,C0541 ; SKIP C0541 +C0540: +; 2092: emit_law_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0118 ; CALL C0118 +; 2093: fin +C0541: +; 2094: fin +C0537: +; 2095: elsif type & PTR_TYPE + DB $50,C0534 ; SKIP C0534 +C0535: + DB $64,$06 ; LLB 6 + DB $2A,$60 ; CB 96 + DB $14 ; BAND + DB $4C,C0542 ; SKPFLS C0542 +; 2096: if type & BPTR_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$20 ; CB 32 + DB $14 ; BAND + DB $4C,C0543 ; SKPFLS C0543 +; 2097: emit_lb() + DB $54,C0108 ; CALL C0108 +; 2098: else + DB $50,C0544 ; SKIP C0544 +C0543: +; 2099: emit_lw() + DB $54,C0110 ; CALL C0110 +; 2100: fin +C0544: +; 2101: fin +C0542: +C0534: +; 2102: else + DB $50,C0531 ; SKIP C0531 +C0532: +; 2103: if type & LOCAL_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$10 ; CB 16 + DB $14 ; BAND + DB $4C,C0545 ; SKPFLS C0545 +; 2104: emit_localaddr_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0150 ; CALL C0150 +; 2105: else + DB $50,C0546 ; SKIP C0546 +C0545: +; 2106: emit_globaladdr_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0152 ; CALL C0152 +; 2107: fin +C0546: +; 2108: fin +C0531: +; 2109: fin ; emit_val +C0523: +; 2110: while optos < opsp +C0547: + DB $66,$08 ; LLW 8 + DB $6A,D0411 ; LAW D0411 + DB $46 ; ISLT + DB $4C,C0548 ; SKPFLS C0548 +; 2111: if !emit_unaryop_11(pop_op_01()) + DB $54,C0311 ; CALL C0311 + DB $54,C0158 ; CALL C0158 + DB $20 ; NOT + DB $4C,C0549 ; SKPFLS C0549 +; 2112: return parse_err_11(@bad_op) + DB $26,D0521 ; LA D0521 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2113: fin +C0549: +C0550: +; 2114: loop + DB $50,C0547 ; SKIP C0547 +C0548: +; 2115: return type + DB $64,$06 ; LLB 6 + DB $5A ; LEAVE +; 2116: end +; 2117: def parse_constexpr_21(valptr, sizeptr) +C0551: ; parse_constexpr_21() + ; valptr = 2 + ; sizeptr = 4 +; 2118: byte type, size1, size2 + ; type = 6 + ; size1 = 7 + ; size2 = 8 +; 2119: word val1, val2 + ; val1 = 9 + ; val2 = 11 +; 2120: +; 2121: type = parse_constval_21(@val1, @size1) + JSR INTERP + DB $58,$0D,$02 ; ENTER 13,2 + DB $28,$09 ; LLA 9 + DB $28,$07 ; LLA 7 + DB $54,C0388 ; CALL C0388 + DB $74,$06 ; SLB 6 +; 2122: if !type + DB $64,$06 ; LLB 6 + DB $20 ; NOT + DB $4C,C0553 ; SKPFLS C0553 +; 2123: return 0 + DB $00 ; ZERO + DB $5A ; LEAVE +; 2124: fin +C0553: +C0554: +; 2125: size2 = 0 + DB $00 ; ZERO + DB $74,$08 ; SLB 8 +; 2126: when scan_01() + DB $54,C0246 ; CALL C0246 +; 2127: is ADD_TKN + DB $2A,$AB ; CB 171 + DB $3E,C0556 ; SKPNE C0556 +; 2128: type = parse_constval_21(@val2, @size2) + DB $28,$0B ; LLA 11 + DB $28,$08 ; LLA 8 + DB $54,C0388 ; CALL C0388 + DB $74,$06 ; SLB 6 +; 2129: if !type + DB $64,$06 ; LLB 6 + DB $20 ; NOT + DB $4C,C0557 ; SKPFLS C0557 +; 2130: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2131: fin +C0557: +C0558: +; 2132: *valptr = val1 + val2 + DB $66,$02 ; LLW 2 + DB $66,$09 ; LLW 9 + DB $66,$0B ; LLW 11 + DB $02 ; ADD + DB $72 ; SW +; 2133: is SUB_TKN + DB $50,C0555 ; SKIP C0555 +C0556: + DB $2A,$AD ; CB 173 + DB $3E,C0559 ; SKPNE C0559 +; 2134: type = parse_constval_21(@val2, @size2) + DB $28,$0B ; LLA 11 + DB $28,$08 ; LLA 8 + DB $54,C0388 ; CALL C0388 + DB $74,$06 ; SLB 6 +; 2135: if !type + DB $64,$06 ; LLB 6 + DB $20 ; NOT + DB $4C,C0560 ; SKPFLS C0560 +; 2136: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2137: fin +C0560: +C0561: +; 2138: *valptr = val1 - val2 + DB $66,$02 ; LLW 2 + DB $66,$09 ; LLW 9 + DB $66,$0B ; LLW 11 + DB $04 ; SUB + DB $72 ; SW +; 2139: is MUL_TKN + DB $50,C0555 ; SKIP C0555 +C0559: + DB $2A,$AA ; CB 170 + DB $3E,C0562 ; SKPNE C0562 +; 2140: type = parse_constval_21(@val2, @size2) + DB $28,$0B ; LLA 11 + DB $28,$08 ; LLA 8 + DB $54,C0388 ; CALL C0388 + DB $74,$06 ; SLB 6 +; 2141: if !type + DB $64,$06 ; LLB 6 + DB $20 ; NOT + DB $4C,C0563 ; SKPFLS C0563 +; 2142: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2143: fin +C0563: +C0564: +; 2144: *valptr = val1 * val2 + DB $66,$02 ; LLW 2 + DB $66,$09 ; LLW 9 + DB $66,$0B ; LLW 11 + DB $06 ; MUL + DB $72 ; SW +; 2145: is DIV_TKN + DB $50,C0555 ; SKIP C0555 +C0562: + DB $2A,$AF ; CB 175 + DB $3E,C0565 ; SKPNE C0565 +; 2146: type = parse_constval_21(@val2, @size2) + DB $28,$0B ; LLA 11 + DB $28,$08 ; LLA 8 + DB $54,C0388 ; CALL C0388 + DB $74,$06 ; SLB 6 +; 2147: if !type + DB $64,$06 ; LLB 6 + DB $20 ; NOT + DB $4C,C0566 ; SKPFLS C0566 +; 2148: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2149: fin +C0566: +C0567: +; 2150: *valptr = val1 + val2 + DB $66,$02 ; LLW 2 + DB $66,$09 ; LLW 9 + DB $66,$0B ; LLW 11 + DB $02 ; ADD + DB $72 ; SW +; 2151: is MOD_TKN + DB $50,C0555 ; SKIP C0555 +C0565: + DB $2A,$A5 ; CB 165 + DB $3E,C0568 ; SKPNE C0568 +; 2152: type = parse_constval_21(@val2, @size2) + DB $28,$0B ; LLA 11 + DB $28,$08 ; LLA 8 + DB $54,C0388 ; CALL C0388 + DB $74,$06 ; SLB 6 +; 2153: if !type + DB $64,$06 ; LLB 6 + DB $20 ; NOT + DB $4C,C0569 ; SKPFLS C0569 +; 2154: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2155: fin +C0569: +C0570: +; 2156: *valptr = val1 % val2 + DB $66,$02 ; LLW 2 + DB $66,$09 ; LLW 9 + DB $66,$0B ; LLW 11 + DB $0A ; DIV,MOD + DB $72 ; SW +; 2157: drop + DB $30 ; DROP +; 2158: is AND_TKN + DB $50,C0555 ; SKIP C0555 +C0568: + DB $2A,$A6 ; CB 166 + DB $3E,C0571 ; SKPNE C0571 +; 2159: type = parse_constval_21(@val2, @size2) + DB $28,$0B ; LLA 11 + DB $28,$08 ; LLA 8 + DB $54,C0388 ; CALL C0388 + DB $74,$06 ; SLB 6 +; 2160: if !type + DB $64,$06 ; LLB 6 + DB $20 ; NOT + DB $4C,C0572 ; SKPFLS C0572 +; 2161: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2162: fin +C0572: +C0573: +; 2163: *valptr = val1 & val2 + DB $66,$02 ; LLW 2 + DB $66,$09 ; LLW 9 + DB $66,$0B ; LLW 11 + DB $14 ; BAND + DB $72 ; SW +; 2164: is OR_TKN + DB $50,C0555 ; SKIP C0555 +C0571: + DB $2A,$BF ; CB 191 + DB $3E,C0574 ; SKPNE C0574 +; 2165: type = parse_constval_21(@val2, @size2) + DB $28,$0B ; LLA 11 + DB $28,$08 ; LLA 8 + DB $54,C0388 ; CALL C0388 + DB $74,$06 ; SLB 6 +; 2166: if !type + DB $64,$06 ; LLB 6 + DB $20 ; NOT + DB $4C,C0575 ; SKPFLS C0575 +; 2167: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2168: fin +C0575: +C0576: +; 2169: *valptr = val1 ? val2 + DB $66,$02 ; LLW 2 + DB $66,$09 ; LLW 9 + DB $66,$0B ; LLW 11 + DB $16 ; IOR + DB $72 ; SW +; 2170: is EOR_TKN + DB $50,C0555 ; SKIP C0555 +C0574: + DB $2A,$DE ; CB 222 + DB $3E,C0577 ; SKPNE C0577 +; 2171: type = parse_constval_21(@val2, @size2) + DB $28,$0B ; LLA 11 + DB $28,$08 ; LLA 8 + DB $54,C0388 ; CALL C0388 + DB $74,$06 ; SLB 6 +; 2172: if !type + DB $64,$06 ; LLB 6 + DB $20 ; NOT + DB $4C,C0578 ; SKPFLS C0578 +; 2173: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2174: fin +C0578: +C0579: +; 2175: *valptr = val1 ^ val2 + DB $66,$02 ; LLW 2 + DB $66,$09 ; LLW 9 + DB $66,$0B ; LLW 11 + DB $18 ; XOR + DB $72 ; SW +; 2176: otherwise + DB $50,C0555 ; SKIP C0555 +C0577: +; 2177: *valptr = val1 + DB $66,$02 ; LLW 2 + DB $66,$09 ; LLW 9 + DB $72 ; SW +; 2178: wend +C0555: + DB $30 ; DROP +; 2179: if size1 > size2 + DB $64,$07 ; LLB 7 + DB $64,$08 ; LLB 8 + DB $44 ; ISGT + DB $4C,C0581 ; SKPFLS C0581 +; 2180: ^sizeptr = size1 + DB $66,$04 ; LLW 4 + DB $64,$07 ; LLB 7 + DB $70 ; SB +; 2181: else + DB $50,C0582 ; SKIP C0582 +C0581: +; 2182: ^sizeptr = size2 + DB $66,$04 ; LLW 4 + DB $64,$08 ; LLB 8 + DB $70 ; SB +; 2183: fin +C0582: +; 2184: return type + DB $64,$06 ; LLB 6 + DB $5A ; LEAVE +; 2185: end +; 2186: def parse_expr_01 +C0000: ; parse_expr_01() +; 2187: byte prevmatch, matchop, i + ; prevmatch = 2 + ; matchop = 3 + ; i = 4 +; 2188: word optos + ; optos = 5 +; 2189: +; 2190: matchop = 0 + JSR INTERP + DB $58,$07,$00 ; ENTER 7,0 + DB $00 ; ZERO + DB $74,$03 ; SLB 3 +; 2191: optos = opsp + DB $6A,D0411 ; LAW D0411 + DB $76,$05 ; SLW 5 +; 2192: repeat +C0585: +; 2193: prevmatch = matchop + DB $64,$03 ; LLB 3 + DB $74,$02 ; SLB 2 +; 2194: matchop = 0 + DB $00 ; ZERO + DB $74,$03 ; SLB 3 +; 2195: if parse_value_11(1) + DB $2A,$01 ; CB 1 + DB $54,C0424 ; CALL C0424 + DB $4C,C0586 ; SKPFLS C0586 +; 2196: matchop = 1 + DB $2A,$01 ; CB 1 + DB $74,$03 ; SLB 3 +; 2197: for i = 0 to bops_tblsz + DB $00 ; ZERO +C0589: + DB $6C,$04 ; DLB 4 + DB $2A,$12 ; CB 18 + DB $3A,C0588 ; SKPGT C0588 + DB $0C ; INCR +; 2198: if token == bops_tbl[i] + DB $68,D0413 ; LAB D0413 + DB $26,D0341 ; LA D0341 + DB $64,$04 ; LLB 4 + DB $02 ; IDXB + DB $60 ; LB + DB $40 ; ISEQ + DB $4C,C0590 ; SKPFLS C0590 +; 2199: matchop = 2 + DB $2A,$02 ; CB 2 + DB $74,$03 ; SLB 3 +; 2200: if bops_prec[i] >= tos_op_prec_11(optos) + DB $26,D0360 ; LA D0360 + DB $64,$04 ; LLB 4 + DB $02 ; IDXB + DB $60 ; LB + DB $66,$05 ; LLW 5 + DB $54,C0319 ; CALL C0319 + DB $48 ; ISGE + DB $4C,C0592 ; SKPFLS C0592 +; 2201: if !emit_binaryop_11(pop_op_01()) + DB $54,C0311 ; CALL C0311 + DB $54,C0169 ; CALL C0169 + DB $20 ; NOT + DB $4C,C0594 ; SKPFLS C0594 +; 2202: return parse_err_11(@bad_op) + DB $30 ; DROP + DB $26,D0521 ; LA D0521 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2203: fin +C0594: +C0595: +; 2204: fin +C0592: +C0593: +; 2205: drop push_op_21(token, bops_prec[i]) + DB $68,D0413 ; LAB D0413 + DB $26,D0360 ; LA D0360 + DB $64,$04 ; LLB 4 + DB $02 ; IDXB + DB $60 ; LB + DB $54,C0307 ; CALL C0307 + DB $30 ; DROP +; 2206: break + DB $50,C0588 ; SKIP C0588 +; 2207: fin +C0590: +C0591: +; 2208: next + DB $50,C0589 ; SKIP C0589 +C0588: + DB $30 ; DROP +; 2209: fin +C0586: +C0587: +; 2210: until matchop <> 2 + DB $64,$03 ; LLB 3 + DB $2A,$02 ; CB 2 + DB $42 ; ISNE + DB $4C,C0585 ; SKPFLS C0585 +C0584: +; 2211: if matchop == 0 and prevmatch == 2 + DB $64,$03 ; LLB 3 + DB $00 ; ZERO + DB $40 ; ISEQ + DB $64,$02 ; LLB 2 + DB $2A,$02 ; CB 2 + DB $40 ; ISEQ + DB $24 ; LAND + DB $4C,C0596 ; SKPFLS C0596 +; 2212: return parse_err_11(@missing_op) + DB $26,D0759 ; LA D0759 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2213: fin +C0596: +C0597: +; 2214: while optos < opsp +C0598: + DB $66,$05 ; LLW 5 + DB $6A,D0411 ; LAW D0411 + DB $46 ; ISLT + DB $4C,C0599 ; SKPFLS C0599 +; 2215: if !emit_binaryop_11(pop_op_01()) + DB $54,C0311 ; CALL C0311 + DB $54,C0169 ; CALL C0169 + DB $20 ; NOT + DB $4C,C0600 ; SKPFLS C0600 +; 2216: return parse_err_11(@bad_op) + DB $26,D0521 ; LA D0521 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2217: fin +C0600: +C0601: +; 2218: loop + DB $50,C0598 ; SKIP C0598 +C0599: +; 2219: return matchop or prevmatch + DB $64,$03 ; LLB 3 + DB $64,$02 ; LLB 2 + DB $22 ; LOR + DB $5A ; LEAVE +; 2220: end +; 2221: def parse_setlist_21(addr, type) +C0602: ; parse_setlist_21() + ; addr = 2 + ; type = 4 +; 2222: word nexttype, nextaddr, idptr, saveptr + ; nexttype = 6 + ; nextaddr = 8 + ; idptr = 10 + ; saveptr = 12 +; 2223: +; 2224: if !(type & VAR_TYPE) + JSR INTERP + DB $58,$0E,$02 ; ENTER 14,2 + DB $66,$04 ; LLW 4 + DB $2A,$06 ; CB 6 + DB $14 ; BAND + DB $20 ; NOT + DB $4C,C0604 ; SKPFLS C0604 +; 2225: emit_push() + DB $54,C0144 ; CALL C0144 +; 2226: fin +C0604: +C0605: +; 2227: nexttype = 0 + DB $00 ; ZERO + DB $76,$06 ; SLW 6 +; 2228: nextaddr = 0 + DB $00 ; ZERO + DB $76,$08 ; SLW 8 +; 2229: if scan_01() == ID_TKN + DB $54,C0246 ; CALL C0246 + DB $2A,$D6 ; CB 214 + DB $40 ; ISEQ + DB $4C,C0606 ; SKPFLS C0606 +; 2230: idptr = id_lookup_21(tknptr, tknlen) + DB $6A,D0417 ; LAW D0417 + DB $68,D0414 ; LAB D0414 + DB $54,C0335 ; CALL C0335 + DB $76,$0A ; SLW 10 +; 2231: if !idptr + DB $66,$0A ; LLW 10 + DB $20 ; NOT + DB $4C,C0608 ; SKPFLS C0608 +; 2232: return FALSE + DB $00 ; ZERO + DB $5A ; LEAVE +; 2233: fin +C0608: +C0609: +; 2234: nexttype = (idptr).idtype + DB $66,$0A ; LLW 10 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $60 ; LB + DB $76,$06 ; SLW 6 +; 2235: if type & VAR_TYPE + DB $66,$04 ; LLW 4 + DB $2A,$06 ; CB 6 + DB $14 ; BAND + DB $4C,C0610 ; SKPFLS C0610 +; 2236: nextaddr = (idptr):idval + DB $66,$0A ; LLW 10 + DB $62 ; LW + DB $76,$08 ; SLW 8 +; 2237: fin +C0610: +C0611: +; 2238: fin +C0606: +C0607: +; 2239: saveptr = tknptr + DB $6A,D0417 ; LAW D0417 + DB $76,$0C ; SLW 12 +; 2240: drop scan_01() + DB $54,C0246 ; CALL C0246 + DB $30 ; DROP +; 2241: if nexttype & VAR_TYPE and token == SET_TKN + DB $66,$06 ; LLW 6 + DB $2A,$06 ; CB 6 + DB $14 ; BAND + DB $68,D0413 ; LAB D0413 + DB $2A,$BD ; CB 189 + DB $40 ; ISEQ + DB $24 ; LAND + DB $4C,C0612 ; SKPFLS C0612 +; 2242: drop parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $30 ; DROP +; 2243: if type & LOCAL_TYPE + DB $66,$04 ; LLW 4 + DB $2A,$10 ; CB 16 + DB $14 ; BAND + DB $4C,C0614 ; SKPFLS C0614 +; 2244: if type & BYTE_TYPE + DB $66,$04 ; LLW 4 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C0616 ; SKPFLS C0616 +; 2245: emit_slb_10(nextaddr) + DB $66,$08 ; LLW 8 + DB $54,C0124 ; CALL C0124 +; 2246: else + DB $50,C0617 ; SKIP C0617 +C0616: +; 2247: emit_slw_10(nextaddr) + DB $66,$08 ; LLW 8 + DB $54,C0126 ; CALL C0126 +; 2248: fin +C0617: +; 2249: else + DB $50,C0615 ; SKIP C0615 +C0614: +; 2250: if type & BYTE_TYPE + DB $66,$04 ; LLW 4 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C0618 ; SKPFLS C0618 +; 2251: emit_sab_10(nextaddr) + DB $66,$08 ; LLW 8 + DB $54,C0132 ; CALL C0132 +; 2252: else + DB $50,C0619 ; SKIP C0619 +C0618: +; 2253: emit_saw_10(nextaddr) + DB $66,$08 ; LLW 8 + DB $54,C0134 ; CALL C0134 +; 2254: fin +C0619: +; 2255: fin +C0615: +; 2256: elsif nexttype & VAR_TYPE and token == SETLIST_TKN + DB $50,C0613 ; SKIP C0613 +C0612: + DB $66,$06 ; LLW 6 + DB $2A,$06 ; CB 6 + DB $14 ; BAND + DB $68,D0413 ; LAB D0413 + DB $2A,$B9 ; CB 185 + DB $40 ; ISEQ + DB $24 ; LAND + DB $4C,C0620 ; SKPFLS C0620 +; 2257: if !parse_setlist_21(nextaddr, nexttype) + DB $66,$08 ; LLW 8 + DB $66,$06 ; LLW 6 + DB $54,C0602 ; CALL C0602 + DB $20 ; NOT + DB $4C,C0621 ; SKPFLS C0621 +; 2258: return FALSE + DB $00 ; ZERO + DB $5A ; LEAVE +; 2259: fin +C0621: +C0622: +; 2260: else + DB $50,C0613 ; SKIP C0613 +C0620: +; 2261: tknptr = saveptr + DB $66,$0C ; LLW 12 + DB $7A,D0417 ; SAW D0417 +; 2262: rewind_10(tknptr) + DB $6A,D0417 ; LAW D0417 + DB $54,C0299 ; CALL C0299 +; 2263: nexttype = parse_value_11(0) + DB $00 ; ZERO + DB $54,C0424 ; CALL C0424 + DB $76,$06 ; SLW 6 +; 2264: if nexttype <> 0 + DB $66,$06 ; LLW 6 + DB $00 ; ZERO + DB $42 ; ISNE + DB $4C,C0623 ; SKPFLS C0623 +; 2265: if token == SET_TKN + DB $68,D0413 ; LAB D0413 + DB $2A,$BD ; CB 189 + DB $40 ; ISEQ + DB $4C,C0625 ; SKPFLS C0625 +; 2266: emit_push() + DB $54,C0144 ; CALL C0144 +; 2267: drop parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $30 ; DROP +; 2268: emit_pull() + DB $54,C0146 ; CALL C0146 +; 2269: emit_swap() + DB $54,C0214 ; CALL C0214 +; 2270: if nexttype & (BYTE_TYPE ? BPTR_TYPE) + DB $66,$06 ; LLW 6 + DB $2A,$02 ; CB 2 + DB $2A,$20 ; CB 32 + DB $16 ; IOR + DB $14 ; BAND + DB $4C,C0627 ; SKPFLS C0627 +; 2271: emit_sb() + DB $54,C0120 ; CALL C0120 +; 2272: else + DB $50,C0628 ; SKIP C0628 +C0627: +; 2273: emit_sw() + DB $54,C0122 ; CALL C0122 +; 2274: fin +C0628: +; 2275: fin +C0625: +C0626: +; 2276: elsif token == SETLIST_TKN + DB $50,C0624 ; SKIP C0624 +C0623: + DB $68,D0413 ; LAB D0413 + DB $2A,$B9 ; CB 185 + DB $40 ; ISEQ + DB $4C,C0629 ; SKPFLS C0629 +; 2277: if !parse_setlist_21(0, nexttype) + DB $00 ; ZERO + DB $66,$06 ; LLW 6 + DB $54,C0602 ; CALL C0602 + DB $20 ; NOT + DB $4C,C0630 ; SKPFLS C0630 +; 2278: return FALSE + DB $00 ; ZERO + DB $5A ; LEAVE +; 2279: fin +C0630: +C0631: +; 2280: else + DB $50,C0624 ; SKIP C0624 +C0629: +; 2281: return parse_err_11(@bad_syntax) + DB $26,D0563 ; LA D0563 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2282: fin +C0624: +; 2283: fin +C0613: +; 2284: if type & VAR_TYPE + DB $66,$04 ; LLW 4 + DB $2A,$06 ; CB 6 + DB $14 ; BAND + DB $4C,C0632 ; SKPFLS C0632 +; 2285: if type & LOCAL_TYPE + DB $66,$04 ; LLW 4 + DB $2A,$10 ; CB 16 + DB $14 ; BAND + DB $4C,C0634 ; SKPFLS C0634 +; 2286: if type & BYTE_TYPE + DB $66,$04 ; LLW 4 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C0636 ; SKPFLS C0636 +; 2287: emit_slb_10(addr) + DB $66,$02 ; LLW 2 + DB $54,C0124 ; CALL C0124 +; 2288: else + DB $50,C0637 ; SKIP C0637 +C0636: +; 2289: emit_slw_10(addr) + DB $66,$02 ; LLW 2 + DB $54,C0126 ; CALL C0126 +; 2290: fin +C0637: +; 2291: else + DB $50,C0635 ; SKIP C0635 +C0634: +; 2292: if type & BYTE_TYPE + DB $66,$04 ; LLW 4 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C0638 ; SKPFLS C0638 +; 2293: emit_sab_10(addr) + DB $66,$02 ; LLW 2 + DB $54,C0132 ; CALL C0132 +; 2294: else + DB $50,C0639 ; SKIP C0639 +C0638: +; 2295: emit_saw_10(addr) + DB $66,$02 ; LLW 2 + DB $54,C0134 ; CALL C0134 +; 2296: fin +C0639: +; 2297: fin +C0635: +; 2298: else + DB $50,C0633 ; SKIP C0633 +C0632: +; 2299: emit_pull() + DB $54,C0146 ; CALL C0146 +; 2300: emit_swap() + DB $54,C0214 ; CALL C0214 +; 2301: if type & (BYTE_TYPE ? BPTR_TYPE) + DB $66,$04 ; LLW 4 + DB $2A,$02 ; CB 2 + DB $2A,$20 ; CB 32 + DB $16 ; IOR + DB $14 ; BAND + DB $4C,C0640 ; SKPFLS C0640 +; 2302: emit_sb() + DB $54,C0120 ; CALL C0120 +; 2303: else + DB $50,C0641 ; SKIP C0641 +C0640: +; 2304: emit_sw() + DB $54,C0122 ; CALL C0122 +; 2305: fin +C0641: +; 2306: fin +C0633: +; 2307: return TRUE + DB $2C,$FF,$FF ; CW -1 + DB $5A ; LEAVE +; 2308: end +; 2309: def parse_stmnt_01 +C0642: ; parse_stmnt_01() +; 2310: byte type, i + ; type = 2 + ; i = 3 +; 2311: word tag_prevbrk, tag_else, tag_endif, tag_while, tag_wend + ; tag_prevbrk = 4 + ; tag_else = 6 + ; tag_endif = 8 + ; tag_while = 10 + ; tag_wend = 12 +; 2312: word tag_repeat, tag_for, tag_choice, idptr, saveptr, addr, stepdir + ; tag_repeat = 14 + ; tag_for = 16 + ; tag_choice = 18 + ; idptr = 20 + ; saveptr = 22 + ; addr = 24 + ; stepdir = 26 +; 2313: +; 2314: if token <> END_TKN and token <> DONE_TKN + JSR INTERP + DB $58,$1C,$00 ; ENTER 28,0 + DB $68,D0413 ; LAB D0413 + DB $2A,$87 ; CB 135 + DB $42 ; ISNE + DB $68,D0413 ; LAB D0413 + DB $2A,$98 ; CB 152 + DB $42 ; ISNE + DB $24 ; LAND + DB $4C,C0644 ; SKPFLS C0644 +; 2315: prevstmnt = token + DB $68,D0413 ; LAB D0413 + DB $78,D0953 ; SAB D0953 +; 2316: fin +C0644: +C0645: +; 2317: when token + DB $68,D0413 ; LAB D0413 +; 2318: is IF_TKN + DB $2A,$83 ; CB 131 + DB $3E,C0647 ; SKPNE C0647 +; 2319: drop parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $30 ; DROP +; 2320: tag_else = ctag_new_01() + DB $54,C0066 ; CALL C0066 + DB $76,$06 ; SLW 6 +; 2321: tag_endif = ctag_new_01() + DB $54,C0066 ; CALL C0066 + DB $76,$08 ; SLW 8 +; 2322: emit_brfls_10(tag_else) + DB $66,$06 ; LLW 6 + DB $54,C0202 ; CALL C0202 +; 2323: drop scan_01() + DB $54,C0246 ; CALL C0246 + DB $30 ; DROP +; 2324: repeat +C0649: +; 2325: while parse_stmnt_01() +C0650: + DB $54,C0642 ; CALL C0642 + DB $4C,C0651 ; SKPFLS C0651 +; 2326: drop nextln_01() + DB $54,C0301 ; CALL C0301 + DB $30 ; DROP +; 2327: loop + DB $50,C0650 ; SKIP C0650 +C0651: +; 2328: if token <> ELSEIF_TKN + DB $68,D0413 ; LAB D0413 + DB $2A,$84 ; CB 132 + DB $42 ; ISNE + DB $4C,C0652 ; SKPFLS C0652 +; 2329: break + DB $50,C0648 ; SKIP C0648 +; 2330: fin +C0652: +C0653: +; 2331: emit_jump_10(tag_endif) + DB $66,$08 ; LLW 8 + DB $54,C0210 ; CALL C0210 +; 2332: emit_codetag_10(tag_else) + DB $66,$06 ; LLW 6 + DB $54,C0082 ; CALL C0082 +; 2333: if !parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $20 ; NOT + DB $4C,C0654 ; SKPFLS C0654 +; 2334: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2335: fin +C0654: +C0655: +; 2336: tag_else = ctag_new_01() + DB $54,C0066 ; CALL C0066 + DB $76,$06 ; SLW 6 +; 2337: emit_brfls_10(tag_else) + DB $66,$06 ; LLW 6 + DB $54,C0202 ; CALL C0202 +; 2338: until FALSE + DB $00 ; ZERO + DB $4C,C0649 ; SKPFLS C0649 +C0648: +; 2339: if token == ELSE_TKN + DB $68,D0413 ; LAB D0413 + DB $2A,$85 ; CB 133 + DB $40 ; ISEQ + DB $4C,C0656 ; SKPFLS C0656 +; 2340: emit_jump_10(tag_endif) + DB $66,$08 ; LLW 8 + DB $54,C0210 ; CALL C0210 +; 2341: emit_codetag_10(tag_else) + DB $66,$06 ; LLW 6 + DB $54,C0082 ; CALL C0082 +; 2342: drop scan_01() + DB $54,C0246 ; CALL C0246 + DB $30 ; DROP +; 2343: while parse_stmnt_01() +C0658: + DB $54,C0642 ; CALL C0642 + DB $4C,C0659 ; SKPFLS C0659 +; 2344: drop nextln_01() + DB $54,C0301 ; CALL C0301 + DB $30 ; DROP +; 2345: loop + DB $50,C0658 ; SKIP C0658 +C0659: +; 2346: emit_codetag_10(tag_endif) + DB $66,$08 ; LLW 8 + DB $54,C0082 ; CALL C0082 +; 2347: else + DB $50,C0657 ; SKIP C0657 +C0656: +; 2348: emit_codetag_10(tag_else) + DB $66,$06 ; LLW 6 + DB $54,C0082 ; CALL C0082 +; 2349: emit_codetag_10(tag_endif) + DB $66,$08 ; LLW 8 + DB $54,C0082 ; CALL C0082 +; 2350: fin +C0657: +; 2351: if token <> FIN_TKN + DB $68,D0413 ; LAB D0413 + DB $2A,$86 ; CB 134 + DB $42 ; ISNE + DB $4C,C0660 ; SKPFLS C0660 +; 2352: return parse_err_11(@no_fin) + DB $30 ; DROP + DB $26,D0775 ; LA D0775 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2353: fin +C0660: +C0661: +; 2354: is FOR_TKN + DB $50,C0646 ; SKIP C0646 +C0647: + DB $2A,$8E ; CB 142 + DB $3E,C0662 ; SKPNE C0662 +; 2355: stack_loop = stack_loop + 1 + DB $68,D0952 ; LAB D0952 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $78,D0952 ; SAB D0952 +; 2356: tag_for = ctag_new_01() + DB $54,C0066 ; CALL C0066 + DB $76,$10 ; SLW 16 +; 2357: tag_prevbrk = break_tag + DB $6A,D0956 ; LAW D0956 + DB $76,$04 ; SLW 4 +; 2358: break_tag = ctag_new_01() + DB $54,C0066 ; CALL C0066 + DB $7A,D0956 ; SAW D0956 +; 2359: if scan_01() <> ID_TKN + DB $54,C0246 ; CALL C0246 + DB $2A,$D6 ; CB 214 + DB $42 ; ISNE + DB $4C,C0663 ; SKPFLS C0663 +; 2360: return parse_err_11(@bad_stmnt) + DB $30 ; DROP + DB $26,D0535 ; LA D0535 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2361: fin +C0663: +C0664: +; 2362: idptr = id_lookup_21(tknptr, tknlen) + DB $6A,D0417 ; LAW D0417 + DB $68,D0414 ; LAB D0414 + DB $54,C0335 ; CALL C0335 + DB $76,$14 ; SLW 20 +; 2363: if idptr + DB $66,$14 ; LLW 20 + DB $4C,C0665 ; SKPFLS C0665 +; 2364: type = (idptr).idtype + DB $66,$14 ; LLW 20 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $60 ; LB + DB $74,$02 ; SLB 2 +; 2365: addr = (idptr):idval + DB $66,$14 ; LLW 20 + DB $62 ; LW + DB $76,$18 ; SLW 24 +; 2366: else + DB $50,C0666 ; SKIP C0666 +C0665: +; 2367: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2368: fin +C0666: +; 2369: if scan_01() <> SET_TKN + DB $54,C0246 ; CALL C0246 + DB $2A,$BD ; CB 189 + DB $42 ; ISNE + DB $4C,C0667 ; SKPFLS C0667 +; 2370: return parse_err_11(@bad_stmnt) + DB $30 ; DROP + DB $26,D0535 ; LA D0535 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2371: fin +C0667: +C0668: +; 2372: if !parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $20 ; NOT + DB $4C,C0669 ; SKPFLS C0669 +; 2373: return parse_err_11(@bad_stmnt) + DB $30 ; DROP + DB $26,D0535 ; LA D0535 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2374: fin +C0669: +C0670: +; 2375: emit_codetag_10(tag_for) + DB $66,$10 ; LLW 16 + DB $54,C0082 ; CALL C0082 +; 2376: if type & LOCAL_TYPE + DB $64,$02 ; LLB 2 + DB $2A,$10 ; CB 16 + DB $14 ; BAND + DB $4C,C0671 ; SKPFLS C0671 +; 2377: if type & BYTE_TYPE + DB $64,$02 ; LLB 2 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C0673 ; SKPFLS C0673 +; 2378: emit_dlb_10(addr) + DB $66,$18 ; LLW 24 + DB $54,C0128 ; CALL C0128 +; 2379: else + DB $50,C0674 ; SKIP C0674 +C0673: +; 2380: emit_dlw_10(addr) + DB $66,$18 ; LLW 24 + DB $54,C0130 ; CALL C0130 +; 2381: fin +C0674: +; 2382: else + DB $50,C0672 ; SKIP C0672 +C0671: +; 2383: if type & BYTE_TYPE + DB $64,$02 ; LLB 2 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C0675 ; SKPFLS C0675 +; 2384: emit_dab_10(addr) + DB $66,$18 ; LLW 24 + DB $54,C0136 ; CALL C0136 +; 2385: else + DB $50,C0676 ; SKIP C0676 +C0675: +; 2386: emit_daw_10(addr) + DB $66,$18 ; LLW 24 + DB $54,C0138 ; CALL C0138 +; 2387: fin +C0676: +; 2388: fin +C0672: +; 2389: stepdir = 1 + DB $2A,$01 ; CB 1 + DB $76,$1A ; SLW 26 +; 2390: if token == TO_TKN + DB $68,D0413 ; LAB D0413 + DB $2A,$8F ; CB 143 + DB $40 ; ISEQ + DB $4C,C0677 ; SKPFLS C0677 +; 2391: drop parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $30 ; DROP +; 2392: elsif token == DOWNTO_TKN + DB $50,C0678 ; SKIP C0678 +C0677: + DB $68,D0413 ; LAB D0413 + DB $2A,$90 ; CB 144 + DB $40 ; ISEQ + DB $4C,C0679 ; SKPFLS C0679 +; 2393: drop parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $30 ; DROP +; 2394: stepdir = -1 + DB $2C,$FF,$FF ; CW -1 + DB $76,$1A ; SLW 26 +; 2395: fin +C0679: +C0678: +; 2396: if stepdir > 0 + DB $66,$1A ; LLW 26 + DB $00 ; ZERO + DB $44 ; ISGT + DB $4C,C0680 ; SKPFLS C0680 +; 2397: emit_brgt_10(break_tag) + DB $6A,D0956 ; LAW D0956 + DB $54,C0204 ; CALL C0204 +; 2398: else + DB $50,C0681 ; SKIP C0681 +C0680: +; 2399: emit_brlt_10(break_tag) + DB $6A,D0956 ; LAW D0956 + DB $54,C0206 ; CALL C0206 +; 2400: fin +C0681: +; 2401: if token == STEP_TKN + DB $68,D0413 ; LAB D0413 + DB $2A,$91 ; CB 145 + DB $40 ; ISEQ + DB $4C,C0682 ; SKPFLS C0682 +; 2402: drop parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $30 ; DROP +; 2403: if stepdir > 0 + DB $66,$1A ; LLW 26 + DB $00 ; ZERO + DB $44 ; ISGT + DB $4C,C0684 ; SKPFLS C0684 +; 2404: drop emit_binaryop_11(ADD_TKN) + DB $2A,$AB ; CB 171 + DB $54,C0169 ; CALL C0169 + DB $30 ; DROP +; 2405: else + DB $50,C0685 ; SKIP C0685 +C0684: +; 2406: drop emit_binaryop_11(SUB_TKN) + DB $2A,$AD ; CB 173 + DB $54,C0169 ; CALL C0169 + DB $30 ; DROP +; 2407: fin +C0685: +; 2408: else + DB $50,C0683 ; SKIP C0683 +C0682: +; 2409: if stepdir > 0 + DB $66,$1A ; LLW 26 + DB $00 ; ZERO + DB $44 ; ISGT + DB $4C,C0686 ; SKPFLS C0686 +; 2410: drop emit_unaryop_11(INC_TKN) + DB $2A,$C1 ; CB 193 + DB $54,C0158 ; CALL C0158 + DB $30 ; DROP +; 2411: else + DB $50,C0687 ; SKIP C0687 +C0686: +; 2412: drop emit_unaryop_11(DEC_TKN) + DB $2A,$C4 ; CB 196 + DB $54,C0158 ; CALL C0158 + DB $30 ; DROP +; 2413: fin +C0687: +; 2414: fin +C0683: +; 2415: while parse_stmnt_01() +C0688: + DB $54,C0642 ; CALL C0642 + DB $4C,C0689 ; SKPFLS C0689 +; 2416: drop nextln_01() + DB $54,C0301 ; CALL C0301 + DB $30 ; DROP +; 2417: loop + DB $50,C0688 ; SKIP C0688 +C0689: +; 2418: if token <> NEXT_TKN + DB $68,D0413 ; LAB D0413 + DB $2A,$92 ; CB 146 + DB $42 ; ISNE + DB $4C,C0690 ; SKPFLS C0690 +; 2419: return parse_err_11(@bad_stmnt) + DB $30 ; DROP + DB $26,D0535 ; LA D0535 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2420: fin +C0690: +C0691: +; 2421: emit_jump_10(tag_for) + DB $66,$10 ; LLW 16 + DB $54,C0210 ; CALL C0210 +; 2422: emit_codetag_10(break_tag) + DB $6A,D0956 ; LAW D0956 + DB $54,C0082 ; CALL C0082 +; 2423: emit_drop() + DB $54,C0212 ; CALL C0212 +; 2424: break_tag = tag_prevbrk + DB $66,$04 ; LLW 4 + DB $7A,D0956 ; SAW D0956 +; 2425: stack_loop = stack_loop - 1 + DB $68,D0952 ; LAB D0952 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $78,D0952 ; SAB D0952 +; 2426: is WHILE_TKN + DB $50,C0646 ; SKIP C0646 +C0662: + DB $2A,$88 ; CB 136 + DB $3E,C0692 ; SKPNE C0692 +; 2427: tag_while = ctag_new_01() + DB $54,C0066 ; CALL C0066 + DB $76,$0A ; SLW 10 +; 2428: tag_wend = ctag_new_01() + DB $54,C0066 ; CALL C0066 + DB $76,$0C ; SLW 12 +; 2429: tag_prevbrk = break_tag + DB $6A,D0956 ; LAW D0956 + DB $76,$04 ; SLW 4 +; 2430: break_tag = tag_wend + DB $66,$0C ; LLW 12 + DB $7A,D0956 ; SAW D0956 +; 2431: emit_codetag_10(tag_while) + DB $66,$0A ; LLW 10 + DB $54,C0082 ; CALL C0082 +; 2432: drop parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $30 ; DROP +; 2433: emit_brfls_10(tag_wend) + DB $66,$0C ; LLW 12 + DB $54,C0202 ; CALL C0202 +; 2434: while parse_stmnt_01() +C0693: + DB $54,C0642 ; CALL C0642 + DB $4C,C0694 ; SKPFLS C0694 +; 2435: drop nextln_01() + DB $54,C0301 ; CALL C0301 + DB $30 ; DROP +; 2436: loop + DB $50,C0693 ; SKIP C0693 +C0694: +; 2437: if token <> LOOP_TKN + DB $68,D0413 ; LAB D0413 + DB $2A,$89 ; CB 137 + DB $42 ; ISNE + DB $4C,C0695 ; SKPFLS C0695 +; 2438: return parse_err_11(@no_loop) + DB $30 ; DROP + DB $26,D0787 ; LA D0787 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2439: fin +C0695: +C0696: +; 2440: emit_jump_10(tag_while) + DB $66,$0A ; LLW 10 + DB $54,C0210 ; CALL C0210 +; 2441: emit_codetag_10(tag_wend) + DB $66,$0C ; LLW 12 + DB $54,C0082 ; CALL C0082 +; 2442: break_tag = tag_prevbrk + DB $66,$04 ; LLW 4 + DB $7A,D0956 ; SAW D0956 +; 2443: is REPEAT_TKN + DB $50,C0646 ; SKIP C0646 +C0692: + DB $2A,$93 ; CB 147 + DB $3E,C0697 ; SKPNE C0697 +; 2444: tag_repeat = ctag_new_01() + DB $54,C0066 ; CALL C0066 + DB $76,$0E ; SLW 14 +; 2445: tag_prevbrk = break_tag + DB $6A,D0956 ; LAW D0956 + DB $76,$04 ; SLW 4 +; 2446: break_tag = ctag_new_01() + DB $54,C0066 ; CALL C0066 + DB $7A,D0956 ; SAW D0956 +; 2447: emit_codetag_10(tag_repeat) + DB $66,$0E ; LLW 14 + DB $54,C0082 ; CALL C0082 +; 2448: drop scan_01() + DB $54,C0246 ; CALL C0246 + DB $30 ; DROP +; 2449: while parse_stmnt_01() +C0698: + DB $54,C0642 ; CALL C0642 + DB $4C,C0699 ; SKPFLS C0699 +; 2450: drop nextln_01() + DB $54,C0301 ; CALL C0301 + DB $30 ; DROP +; 2451: loop + DB $50,C0698 ; SKIP C0698 +C0699: +; 2452: if token <> UNTIL_TKN + DB $68,D0413 ; LAB D0413 + DB $2A,$94 ; CB 148 + DB $42 ; ISNE + DB $4C,C0700 ; SKPFLS C0700 +; 2453: return parse_err_11(@no_until) + DB $30 ; DROP + DB $26,D0800 ; LA D0800 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2454: fin +C0700: +C0701: +; 2455: drop parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $30 ; DROP +; 2456: emit_brfls_10(tag_repeat) + DB $66,$0E ; LLW 14 + DB $54,C0202 ; CALL C0202 +; 2457: emit_codetag_10(break_tag) + DB $6A,D0956 ; LAW D0956 + DB $54,C0082 ; CALL C0082 +; 2458: break_tag = tag_prevbrk + DB $66,$04 ; LLW 4 + DB $7A,D0956 ; SAW D0956 +; 2459: is CASE_TKN + DB $50,C0646 ; SKIP C0646 +C0697: + DB $2A,$8A ; CB 138 + DB $3E,C0702 ; SKPNE C0702 +; 2460: stack_loop = stack_loop + 1 + DB $68,D0952 ; LAB D0952 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $78,D0952 ; SAB D0952 +; 2461: tag_choice = ctag_new_01() + DB $54,C0066 ; CALL C0066 + DB $76,$12 ; SLW 18 +; 2462: tag_prevbrk = break_tag + DB $6A,D0956 ; LAW D0956 + DB $76,$04 ; SLW 4 +; 2463: break_tag = ctag_new_01() + DB $54,C0066 ; CALL C0066 + DB $7A,D0956 ; SAW D0956 +; 2464: drop parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $30 ; DROP +; 2465: drop nextln_01() + DB $54,C0301 ; CALL C0301 + DB $30 ; DROP +; 2466: while token <> ENDCASE_TKN +C0703: + DB $68,D0413 ; LAB D0413 + DB $2A,$8D ; CB 141 + DB $42 ; ISNE + DB $4C,C0704 ; SKPFLS C0704 +; 2467: when token + DB $68,D0413 ; LAB D0413 +; 2468: is OF_TKN + DB $2A,$8B ; CB 139 + DB $3E,C0706 ; SKPNE C0706 +; 2469: if !parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $20 ; NOT + DB $4C,C0707 ; SKPFLS C0707 +; 2470: return parse_err_11(@bad_stmnt) + DB $30 ; DROP + DB $30 ; DROP + DB $26,D0535 ; LA D0535 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2471: fin +C0707: +C0708: +; 2472: emit_brne_10(tag_choice) + DB $66,$12 ; LLW 18 + DB $54,C0208 ; CALL C0208 +; 2473: while parse_stmnt_01() +C0709: + DB $54,C0642 ; CALL C0642 + DB $4C,C0710 ; SKPFLS C0710 +; 2474: drop nextln_01() + DB $54,C0301 ; CALL C0301 + DB $30 ; DROP +; 2475: loop + DB $50,C0709 ; SKIP C0709 +C0710: +; 2476: emit_jump_10(break_tag) + DB $6A,D0956 ; LAW D0956 + DB $54,C0210 ; CALL C0210 +; 2477: emit_codetag_10(tag_choice) + DB $66,$12 ; LLW 18 + DB $54,C0082 ; CALL C0082 +; 2478: tag_choice = ctag_new_01() + DB $54,C0066 ; CALL C0066 + DB $76,$12 ; SLW 18 +; 2479: is DEFAULT_TKN + DB $50,C0705 ; SKIP C0705 +C0706: + DB $2A,$8C ; CB 140 + DB $3E,C0711 ; SKPNE C0711 +; 2480: drop scan_01() + DB $54,C0246 ; CALL C0246 + DB $30 ; DROP +; 2481: while parse_stmnt_01() +C0712: + DB $54,C0642 ; CALL C0642 + DB $4C,C0713 ; SKPFLS C0713 +; 2482: drop nextln_01() + DB $54,C0301 ; CALL C0301 + DB $30 ; DROP +; 2483: loop + DB $50,C0712 ; SKIP C0712 +C0713: +; 2484: if token <> ENDCASE_TKN + DB $68,D0413 ; LAB D0413 + DB $2A,$8D ; CB 141 + DB $42 ; ISNE + DB $4C,C0714 ; SKPFLS C0714 +; 2485: return parse_err_11(@bad_stmnt) + DB $30 ; DROP + DB $30 ; DROP + DB $26,D0535 ; LA D0535 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2486: fin +C0714: +C0715: +; 2487: otherwise + DB $50,C0705 ; SKIP C0705 +C0711: +; 2488: return parse_err_11(@bad_stmnt) + DB $30 ; DROP + DB $30 ; DROP + DB $26,D0535 ; LA D0535 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2489: wend +C0705: + DB $30 ; DROP +; 2490: loop + DB $50,C0703 ; SKIP C0703 +C0704: +; 2491: emit_codetag_10(break_tag) + DB $6A,D0956 ; LAW D0956 + DB $54,C0082 ; CALL C0082 +; 2492: emit_drop() + DB $54,C0212 ; CALL C0212 +; 2493: break_tag = tag_prevbrk + DB $66,$04 ; LLW 4 + DB $7A,D0956 ; SAW D0956 +; 2494: stack_loop = stack_loop - 1 + DB $68,D0952 ; LAB D0952 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $78,D0952 ; SAB D0952 +; 2495: is BREAK_TKN + DB $50,C0646 ; SKIP C0646 +C0702: + DB $2A,$9A ; CB 154 + DB $3E,C0717 ; SKPNE C0717 +; 2496: if break_tag + DB $6A,D0956 ; LAW D0956 + DB $4C,C0718 ; SKPFLS C0718 +; 2497: emit_jump_10(break_tag) + DB $6A,D0956 ; LAW D0956 + DB $54,C0210 ; CALL C0210 +; 2498: else + DB $50,C0719 ; SKIP C0719 +C0718: +; 2499: return parse_err_11(@bad_stmnt) + DB $30 ; DROP + DB $26,D0535 ; LA D0535 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2500: fin +C0719: +; 2501: is RETURN_TKN + DB $50,C0646 ; SKIP C0646 +C0717: + DB $2A,$99 ; CB 153 + DB $3E,C0720 ; SKPNE C0720 +; 2502: if infunc + DB $68,D0951 ; LAB D0951 + DB $4C,C0721 ; SKPFLS C0721 +; 2503: for i = 1 to stack_loop + DB $2A,$01 ; CB 1 +C0724: + DB $6C,$03 ; DLB 3 + DB $68,D0952 ; LAB D0952 + DB $3A,C0723 ; SKPGT C0723 + DB $0C ; INCR +; 2504: emit_drop() + DB $54,C0212 ; CALL C0212 +; 2505: next + DB $50,C0724 ; SKIP C0724 +C0723: + DB $30 ; DROP +; 2506: drop parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $30 ; DROP +; 2507: emit_leave_10(framesize) + DB $6A,D0008 ; LAW D0008 + DB $54,C0216 ; CALL C0216 +; 2508: else + DB $50,C0722 ; SKIP C0722 +C0721: +; 2509: return parse_err_11(@bad_stmnt) + DB $30 ; DROP + DB $26,D0535 ; LA D0535 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2510: fin +C0722: +; 2511: is EXIT_TKN + DB $50,C0646 ; SKIP C0646 +C0720: + DB $2A,$9C ; CB 156 + DB $3E,C0725 ; SKPNE C0725 +; 2512: drop parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $30 ; DROP +; 2513: emit_exit() + DB $54,C0226 ; CALL C0226 +; 2514: is DROP_TKN + DB $50,C0646 ; SKIP C0646 +C0725: + DB $2A,$97 ; CB 151 + DB $3E,C0726 ; SKPNE C0726 +; 2515: drop parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $30 ; DROP +; 2516: emit_drop() + DB $54,C0212 ; CALL C0212 +; 2517: is ELSE_TKN + DB $50,C0646 ; SKIP C0646 +C0726: + DB $2A,$85 ; CB 133 + DB $3E,C0727 ; SKPNE C0727 +; 2518: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2519: is ELSEIF_TKN + DB $50,C0646 ; SKIP C0646 +C0727: + DB $2A,$84 ; CB 132 + DB $3E,C0728 ; SKPNE C0728 +; 2520: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2521: is FIN_TKN + DB $50,C0646 ; SKIP C0646 +C0728: + DB $2A,$86 ; CB 134 + DB $3E,C0729 ; SKPNE C0729 +; 2522: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2523: is LOOP_TKN + DB $50,C0646 ; SKIP C0646 +C0729: + DB $2A,$89 ; CB 137 + DB $3E,C0730 ; SKPNE C0730 +; 2524: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2525: is UNTIL_TKN + DB $50,C0646 ; SKIP C0646 +C0730: + DB $2A,$94 ; CB 148 + DB $3E,C0731 ; SKPNE C0731 +; 2526: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2527: is NEXT_TKN + DB $50,C0646 ; SKIP C0646 +C0731: + DB $2A,$92 ; CB 146 + DB $3E,C0732 ; SKPNE C0732 +; 2528: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2529: is OF_TKN + DB $50,C0646 ; SKIP C0646 +C0732: + DB $2A,$8B ; CB 139 + DB $3E,C0733 ; SKPNE C0733 +; 2530: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2531: is DEFAULT_TKN + DB $50,C0646 ; SKIP C0646 +C0733: + DB $2A,$8C ; CB 140 + DB $3E,C0734 ; SKPNE C0734 +; 2532: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2533: is ENDCASE_TKN + DB $50,C0646 ; SKIP C0646 +C0734: + DB $2A,$8D ; CB 141 + DB $3E,C0735 ; SKPNE C0735 +; 2534: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2535: is END_TKN + DB $50,C0646 ; SKIP C0646 +C0735: + DB $2A,$87 ; CB 135 + DB $3E,C0736 ; SKPNE C0736 +; 2536: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2537: is DONE_TKN + DB $50,C0646 ; SKIP C0646 +C0736: + DB $2A,$98 ; CB 152 + DB $3E,C0737 ; SKPNE C0737 +; 2538: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2539: is IFUNC_TKN + DB $50,C0646 ; SKIP C0646 +C0737: + DB $2A,$95 ; CB 149 + DB $3E,C0738 ; SKPNE C0738 +; 2540: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2541: is NFUNC_TKN + DB $50,C0646 ; SKIP C0646 +C0738: + DB $2A,$96 ; CB 150 + DB $3E,C0739 ; SKPNE C0739 +; 2542: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2543: is EOF_TKN + DB $50,C0646 ; SKIP C0646 +C0739: + DB $2A,$01 ; CB 1 + DB $3E,C0740 ; SKPNE C0740 +; 2544: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2545: is EOL_TKN + DB $50,C0646 ; SKIP C0646 +C0740: + DB $2A,$02 ; CB 2 + DB $3E,C0741 ; SKPNE C0741 +; 2546: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5A ; LEAVE +; 2547: otherwise + DB $50,C0646 ; SKIP C0646 +C0741: +; 2548: if token == ID_TKN + DB $68,D0413 ; LAB D0413 + DB $2A,$D6 ; CB 214 + DB $40 ; ISEQ + DB $4C,C0743 ; SKPFLS C0743 +; 2549: saveptr = tknptr + DB $6A,D0417 ; LAW D0417 + DB $76,$16 ; SLW 22 +; 2550: idptr = id_lookup_21(tknptr, tknlen) + DB $6A,D0417 ; LAW D0417 + DB $68,D0414 ; LAB D0414 + DB $54,C0335 ; CALL C0335 + DB $76,$14 ; SLW 20 +; 2551: if !idptr + DB $66,$14 ; LLW 20 + DB $20 ; NOT + DB $4C,C0745 ; SKPFLS C0745 +; 2552: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2553: fin +C0745: +C0746: +; 2554: type = (idptr).idtype + DB $66,$14 ; LLW 20 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $60 ; LB + DB $74,$02 ; SLB 2 +; 2555: if type & ADDR_TYPE + DB $64,$02 ; LLB 2 + DB $2A,$0E ; CB 14 + DB $14 ; BAND + DB $4C,C0747 ; SKPFLS C0747 +; 2556: addr = (idptr):idval + DB $66,$14 ; LLW 20 + DB $62 ; LW + DB $76,$18 ; SLW 24 +; 2557: if scan_01() == SET_TKN + DB $54,C0246 ; CALL C0246 + DB $2A,$BD ; CB 189 + DB $40 ; ISEQ + DB $4C,C0749 ; SKPFLS C0749 +; 2558: if type & VAR_TYPE + DB $64,$02 ; LLB 2 + DB $2A,$06 ; CB 6 + DB $14 ; BAND + DB $4C,C0751 ; SKPFLS C0751 +; 2559: drop parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $30 ; DROP +; 2560: if type & LOCAL_TYPE + DB $64,$02 ; LLB 2 + DB $2A,$10 ; CB 16 + DB $14 ; BAND + DB $4C,C0753 ; SKPFLS C0753 +; 2561: if type & BYTE_TYPE + DB $64,$02 ; LLB 2 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C0755 ; SKPFLS C0755 +; 2562: emit_slb_10(addr) + DB $66,$18 ; LLW 24 + DB $54,C0124 ; CALL C0124 +; 2563: else + DB $50,C0756 ; SKIP C0756 +C0755: +; 2564: emit_slw_10(addr) + DB $66,$18 ; LLW 24 + DB $54,C0126 ; CALL C0126 +; 2565: fin +C0756: +; 2566: else + DB $50,C0754 ; SKIP C0754 +C0753: +; 2567: if type & BYTE_TYPE + DB $64,$02 ; LLB 2 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C0757 ; SKPFLS C0757 +; 2568: emit_sab_10(addr) + DB $66,$18 ; LLW 24 + DB $54,C0132 ; CALL C0132 +; 2569: else + DB $50,C0758 ; SKIP C0758 +C0757: +; 2570: emit_saw_10(addr) + DB $66,$18 ; LLW 24 + DB $54,C0134 ; CALL C0134 +; 2571: fin +C0758: +; 2572: fin +C0754: +; 2573: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5A ; LEAVE +; 2574: fin +C0751: +C0752: +; 2575: elsif token == SETLIST_TKN and type & VAR_TYPE + DB $50,C0750 ; SKIP C0750 +C0749: + DB $68,D0413 ; LAB D0413 + DB $2A,$B9 ; CB 185 + DB $40 ; ISEQ + DB $64,$02 ; LLB 2 + DB $2A,$06 ; CB 6 + DB $14 ; BAND + DB $24 ; LAND + DB $4C,C0759 ; SKPFLS C0759 +; 2576: return parse_setlist_21(addr, type); + DB $30 ; DROP + DB $66,$18 ; LLW 24 + DB $64,$02 ; LLB 2 + DB $54,C0602 ; CALL C0602 + DB $5A ; LEAVE +; 2577: elsif token == EOL_TKN and type & FUNC_TYPE + DB $50,C0750 ; SKIP C0750 +C0759: + DB $68,D0413 ; LAB D0413 + DB $2A,$02 ; CB 2 + DB $40 ; ISEQ + DB $64,$02 ; LLB 2 + DB $2A,$08 ; CB 8 + DB $14 ; BAND + DB $24 ; LAND + DB $4C,C0760 ; SKPFLS C0760 +; 2578: emit_call_10(addr) + DB $66,$18 ; LLW 24 + DB $54,C0140 ; CALL C0140 +; 2579: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5A ; LEAVE +; 2580: fin +C0760: +C0750: +; 2581: fin +C0747: +C0748: +; 2582: tknptr = saveptr + DB $66,$16 ; LLW 22 + DB $7A,D0417 ; SAW D0417 +; 2583: fin +C0743: +C0744: +; 2584: rewind_10(tknptr) + DB $6A,D0417 ; LAW D0417 + DB $54,C0299 ; CALL C0299 +; 2585: type = parse_value_11(0) + DB $00 ; ZERO + DB $54,C0424 ; CALL C0424 + DB $74,$02 ; SLB 2 +; 2586: if type + DB $64,$02 ; LLB 2 + DB $4C,C0761 ; SKPFLS C0761 +; 2587: if token == SET_TKN + DB $68,D0413 ; LAB D0413 + DB $2A,$BD ; CB 189 + DB $40 ; ISEQ + DB $4C,C0763 ; SKPFLS C0763 +; 2588: drop parse_expr_01() + DB $54,C0000 ; CALL C0000 + DB $30 ; DROP +; 2589: if type & XBYTE_TYPE + DB $64,$02 ; LLB 2 + DB $2A,$22 ; CB 34 + DB $14 ; BAND + DB $4C,C0765 ; SKPFLS C0765 +; 2590: emit_sb() + DB $54,C0120 ; CALL C0120 +; 2591: else + DB $50,C0766 ; SKIP C0766 +C0765: +; 2592: emit_sw() + DB $54,C0122 ; CALL C0122 +; 2593: fin +C0766: +; 2594: elsif token == SETLIST_TKN + DB $50,C0764 ; SKIP C0764 +C0763: + DB $68,D0413 ; LAB D0413 + DB $2A,$B9 ; CB 185 + DB $40 ; ISEQ + DB $4C,C0767 ; SKPFLS C0767 +; 2595: return parse_setlist_21(0, type); + DB $30 ; DROP + DB $00 ; ZERO + DB $64,$02 ; LLB 2 + DB $54,C0602 ; CALL C0602 + DB $5A ; LEAVE +; 2596: else + DB $50,C0764 ; SKIP C0764 +C0767: +; 2597: if type & BPTR_TYPE + DB $64,$02 ; LLB 2 + DB $2A,$20 ; CB 32 + DB $14 ; BAND + DB $4C,C0768 ; SKPFLS C0768 +; 2598: emit_lb() + DB $54,C0108 ; CALL C0108 +; 2599: elsif type & WPTR_TYPE + DB $50,C0769 ; SKIP C0769 +C0768: + DB $64,$02 ; LLB 2 + DB $2A,$40 ; CB 64 + DB $14 ; BAND + DB $4C,C0770 ; SKPFLS C0770 +; 2600: emit_lw() + DB $54,C0110 ; CALL C0110 +; 2601: fin +C0770: +C0769: +; 2602: fin +C0764: +; 2603: else + DB $50,C0762 ; SKIP C0762 +C0761: +; 2604: return parse_err_11(@bad_syntax) + DB $30 ; DROP + DB $26,D0563 ; LA D0563 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2605: fin +C0762: +; 2606: wend +C0646: + DB $30 ; DROP +; 2607: if scan_01() <> EOL_TKN + DB $54,C0246 ; CALL C0246 + DB $2A,$02 ; CB 2 + DB $42 ; ISNE + DB $4C,C0771 ; SKPFLS C0771 +; 2608: return parse_err_11(@bad_syntax) + DB $26,D0563 ; LA D0563 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2609: fin +C0771: +C0772: +; 2610: return TRUE + DB $2C,$FF,$FF ; CW -1 + DB $5A ; LEAVE +; 2611: end +; 2612: def parse_var_11(type) +C0773: ; parse_var_11() + ; type = 2 +; 2613: byte consttype, constsize, idlen + ; consttype = 4 + ; constsize = 5 + ; idlen = 6 +; 2614: word idptr, constval, arraysize, size + ; idptr = 7 + ; constval = 9 + ; arraysize = 11 + ; size = 13 +; 2615: +; 2616: idlen = 0 + JSR INTERP + DB $58,$0F,$01 ; ENTER 15,1 + DB $00 ; ZERO + DB $74,$06 ; SLB 6 +; 2617: size = 1 + DB $2A,$01 ; CB 1 + DB $76,$0D ; SLW 13 +; 2618: if scan_01() == ID_TKN + DB $54,C0246 ; CALL C0246 + DB $2A,$D6 ; CB 214 + DB $40 ; ISEQ + DB $4C,C0775 ; SKPFLS C0775 +; 2619: idptr = tknptr + DB $6A,D0417 ; LAW D0417 + DB $76,$07 ; SLW 7 +; 2620: idlen = tknlen + DB $68,D0414 ; LAB D0414 + DB $74,$06 ; SLB 6 +; 2621: if scan_01() == OPEN_BRACKET_TKN + DB $54,C0246 ; CALL C0246 + DB $2A,$DB ; CB 219 + DB $40 ; ISEQ + DB $4C,C0777 ; SKPFLS C0777 +; 2622: size = 0 + DB $00 ; ZERO + DB $76,$0D ; SLW 13 +; 2623: drop parse_constexpr_21(@size, @constsize) + DB $28,$0D ; LLA 13 + DB $28,$05 ; LLA 5 + DB $54,C0551 ; CALL C0551 + DB $30 ; DROP +; 2624: if token <> CLOSE_BRACKET_TKN + DB $68,D0413 ; LAB D0413 + DB $2A,$DD ; CB 221 + DB $42 ; ISNE + DB $4C,C0779 ; SKPFLS C0779 +; 2625: return parse_err_11(@no_close_bracket) + DB $26,D0735 ; LA D0735 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2626: fin +C0779: +C0780: +; 2627: drop scan_01() + DB $54,C0246 ; CALL C0246 + DB $30 ; DROP +; 2628: fin +C0777: +C0778: +; 2629: fin +C0775: +C0776: +; 2630: if type == WORD_TYPE + DB $66,$02 ; LLW 2 + DB $2A,$04 ; CB 4 + DB $40 ; ISEQ + DB $4C,C0781 ; SKPFLS C0781 +; 2631: size = size * 2 + DB $66,$0D ; LLW 13 + DB $2A,$02 ; CB 2 + DB $06 ; MUL + DB $76,$0D ; SLW 13 +; 2632: fin +C0781: +C0782: +; 2633: if token == SET_TKN + DB $68,D0413 ; LAB D0413 + DB $2A,$BD ; CB 189 + DB $40 ; ISEQ + DB $4C,C0783 ; SKPFLS C0783 +; 2634: if infunc + DB $68,D0951 ; LAB D0951 + DB $4C,C0785 ; SKPFLS C0785 +; 2635: return parse_err_11(@no_local_init) + DB $26,D0827 ; LA D0827 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2636: fin +C0785: +C0786: +; 2637: if idlen + DB $64,$06 ; LLB 6 + DB $4C,C0787 ; SKPFLS C0787 +; 2638: drop iddata_add_41(idptr, idlen, type, 0) + DB $66,$07 ; LLW 7 + DB $64,$06 ; LLB 6 + DB $66,$02 ; LLW 2 + DB $00 ; ZERO + DB $54,C0351 ; CALL C0351 + DB $30 ; DROP +; 2639: fin +C0787: +C0788: +; 2640: consttype = parse_constexpr_21(@constval, @constsize) + DB $28,$09 ; LLA 9 + DB $28,$05 ; LLA 5 + DB $54,C0551 ; CALL C0551 + DB $74,$04 ; SLB 4 +; 2641: if consttype + DB $64,$04 ; LLB 4 + DB $4C,C0789 ; SKPFLS C0789 +; 2642: arraysize = emit_data_41(type, consttype, constval, constsize) + DB $66,$02 ; LLW 2 + DB $64,$04 ; LLB 4 + DB $66,$09 ; LLW 9 + DB $64,$05 ; LLB 5 + DB $54,C0094 ; CALL C0094 + DB $76,$0B ; SLW 11 +; 2643: while token == COMMA_TKN +C0791: + DB $68,D0413 ; LAB D0413 + DB $2A,$AC ; CB 172 + DB $40 ; ISEQ + DB $4C,C0792 ; SKPFLS C0792 +; 2644: consttype = parse_constexpr_21(@constval, @constsize) + DB $28,$09 ; LLA 9 + DB $28,$05 ; LLA 5 + DB $54,C0551 ; CALL C0551 + DB $74,$04 ; SLB 4 +; 2645: if consttype + DB $64,$04 ; LLB 4 + DB $4C,C0793 ; SKPFLS C0793 +; 2646: arraysize = arraysize + emit_data_41(type, consttype, constval, constsize) + DB $66,$0B ; LLW 11 + DB $66,$02 ; LLW 2 + DB $64,$04 ; LLB 4 + DB $66,$09 ; LLW 9 + DB $64,$05 ; LLB 5 + DB $54,C0094 ; CALL C0094 + DB $02 ; ADD + DB $76,$0B ; SLW 11 +; 2647: else + DB $50,C0794 ; SKIP C0794 +C0793: +; 2648: return parse_err_11(@bad_decl) + DB $26,D0505 ; LA D0505 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2649: fin +C0794: +; 2650: loop + DB $50,C0791 ; SKIP C0791 +C0792: +; 2651: if token <> EOL_TKN + DB $68,D0413 ; LAB D0413 + DB $2A,$02 ; CB 2 + DB $42 ; ISNE + DB $4C,C0795 ; SKPFLS C0795 +; 2652: return parse_err_11(@no_close_bracket) + DB $26,D0735 ; LA D0735 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2653: fin +C0795: +C0796: +; 2654: iddata_size_30(PTR_TYPE, size, arraysize); + DB $2A,$60 ; CB 96 + DB $66,$0D ; LLW 13 + DB $66,$0B ; LLW 11 + DB $54,C0357 ; CALL C0357 +; 2655: else + DB $50,C0790 ; SKIP C0790 +C0789: +; 2656: return parse_err_11(@bad_decl) + DB $26,D0505 ; LA D0505 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2657: fin +C0790: +; 2658: elsif idlen + DB $50,C0784 ; SKIP C0784 +C0783: + DB $64,$06 ; LLB 6 + DB $4C,C0797 ; SKPFLS C0797 +; 2659: if infunc + DB $68,D0951 ; LAB D0951 + DB $4C,C0798 ; SKPFLS C0798 +; 2660: drop idlocal_add_41(idptr, idlen, type, size) + DB $66,$07 ; LLW 7 + DB $64,$06 ; LLB 6 + DB $66,$02 ; LLW 2 + DB $66,$0D ; LLW 13 + DB $54,C0343 ; CALL C0343 + DB $30 ; DROP +; 2661: else + DB $50,C0799 ; SKIP C0799 +C0798: +; 2662: drop iddata_add_41(idptr, idlen, type, size) + DB $66,$07 ; LLW 7 + DB $64,$06 ; LLB 6 + DB $66,$02 ; LLW 2 + DB $66,$0D ; LLW 13 + DB $54,C0351 ; CALL C0351 + DB $30 ; DROP +; 2663: fin +C0799: +; 2664: fin +C0797: +C0784: +; 2665: return TRUE + DB $2C,$FF,$FF ; CW -1 + DB $5A ; LEAVE +; 2666: end +; 2667: def parse_vars_01 +C0800: ; parse_vars_01() +; 2668: byte idlen, type, size + ; idlen = 2 + ; type = 3 + ; size = 4 +; 2669: word value, idptr + ; value = 5 + ; idptr = 7 +; 2670: +; 2671: when token + JSR INTERP + DB $58,$09,$00 ; ENTER 9,0 + DB $68,D0413 ; LAB D0413 +; 2672: is CONST_TKN + DB $2A,$80 ; CB 128 + DB $3E,C0803 ; SKPNE C0803 +; 2673: if scan_01() <> ID_TKN + DB $54,C0246 ; CALL C0246 + DB $2A,$D6 ; CB 214 + DB $42 ; ISNE + DB $4C,C0804 ; SKPFLS C0804 +; 2674: return parse_err_11(@bad_cnst) + DB $30 ; DROP + DB $26,D0474 ; LA D0474 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2675: fin +C0804: +C0805: +; 2676: idptr = tknptr; + DB $6A,D0417 ; LAW D0417 + DB $76,$07 ; SLW 7 +; 2677: idlen = tknlen + DB $68,D0414 ; LAB D0414 + DB $74,$02 ; SLB 2 +; 2678: if scan_01() <> SET_TKN + DB $54,C0246 ; CALL C0246 + DB $2A,$BD ; CB 189 + DB $42 ; ISNE + DB $4C,C0806 ; SKPFLS C0806 +; 2679: return parse_err_11(@bad_cnst) + DB $30 ; DROP + DB $26,D0474 ; LA D0474 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2680: fin +C0806: +C0807: +; 2681: if !parse_constexpr_21(@value, @size) + DB $28,$05 ; LLA 5 + DB $28,$04 ; LLA 4 + DB $54,C0551 ; CALL C0551 + DB $20 ; NOT + DB $4C,C0808 ; SKPFLS C0808 +; 2682: return parse_err_11(@bad_cnst) + DB $30 ; DROP + DB $26,D0474 ; LA D0474 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2683: fin +C0808: +C0809: +; 2684: drop idconst_add_31(idptr, idlen, value) + DB $66,$07 ; LLW 7 + DB $64,$02 ; LLB 2 + DB $66,$05 ; LLW 5 + DB $54,C0369 ; CALL C0369 + DB $30 ; DROP +; 2685: is BYTE_TKN + DB $50,C0802 ; SKIP C0802 +C0803: + DB $2A,$81 ; CB 129 + DB $3E,C0810 ; SKPNE C0810 +; 2686: type = BYTE_TYPE + DB $2A,$02 ; CB 2 + DB $74,$03 ; SLB 3 +; 2687: repeat +C0812: +; 2688: if !parse_var_11(type) + DB $64,$03 ; LLB 3 + DB $54,C0773 ; CALL C0773 + DB $20 ; NOT + DB $4C,C0813 ; SKPFLS C0813 +; 2689: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2690: fin +C0813: +C0814: +; 2691: until token <> COMMA_TKN + DB $68,D0413 ; LAB D0413 + DB $2A,$AC ; CB 172 + DB $42 ; ISNE + DB $4C,C0812 ; SKPFLS C0812 +C0811: +; 2692: is WORD_TKN + DB $50,C0802 ; SKIP C0802 +C0810: + DB $2A,$82 ; CB 130 + DB $3E,C0815 ; SKPNE C0815 +; 2693: type = WORD_TYPE + DB $2A,$04 ; CB 4 + DB $74,$03 ; SLB 3 +; 2694: repeat +C0817: +; 2695: if !parse_var_11(type) + DB $64,$03 ; LLB 3 + DB $54,C0773 ; CALL C0773 + DB $20 ; NOT + DB $4C,C0818 ; SKPFLS C0818 +; 2696: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2697: fin +C0818: +C0819: +; 2698: until token <> COMMA_TKN + DB $68,D0413 ; LAB D0413 + DB $2A,$AC ; CB 172 + DB $42 ; ISNE + DB $4C,C0817 ; SKPFLS C0817 +C0816: +; 2699: is FUNC_TKN + DB $50,C0802 ; SKIP C0802 +C0815: + DB $2A,$9E ; CB 158 + DB $3E,C0820 ; SKPNE C0820 +; 2700: repeat +C0822: +; 2701: if scan_01() == ID_TKN + DB $54,C0246 ; CALL C0246 + DB $2A,$D6 ; CB 214 + DB $40 ; ISEQ + DB $4C,C0823 ; SKPFLS C0823 +; 2702: drop idfunc_add_31(tknptr, tknlen, ctag_new_01()) + DB $6A,D0417 ; LAW D0417 + DB $68,D0414 ; LAB D0414 + DB $54,C0066 ; CALL C0066 + DB $54,C0367 ; CALL C0367 + DB $30 ; DROP +; 2703: else + DB $50,C0824 ; SKIP C0824 +C0823: +; 2704: return parse_err_11(@bad_decl) + DB $30 ; DROP + DB $26,D0505 ; LA D0505 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2705: fin +C0824: +; 2706: until scan_01() <> COMMA_TKN + DB $54,C0246 ; CALL C0246 + DB $2A,$AC ; CB 172 + DB $42 ; ISNE + DB $4C,C0822 ; SKPFLS C0822 +C0821: +; 2707: is EOL_TKN + DB $50,C0802 ; SKIP C0802 +C0820: + DB $2A,$02 ; CB 2 + DB $3E,C0825 ; SKPNE C0825 +; 2708: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5A ; LEAVE +; 2709: otherwise + DB $50,C0802 ; SKIP C0802 +C0825: +; 2710: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2711: wend +C0802: + DB $30 ; DROP +; 2712: return TRUE + DB $2C,$FF,$FF ; CW -1 + DB $5A ; LEAVE +; 2713: end +; 2714: def parse_func_01 +C0827: ; parse_func_01() +; 2715: byte opt, cfnparms + ; opt = 2 + ; cfnparms = 3 +; 2716: word func_tag, idptr + ; func_tag = 4 + ; idptr = 6 +; 2717: +; 2718: if token == IFUNC_TKN or token == NFUNC_TKN + JSR INTERP + DB $58,$08,$00 ; ENTER 8,0 + DB $68,D0413 ; LAB D0413 + DB $2A,$95 ; CB 149 + DB $40 ; ISEQ + DB $68,D0413 ; LAB D0413 + DB $2A,$96 ; CB 150 + DB $40 ; ISEQ + DB $22 ; LOR + DB $4C,C0829 ; SKPFLS C0829 +; 2719: opt = token - IFUNC_TKN + DB $68,D0413 ; LAB D0413 + DB $2A,$95 ; CB 149 + DB $04 ; SUB + DB $74,$02 ; SLB 2 +; 2720: if scan_01() <> ID_TKN + DB $54,C0246 ; CALL C0246 + DB $2A,$D6 ; CB 214 + DB $42 ; ISNE + DB $4C,C0831 ; SKPFLS C0831 +; 2721: return parse_err_11(@bad_decl) + DB $26,D0505 ; LA D0505 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2722: fin +C0831: +C0832: +; 2723: cfnparms = 0 + DB $00 ; ZERO + DB $74,$03 ; SLB 3 +; 2724: infunc = TRUE + DB $2C,$FF,$FF ; CW -1 + DB $78,D0951 ; SAB D0951 +; 2725: idptr = idglobal_lookup_21(tknptr, tknlen) + DB $6A,D0417 ; LAW D0417 + DB $68,D0414 ; LAB D0414 + DB $54,C0341 ; CALL C0341 + DB $76,$06 ; SLW 6 +; 2726: if idptr + DB $66,$06 ; LLW 6 + DB $4C,C0833 ; SKPFLS C0833 +; 2727: func_tag = (idptr):idval + DB $66,$06 ; LLW 6 + DB $62 ; LW + DB $76,$04 ; SLW 4 +; 2728: else + DB $50,C0834 ; SKIP C0834 +C0833: +; 2729: func_tag = ctag_new_01() + DB $54,C0066 ; CALL C0066 + DB $76,$04 ; SLW 4 +; 2730: drop idfunc_add_31(tknptr, tknlen, func_tag) + DB $6A,D0417 ; LAW D0417 + DB $68,D0414 ; LAB D0414 + DB $66,$04 ; LLW 4 + DB $54,C0367 ; CALL C0367 + DB $30 ; DROP +; 2731: fin +C0834: +; 2732: emit_codetag_10(func_tag) + DB $66,$04 ; LLW 4 + DB $54,C0082 ; CALL C0082 +; 2733: retfunc_tag = ctag_new_01() + DB $54,C0066 ; CALL C0066 + DB $7A,D0954 ; SAW D0954 +; 2734: idlocal_init() + DB $54,C0373 ; CALL C0373 +; 2735: if scan_01() == OPEN_PAREN_TKN + DB $54,C0246 ; CALL C0246 + DB $2A,$A8 ; CB 168 + DB $40 ; ISEQ + DB $4C,C0835 ; SKPFLS C0835 +; 2736: repeat +C0838: +; 2737: if scan_01() == ID_TKN + DB $54,C0246 ; CALL C0246 + DB $2A,$D6 ; CB 214 + DB $40 ; ISEQ + DB $4C,C0839 ; SKPFLS C0839 +; 2738: cfnparms = cfnparms + 1 + DB $64,$03 ; LLB 3 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $74,$03 ; SLB 3 +; 2739: drop idlocal_add_41(tknptr, tknlen, WORD_TYPE, 2) + DB $6A,D0417 ; LAW D0417 + DB $68,D0414 ; LAB D0414 + DB $2A,$04 ; CB 4 + DB $2A,$02 ; CB 2 + DB $54,C0343 ; CALL C0343 + DB $30 ; DROP +; 2740: drop scan_01() + DB $54,C0246 ; CALL C0246 + DB $30 ; DROP +; 2741: fin +C0839: +C0840: +; 2742: until token <> COMMA_TKN + DB $68,D0413 ; LAB D0413 + DB $2A,$AC ; CB 172 + DB $42 ; ISNE + DB $4C,C0838 ; SKPFLS C0838 +C0837: +; 2743: if token <> CLOSE_PAREN_TKN + DB $68,D0413 ; LAB D0413 + DB $2A,$A9 ; CB 169 + DB $42 ; ISNE + DB $4C,C0841 ; SKPFLS C0841 +; 2744: return parse_err_11(@bad_decl) + DB $26,D0505 ; LA D0505 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2745: fin +C0841: +C0842: +; 2746: drop scan_01() + DB $54,C0246 ; CALL C0246 + DB $30 ; DROP +; 2747: fin +C0835: +C0836: +; 2748: while parse_vars_01() +C0843: + DB $54,C0800 ; CALL C0800 + DB $4C,C0844 ; SKPFLS C0844 +; 2749: drop nextln_01() + DB $54,C0301 ; CALL C0301 + DB $30 ; DROP +; 2750: loop + DB $50,C0843 ; SKIP C0843 +C0844: +; 2751: emit_enter_20(framesize, cfnparms) + DB $6A,D0008 ; LAW D0008 + DB $64,$03 ; LLB 3 + DB $54,C0220 ; CALL C0220 +; 2752: prevstmnt = 0 + DB $00 ; ZERO + DB $78,D0953 ; SAB D0953 +; 2753: while parse_stmnt_01() +C0845: + DB $54,C0642 ; CALL C0642 + DB $4C,C0846 ; SKPFLS C0846 +; 2754: drop nextln_01() + DB $54,C0301 ; CALL C0301 + DB $30 ; DROP +; 2755: loop + DB $50,C0845 ; SKIP C0845 +C0846: +; 2756: infunc = FALSE + DB $00 ; ZERO + DB $78,D0951 ; SAB D0951 +; 2757: if token <> END_TKN + DB $68,D0413 ; LAB D0413 + DB $2A,$87 ; CB 135 + DB $42 ; ISNE + DB $4C,C0847 ; SKPFLS C0847 +; 2758: return parse_err_11(@bad_syntax) + DB $26,D0563 ; LA D0563 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2759: fin +C0847: +C0848: +; 2760: if scan_01() <> EOL_TKN + DB $54,C0246 ; CALL C0246 + DB $2A,$02 ; CB 2 + DB $42 ; ISNE + DB $4C,C0849 ; SKPFLS C0849 +; 2761: return parse_err_11(@bad_syntax) + DB $26,D0563 ; LA D0563 + DB $54,C0062 ; CALL C0062 + DB $5A ; LEAVE +; 2762: fin +C0849: +C0850: +; 2763: if prevstmnt <> RETURN_TKN + DB $68,D0953 ; LAB D0953 + DB $2A,$99 ; CB 153 + DB $42 ; ISNE + DB $4C,C0851 ; SKPFLS C0851 +; 2764: emit_leave_10(framesize) + DB $6A,D0008 ; LAW D0008 + DB $54,C0216 ; CALL C0216 +; 2765: fin +C0851: +C0852: +; 2766: return TRUE + DB $2C,$FF,$FF ; CW -1 + DB $5A ; LEAVE +; 2767: elsif token == EOL_TKN + DB $50,C0830 ; SKIP C0830 +C0829: + DB $68,D0413 ; LAB D0413 + DB $2A,$02 ; CB 2 + DB $40 ; ISEQ + DB $4C,C0853 ; SKPFLS C0853 +; 2768: return TRUE + DB $2C,$FF,$FF ; CW -1 + DB $5A ; LEAVE +; 2769: fin +C0853: +C0830: +; 2770: return FALSE + DB $00 ; ZERO + DB $5A ; LEAVE +; 2771: end +; 2772: def parse_module_01 +C0001: ; parse_module_01() +; 2773: entrypoint = 0 + JSR INTERP + DB $00 ; ZERO + DB $7A,D0016 ; SAW D0016 +; 2774: idglobal_init() + DB $54,C0371 ; CALL C0371 +; 2775: idlocal_init() + DB $54,C0373 ; CALL C0373 +; 2776: if nextln_01() + DB $54,C0301 ; CALL C0301 + DB $4C,C0855 ; SKPFLS C0855 +; 2777: while parse_vars_01() +C0857: + DB $54,C0800 ; CALL C0800 + DB $4C,C0858 ; SKPFLS C0858 +; 2778: drop nextln_01() + DB $54,C0301 ; CALL C0301 + DB $30 ; DROP +; 2779: loop + DB $50,C0857 ; SKIP C0857 +C0858: +; 2780: while parse_func_01() +C0859: + DB $54,C0827 ; CALL C0827 + DB $4C,C0860 ; SKPFLS C0860 +; 2781: drop nextln_01() + DB $54,C0301 ; CALL C0301 + DB $30 ; DROP +; 2782: loop + DB $50,C0859 ; SKIP C0859 +C0860: +; 2783: if token <> DONE_TKN + DB $68,D0413 ; LAB D0413 + DB $2A,$98 ; CB 152 + DB $42 ; ISNE + DB $4C,C0861 ; SKPFLS C0861 +; 2784: emit_start() + DB $54,C0224 ; CALL C0224 +; 2785: prevstmnt = 0 + DB $00 ; ZERO + DB $78,D0953 ; SAB D0953 +; 2786: while parse_stmnt_01() +C0863: + DB $54,C0642 ; CALL C0642 + DB $4C,C0864 ; SKPFLS C0864 +; 2787: drop nextln_01() + DB $54,C0301 ; CALL C0301 + DB $30 ; DROP +; 2788: loop + DB $50,C0863 ; SKIP C0863 +C0864: +; 2789: if token <> DONE_TKN + DB $68,D0413 ; LAB D0413 + DB $2A,$98 ; CB 152 + DB $42 ; ISNE + DB $4C,C0865 ; SKPFLS C0865 +; 2790: drop parse_err_11(@no_done) + DB $26,D0814 ; LA D0814 + DB $54,C0062 ; CALL C0062 + DB $30 ; DROP +; 2791: fin +C0865: +C0866: +; 2792: if prevstmnt <> EXIT_TKN + DB $68,D0953 ; LAB D0953 + DB $2A,$9C ; CB 156 + DB $42 ; ISNE + DB $4C,C0867 ; SKPFLS C0867 +; 2793: emit_const_10(0) + DB $00 ; ZERO + DB $54,C0103 ; CALL C0103 +; 2794: emit_exit() + DB $54,C0226 ; CALL C0226 +; 2795: fin +C0867: +C0868: +; 2796: fin +C0861: +C0862: +; 2797: ; dumpsym(idglobal_tbl, globals) +; 2798: ; prstr(@entrypt_str) +; 2799: ; prword(entrypoint) +; 2800: ; crout() +; 2801: ; keyin_01() +; 2802: return TRUE + DB $2C,$FF,$FF ; CW -1 + DB $5C ; RET +; 2803: fin +C0855: +C0856: +; 2804: return FALSE + DB $00 ; ZERO + DB $5C ; RET +; 2805: end +; 2806: def exec +C0869: ; exec() +; 2807: when execentry() + JSR INTERP + DB $54,C0004 ; CALL C0004 +; 2808: is 0 + DB $00 ; ZERO + DB $3E,C0872 ; SKPNE C0872 +; 2809: crout() + DB $54,C0046 ; CALL C0046 +; 2810: prstr(@donemsg) + DB $26,D0053 ; LA D0053 + DB $54,C0020 ; CALL C0020 +; 2811: is 1 + DB $50,C0871 ; SKIP C0871 +C0872: + DB $2A,$01 ; CB 1 + DB $3E,C0873 ; SKPNE C0873 +; 2812: crout() + DB $54,C0046 ; CALL C0046 +; 2813: prstr(@brkmsg) + DB $26,D0104 ; LA D0104 + DB $54,C0020 ; CALL C0020 +; 2814: is 2 + DB $50,C0871 ; SKIP C0871 +C0873: + DB $2A,$02 ; CB 2 + DB $3E,C0874 ; SKPNE C0874 +; 2815: crout() + DB $54,C0046 ; CALL C0046 +; 2816: prstr(@stkovflwmsg) + DB $26,D0117 ; LA D0117 + DB $54,C0020 ; CALL C0020 +; 2817: wend + DB $50,C0871 ; SKIP C0871 +C0874: +C0871: + DB $30 ; DROP +; 2818: end + DB $5C ; RET +; 2819: ; +; 2820: ; Compile PLASMA file and execute it +; 2821: ; +; 2822: ;emptystk = estk() +; 2823: prstr(@version) +START: ; JSR INTERP + DB $26,D0020 ; LA D0020 + DB $54,C0020 ; CALL C0020 +; 2824: crout() + DB $54,C0046 ; CALL C0046 +; 2825: if ^argbuff + DB $2C,$06,$20 ; CW 8198 + DB $60 ; LB + DB $4C,C0876 ; SKPFLS C0876 +; 2826: inref = open_21(argbuff, iobuffer) + DB $2C,$06,$20 ; CW 8198 + DB $2C,$00,$08 ; CW 2048 + DB $54,C0032 ; CALL C0032 + DB $78,D0000 ; SAB D0000 +; 2827: else + DB $50,C0877 ; SKIP C0877 +C0876: +; 2828: inref = open_21(rdstr($BA), iobuffer) + DB $2A,$BA ; CB 186 + DB $54,C0022 ; CALL C0022 + DB $2C,$00,$08 ; CW 2048 + DB $54,C0032 ; CALL C0032 + DB $78,D0000 ; SAB D0000 +; 2829: fin +C0877: +; 2830: if inref + DB $68,D0000 ; LAB D0000 + DB $4C,C0878 ; SKPFLS C0878 +; 2831: drop newline_31(inref, $7F, $0D) + DB $68,D0000 ; LAB D0000 + DB $2A,$7F ; CB 127 + DB $2A,$0D ; CB 13 + DB $54,C0044 ; CALL C0044 + DB $30 ; DROP +; 2832: if parse_module_01() + DB $54,C0001 ; CALL C0001 + DB $4C,C0880 ; SKPFLS C0880 +; 2833: drop close_11(inref) + DB $68,D0000 ; LAB D0000 + DB $54,C0034 ; CALL C0034 + DB $30 ; DROP +; 2834: exec(entrypoint) + DB $6A,D0016 ; LAW D0016 + DB $54,C0869 ; CALL C0869 +; 2835: ; +; 2836: ; Close all files +; 2837: ; +; 2838: ^$BFD8 = 0 + DB $2C,$D8,$BF ; CW 49112 + DB $00 ; ZERO + DB $70 ; SB +; 2839: drop close_11(0) + DB $00 ; ZERO + DB $54,C0034 ; CALL C0034 + DB $30 ; DROP +; 2840: else + DB $50,C0881 ; SKIP C0881 +C0880: +; 2841: drop close_11(inref) + DB $68,D0000 ; LAB D0000 + DB $54,C0034 ; CALL C0034 + DB $30 ; DROP +; 2842: crout() + DB $54,C0046 ; CALL C0046 +; 2843: prstr(@badfile) + DB $26,D0089 ; LA D0089 + DB $54,C0020 ; CALL C0020 +; 2844: fin +C0881: +; 2845: cin() + DB $54,C0018 ; CALL C0018 +; 2846: ; crout +; 2847: ; dumpsym(@idglobal_tbl, globals) +; 2848: ; crout +; 2849: fin +C0878: +C0879: +; 2850: done + DB $5C ; RET diff --git a/plasma2/plib.s b/plasma2/plib.s new file mode 100755 index 0000000..97e8502 --- /dev/null +++ b/plasma2/plib.s @@ -0,0 +1,64 @@ +.PC02 +.DEFINE EQU = +.DEFINE DB .BYTE +.DEFINE DW .WORD +.DEFINE DS .RES +;* +;* LANGUAGE CARD CONTROL +;* +LCBNK2 EQU $C080 +ROMIN EQU $C081 +;* +;* LOAD VMCORE FILE +;* +;LOADVM: + LDA #$00 + INC ; ONLY WORKS ON 65C02 + CMP #$01 + BEQ LDVMC02 +LDVM02: LDA #VMCORE + STA $07 + BNE :+ +LDVMC02: LDA #VMCOREC + STA $07 +;* +;* MOVE VM INTO LANGUAGE CARD +;* +: LDA #$00 + STA $08 + LDA #$D0 + STA $09 + LDY #$00 + BIT $C083 ; SELECT AND WE LC BANK 2 + BIT $C083 +MVVM: LDA ($06),Y + STA ($08),Y + INY + BNE MVVM + INC $07 + INC $09 + LDA $09 + CMP #$E0 + BNE MVVM + BIT ROMIN +;* +;* LOOK FOR STARTUP FILE +;* + +;* +;* EXIT TO PRODOS +;* +EXIT: JSR $BF00 + DB $65 + DW EXITPARMS +EXITPARMS: + DB 4 + DB 0 +VMCORE: + .INCLUDE "vmcore.byte" +VMCOREC: + .INCLUDE "vmcorec.byte" diff --git a/plasma2/plide.cfg b/plasma2/plide.cfg new file mode 100755 index 0000000..2bc7ee1 --- /dev/null +++ b/plasma2/plide.cfg @@ -0,0 +1,10 @@ +MEMORY { + RAM: start = $2000, size = $5000, file = %O; +} +SEGMENTS { + CODE: load = RAM, type = rw; + DATA: load = RAM, type = rw; + BSS: load = RAM, type = rw; +} + + diff --git a/plasma2/plide.pla b/plasma2/plide.pla new file mode 100755 index 0000000..cf41ea4 --- /dev/null +++ b/plasma2/plide.pla @@ -0,0 +1,3845 @@ +; +; Global constants +; +const FALSE = 0 +const TRUE = !FALSE +; +; Hardware constants +; +const csw = $0036 +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 pushbttn1 = $C061 +const pushbttn2 = $C062 +const pushbttn3 = $C063 +const keyboard = $C000 +const keystrobe = $C010 +const keyenter = $8D +const keyspace = $A0 +const keyarrowup = $8B +const keyarrowdown = $8A +const keyarrowleft = $88 +const keyarrowright = $95 +const keyescape = $9B +const keyctrla = $81 +const keyctrlb = $82 +const keyctrlc = $83 +const keyctrld = $84 +const keyctrle = $85 +const keyctrli = $89 +const keyctrlk = $8B +const keyctrll = $8C +const keyctrln = $8E +const keyctrlo = $8F +const keyctrlp = $90 +const keyctrlq = $91 +const keyctrlr = $92 +const keyctrls = $93 +const keyctrlt = $94 +const keyctrlu = $95 +const keyctrlv = $96 +const keyctrlw = $97 +const keyctrlx = $98 +const keyctrlz = $9A +const keydelete = $FF +const getbuff = $01FF +const argbuff = $2006 +word txtscrn[] = $0400,$0480,$0500,$0580,$0600,$0680,$0700,$0780 +word = $0428,$04A8,$0528,$05A8,$0628,$06A8,$0728,$07A8 +word = $0450,$04D0,$0550,$05D0,$0650,$06D0,$0750,$07D0 +; +; Data and text buffer constants +; +const machid = $BF98 +const maxlines = 626 +const maxfill = 640 +const iobuffer = $0800 +const databuff = $0C00 +const strlinbuf = $1000 +const strheapmap = $1500 +const strheapmsz = $70 ; = memory@16 bytes per bit map, 128 bytes per 8 bit map, 1K bytes per 8 byte map +const maxlnlen = 79 +const strheap = $7000 +const strheasz = $3800 +const codebuff = $A800 +const codebuffsz = $1000 +const pgjmp = 16 +const changed = 1 +const insmode = 2 +const showcurs = 4 +const uppercase = 8 +const shiftlock = 128 +; +; Editor variables +; +byte nullstr[] = "" +byte version[] = "PLASMA ][ IDE VERSION 0.8 " +byte errorstr[] = "ERROR: $" +byte okstr[] = "OK" +byte perr +byte outofmem[] = "OUT OF MEMORY!" +byte losechng[] = "LOSE CHANGES TO FILE (Y/N)?" +;byte emiterr[] = "EMIT CODE/DATA MISMATCH" +byte untitled[] = "UNTITLED" +byte txtfile[64] = "UNTITLED.PLA" +byte flags = 0 +byte flash = 0 +byte cursx, cursy, scrnleft, curscol, underchr, curschr +word cursrow, scrntop, cursptr +word numlines = 0 +word cutbuf = 0 +word keyin_01 +; +; Predeclared functions +; +func cmdmode +; +; Compiler variables +; +; +; Tokens +; +const ID_TKN = $D6 ; V +const CHR_TKN = $C3 ; C +const INT_TKN = $C9 ; I +const STR_TKN = $D3 ; S +const EOL_TKN = $02 +const EOF_TKN = $01 +const ERR_TKN = $00 +; +; Binary operand operators +; +const SET_TKN = $BD ; = +const SETLIST_TKN = $B9 ; =, +const ADD_TKN = $AB ; + +const SUB_TKN = $AD ; - +const MUL_TKN = $AA ; * +const DIV_TKN = $AF ; / +const MOD_TKN = $A5 ; % +const OR_TKN = $BF ; ? +const EOR_TKN = $DE ; ^ +const AND_TKN = $A6 ; & +const SHR_TKN = $D2 ; R +const SHL_TKN = $CC ; L +const GT_TKN = $BE ; > +const GE_TKN = $C8 ; H +const LT_TKN = $BC ; < +const LE_TKN = $C2 ; B +const NE_TKN = $D5 ; U +const EQ_TKN = $C5 ; E +const LOGIC_AND_TKN = $CE ; N +const LOGIC_OR_TKN = $CF ; O +; +; Unary operand operators +; +const AT_TKN = $C0 ; @ +const DOT_TKN = $AE ; . +const COLON_TKN = $BA ; : +const NEG_TKN = $AD ; - +const COMP_TKN = $A3 ; # +const LOGIC_NOT_TKN = $A1 ; ! +const BPTR_TKN = $DE ; ^ +const WPTR_TKN = $AA ; * +const INC_TKN = $C1 ; A +const DEC_TKN = $C4 ; D +; +; Enclosure tokens +; +const OPEN_PAREN_TKN = $A8 ; ( +const CLOSE_PAREN_TKN = $A9 ; ) +const OPEN_BRACKET_TKN = $DB ; [ +const CLOSE_BRACKET_TKN = $DD ; ] +; +; Misc. tokens +; +const COMMA_TKN = $AC ; , +const COMMENT_TKN = $BB ; ; +; +; Keyword tokens +; +const CONST_TKN = $80 +const BYTE_TKN = $81 +const WORD_TKN = $82 +const IF_TKN = $83 +const ELSEIF_TKN = $84 +const ELSE_TKN = $85 +const FIN_TKN = $86 +const END_TKN = $87 +const WHILE_TKN = $88 +const LOOP_TKN = $89 +const CASE_TKN = $8A +const OF_TKN = $8B +const DEFAULT_TKN = $8C +const ENDCASE_TKN = $8D +const FOR_TKN = $8E +const TO_TKN = $8F +const DOWNTO_TKN = $90 +const STEP_TKN = $91 +const NEXT_TKN = $92 +const REPEAT_TKN = $93 +const UNTIL_TKN = $94 +const IFUNC_TKN = $95 +const NFUNC_TKN = $96 +const DROP_TKN = $97 +const DONE_TKN = $98 +const RETURN_TKN = $99 +const BREAK_TKN = $9A +const START_TKN = $9B +const EXIT_TKN = $9C +const EVAL_TKN = $9D +const FUNC_TKN = $9E +; +; Types +; +const CONST_TYPE = $01 +const BYTE_TYPE = $02 +const WORD_TYPE = $04 +const VAR_TYPE = $06 ; (WORD_TYPE | BYTE_TYPE) +const FUNC_TYPE = $08 +const FUNC_CONST_TYPE = $09 +const ADDR_TYPE = $0E ; (VAR_TYPE | FUNC_TYPE) +const LOCAL_TYPE = $10 +const BPTR_TYPE = $20 +const WPTR_TYPE = $40 +const PTR_TYPE = $60 ; (BPTR_TYPE | WPTR_TYPE) +const XBYTE_TYPE = $22 ; (BPTR_TYPE | BYTE_TYPE) +const XWORD_TYPE = $44 ; (WPTR_TYPE | WORD_TYPE) +const STR_TYPE = $80 +; +; Keywords +; +byte keywrds[] +byte = "IF", IF_TKN +byte = "TO", TO_TKN +byte = "IS", OF_TKN +byte = "OR", LOGIC_OR_TKN +byte = "FOR", FOR_TKN +byte = "FIN", FIN_TKN +byte = "DEF", IFUNC_TKN +byte = "END", END_TKN +byte = "AND", LOGIC_AND_TKN +byte = "NOT", LOGIC_NOT_TKN +byte = "BYTE", BYTE_TKN +byte = "WORD", WORD_TKN +byte = "DROP", DROP_TKN +byte = "ELSE", ELSE_TKN +byte = "NEXT", NEXT_TKN +byte = "WHEN", CASE_TKN +byte = "LOOP", LOOP_TKN +byte = "FUNC", FUNC_TKN +byte = "STEP", STEP_TKN +byte = "EXIT", EXIT_TKN +byte = "DONE", DONE_TKN +byte = "WEND", ENDCASE_TKN +byte = "CONST", CONST_TKN +byte = "ELSIF", ELSEIF_TKN +byte = "WHILE", WHILE_TKN +byte = "UNTIL", UNTIL_TKN +byte = "BREAK", BREAK_TKN +byte = "OTHER", DEFAULT_TKN +byte = "DOWNTO", DOWNTO_TKN +byte = "REPEAT", REPEAT_TKN +byte = "DEFOPT", NFUNC_TKN +byte = "RETURN", RETURN_TKN +byte = $FF +; +; Mathematical ops +; +const bops_tblsz = 18 ; minus 1 +byte bops_tbl[] ; Highest precedence +byte = MUL_TKN, DIV_TKN, MOD_TKN +byte = ADD_TKN, SUB_TKN +byte = SHR_TKN, SHL_TKN +byte = AND_TKN +byte = EOR_TKN +byte = OR_TKN +byte = GT_TKN, GE_TKN, LT_TKN, LE_TKN +byte = EQ_TKN, NE_TKN +byte = LOGIC_AND_TKN +byte = LOGIC_OR_TKN +byte = COMMA_TKN + ; Lowest precedence +byte bops_prec[] ; Highest precedence +byte = 1, 1, 1 +byte = 2, 2 +byte = 3, 3 +byte = 4 +byte = 5 +byte = 6 +byte = 7, 7, 7, 7 +byte = 8, 8 +byte = 9 +byte = 10 +byte = 11 + ; Lowest precedence +byte opstack[16] +byte precstack[16] +word opsp = -1 +; +; Symbol table variables +; +const idglobal_tblsz = 2048 +const idlocal_tblsz = 512 +const idglobal_tbl = $1600 +const idlocal_tbl = $1E00 +const ctag_max = 640 +const ctag_value = $800 +const ctag_flags = $D80 +const idval = 0 +const idtype = 2 +const idname = 3 +const idrecsz = 4 +word globals = 0 +word datasize = 0 +word lastglobal +byte locals = 0 +word framesize = 0 +word lastlocal +const resolved = 1 +const is_ctag = $8000 +const mask_ctag = $7FFF +word codetag = -1 +word codeptr, entrypoint = 0 +byte lastop = $FF +; +; Scanner variables +; +const inbuff = $0200 +const instr = $01FF +byte token, tknlen +byte parserrpos, parserr = 0 +word scanptr, tknptr, parserrln +word constval +word lineno = 0 +; +; Compiler output messages +; +byte entrypt_str[] = "START: " +byte comp_ok_msg[] = "COMPILATION COMPLETE" +byte dup_id[] = "DUPLICATE IDENTIFIER" +byte undecl_id[] = "UNDECLARED IDENTIFIER" +byte bad_cnst[] = "BAD CONSTANT" +byte bad_offset[] = "BAD STRUCT OFFSET" +byte bad_decl[] = "BAD DECLARATION" +byte bad_op[] = "BAD OPERATION" +byte bad_stmnt[] = "BAD STATMENT" +byte bad_expr[] = "BAD EXPRESSION" +byte bad_syntax[] = "BAD SYNTAX" +byte estk_overflw[] = "EVAL STACK OVERFLOW" +byte estk_underflw[] = "EVAL STACK UNDERFLOW" +byte local_overflw[] = "LOCAL FRAME OVERFLOW" +byte global_sym_overflw[] = "GLOBAL SYMBOL TABLE OVERFLOW" +byte local_sym_overflw[] = "LOCAL SYMBOL TABLE OVERFLOW" +byte ctag_full[] = "CODE LABEL OVERFLOW" +byte no_close_paren[] = "MISSING CLOSING PAREN" +byte no_close_bracket[] = "MISSING CLOSING BRACKET" +byte missing_op[] = "MISSING OPERAND" +byte no_fin[] = "MISSING FIN" +byte no_loop[] = "MISSING LOOP" +byte no_until[] = "MISSING UNTIL" +byte no_done[] = "MISSING DONE" +byte no_local_init[] = "NO INITIALIZED LOCALS" +; +; Runtime messages +; +byte brkmsg[] = "CTRL-C BREAK" +byte stkovflwmsg[] = "STACK OVERFLOW/UNDERFLOW ERROR" +; +; Runtime functions +; +byte runtime0[] = "romcall" +byte RUNTIME0[] = "ROMCALL" +byte runtime1[] = "syscall" +byte RUNTIME1[] = "SYSCALL" +byte runtime2[] = "memset" +byte RUNTIME2[] = "MEMSET" +byte runtime3[] = "memcpy" +byte RUNTIME3[] = "MEMCPY" +byte runtime4[] = "cout" +byte RUNTIME4[] = "COUT" +byte runtime5[] = "cin" +byte RUNTIME5[] = "CIN" +byte runtime6[] = "prstr" +byte RUNTIME6[] = "PRSTR" +byte runtime7[] = "rdstr" +byte RUNTIME7[] = "RDSTR" +; +; Parser variables +; +byte infunc = 0 +byte stack_loop = 0 +byte prevstmnt = 0 +word retfunc_tag = 0 +word break_tag = 0 +func parse_expr_01, parse_module_01 +; +; Utility functions +; +; Defines for ASM routines +; +asm equates + TMP EQU $F0 + TMPL EQU TMP + TMPH EQU TMP+1 + SRC EQU TMP + SRCL EQU SRC + SRCH EQU SRC+1 + DST EQU SRC+2 + DSTL EQU DST + DSTH EQU DST+1 + ESP EQU DST+2 + SAVEESP EQU ESP+1 + SAVESP EQU SAVEESP+1 + SAVEFP EQU SAVESP+1 + SAVETMR EQU SAVEFP+2 + SAVEINT EQU SAVETMR+2 + TMRVEC EQU $03E8 + INTVEC EQU $03EA +JMPTMP: JMP (TMP) +STKOVFLW: + LDY #$02 + JMP EXECRET +BRKCHK: + LDA $C000 + CMP #$83 ; CTRL-C + BNE :+ + BIT $C010 + LDY #$01 + JMP EXECRET +: +end +; +; ENTER MODULE UNDER TEST +; +asm execentry + LDA ESTKL,X + STA TMPL + LDA ESTKH,X + STA TMPH + STX SAVEESP + TSX + STX SAVESP + LDA FRMPL + STA SAVEFP + LDA FRMPH + STA SAVEFP+1 + LDA TMRVEC + STA SAVETMR + LDA TMRVEC+1 + STA SAVETMR+1 + LDA INTVEC + STA SAVEINT + LDA INTVEC+1 + STA SAVEINT+1 + LDA #BRKCHK + STA TMRVEC+1 + LDA #STKOVFLW + STA INTVEC+1 + LDX #ESTKSZ/2 + JSR JMPTMP + LDY #$00 +EXECRET: + STY TMP + BIT ROMIN + BIT $C054 + BIT $C051 + BIT $C058 + JSR $FB39 ; SET TEXT MODE + BIT LCBNK2 + LDA SAVEFP + STA FRMPL + LDA SAVEFP+1 + STA FRMPH + LDA SAVETMR + STA TMRVEC + LDA SAVETMR+1 + STA TMRVEC+1 + LDA SAVEINT + STA INTVEC + LDA SAVEINT+1 + STA INTVEC+1 + LDX SAVESP + TXS + LDX SAVEESP + LDY TMP + STY ESTKL,X + LDY #$00 + STY ESTKH,X +end +; +; CALL 6502 ROUTINE +; ROMCALL(AREG, XREG, YREG, STATUS, ADDR) +; +asm romcall + PHP + LDA ESTKL,X + STA TMPL + LDA ESTKH,X + STA TMPH + INX + LDA ESTKL,X + PHA + INX + LDA ESTKL,X + TAY + INX + LDA ESTKL+1,X + PHA + LDA ESTKL,X + INX + STX ESP + TAX + PLA + BIT ROMIN + PLP + JSR JMPTMP + PHP + BIT LCBNK2 + STA REGVALS+0 + STX REGVALS+1 + STY REGVALS+2 + PLA + STA REGVALS+3 + LDX ESP + LDA #REGVALS + STA ESTKL,X + STY ESTKH,X + PLP + RTS +REGVALS: DS 4 +end +; +; CALL PRODOS +; SYSCALL(CMD, PARAMS) +; +asm syscall + LDA ESTKL,X + LDY ESTKH,X + STA PARAMS + STY PARAMS+1 + INX + LDA ESTKL,X + STA CMD + STX ESP + JSR $BF00 +CMD: DB 00 +PARAMS: DW 0000 + BIT LCBNK2 + LDX ESP + STA ESTKL,X + LDY #$00 + STY ESTKH,X +end +; +; SET MEMORY TO VALUE +; MEMSET(VALUE, ADDR, SIZE) +; +asm memset + LDY #$00 + LDA ESTKL+1,X + STA DSTL + LDA ESTKH+1,X + STA DSTH + INC ESTKL,X + INC ESTKH,X +SETMEM: DEC ESTKL,X + BNE :+ + DEC ESTKH,X + BEQ MEMEXIT +: LDA ESTKL+2,X + STA (DST),Y + INY + BNE :+ + INC DSTH +: DEC ESTKL,X + BNE :+ + DEC ESTKH,X + BEQ MEMEXIT +: LDA ESTKH+2,X + STA (DST),Y + INY + BNE SETMEM + INC DSTH + BNE SETMEM +MEMEXIT: INX + INX + INX +end +; +; COPY MEMORY +; MEMCPY(SRCADDR, DSTADDR, SIZE) +; +asm memcpy + LDY #$00 + LDA ESTKL,X + BNE :+ + LDA ESTKH,X + BEQ MEMEXIT +: LDA ESTKL+1,X + STA DSTL + LDA ESTKH+1,X + STA DSTH + LDA ESTKL+2,X + STA SRCL + LDA ESTKH+2,X + STA SRCH + CMP DSTH + BCC REVCPY + BNE FORCPY + LDA SRCL + CMP DSTL + BCS FORCPY +REVCPY: ; REVERSE DIRECTION COPY +; CLC + LDA ESTKL,X + ADC DSTL + STA DSTL + LDA ESTKH,X + ADC DSTH + STA DSTH + CLC + LDA ESTKL,X + ADC SRCL + STA SRCL + LDA ESTKH,X + ADC SRCH + STA SRCH + INC ESTKH,X +REVCPYLP: + LDA DSTL + BNE :+ + DEC DSTH +: DEC DSTL + LDA SRCL + BNE :+ + DEC SRCH +: DEC SRCL + LDA (SRC),Y + STA (DST),Y + DEC ESTKL,X + BNE REVCPYLP + DEC ESTKH,X + BNE REVCPYLP + BEQ MEMEXIT +FORCPY: INC ESTKH,X +FORCPYLP: + LDA (SRC),Y + STA (DST),Y + INC DSTL + BNE :+ + INC DSTH +: INC SRCL + BNE :+ + INC SRCH +: DEC ESTKL,X + BNE FORCPYLP + DEC ESTKH,X + BNE FORCPYLP + BEQ MEMEXIT +end +; +; CHAR OUT +; COUT(CHAR) +; +asm cout + LDA ESTKL,X + INX + ORA #$80 + BIT ROMIN + JSR $FDED + BIT LCBNK2 +end +; +; CHAR IN +; RDKEY() +; +asm cin + BIT ROMIN + STX ESP + JSR $FD0C + LDX ESP + BIT LCBNK2 + DEX + AND #$7F + STA ESTKL,X + LDY #$00 + STY ESTKH,X +end +; +; PRINT STRING +; PRSTR(STR) +; +asm prstr + LDY #$00 + LDA ESTKL,X + STA SRCL + LDA ESTKH,X + STA SRCH + BIT ROMIN + LDA (SRC),Y + STA ESTKL,X + BEQ :+ +_PRS1: INY + LDA (SRC),Y + ORA #$80 + JSR $FDED + TYA + CMP ESTKL,X + BNE _PRS1 +: INX + BIT LCBNK2 +end +; +; READ STRING +; STR = RDSTR(PROMPTCHAR) +; +asm rdstr + LDA ESTKL,X + STA $33 + STX ESP + BIT ROMIN + JSR $FD6A + BIT LCBNK2 + STX $01FF +: LDA $01FF,X + AND #$7F + STA $01FF,X + DEX + BPL :- + LDX ESP + LDA #$FF + STA ESTKL,X + LDA #$01 + STA ESTKH,X +end +; +; EXIT +; +asm exit + JSR $BF00 + DB $65 + DW EXITTBL +EXITTBL: + DB 4 + DB 0 +end +; +; ProDOS routines +; +def getpfx_11(path) + byte params[3] + + ^path = 0 + params.0 = 1 + params:1 = path + perr = syscall($C7, @params) + return path +end +def setpfx_11(path) + byte params[3] + + params.0 = 1 + params:1 = path + perr = syscall($C6, @params) + return path +end +def open_21(path, buff) + byte params[6] + + params.0 = 3 + params:1 = path + params:3 = buff + params.5 = 0 + perr = syscall($C8, @params) + return params.5 +end +def close_11(refnum) + byte params[2] + + params.0 = 1 + params.1 = refnum + perr = syscall($CC, @params) + return perr +end +def read_31(refnum, buff, len) + byte params[8] + + params.0 = 4 + params.1 = refnum + params:2 = buff + params:4 = len + params:6 = 0 + perr = syscall($CA, @params) + return params:6 +end +def write_31(refnum, buff, len) + byte params[8] + + params.0 = 4 + params.1 = refnum + params:2 = buff + params:4 = len + params:6 = 0 + perr = syscall($CB, @params) + return params:6 +end +def create_41(path, access, type, aux) + byte params[12] + + params.0 = 7 + params:1 = path + params.3 = access + params.4 = type + params:5 = aux + params.7 = $1 + params:8 = 0 + params:10 = 0 + perr = syscall($C0, @params) + return perr +end +def destroy_11(path) + byte params[12] + + params.0 = 1 + params:1 = path + perr = syscall($C1, @params) + return perr +end +def newline_31(refnum, emask, nlchar) + byte params[4] + + params.0 = 3 + params.1 = refnum + params.2 = emask + params.3 = nlchar + perr = syscall($C9, @params) + return perr +end + +;===================================== +; +; Editor +; +;===================================== + +def crout + cout($0D) +end +def bell + drop romcall(0, 0, 0, 0, $FBDD) +end +; +; Memory management routines +; +defopt strcpy_20(srcstr, dststr) + byte strlen + + strlen = ^srcstr + while (srcstr).[strlen] == $8D or (srcstr).[strlen] == $A0 + strlen = strlen - 1 + loop + ^dststr = strlen + memcpy(srcstr + 1, dststr + 1, strlen) +end +defopt heapaddr_21(ofst, mask) + word addr + + addr = (ofst << 7) + strheap + while !(mask & 1) + addr = addr + 16 + mask = mask >> 1 + loop + return addr +end +defopt sizemask_11(size) + if size <= 16 + return $01 + elsif size <= 32 + return $03 + elsif size <= 48 + return $07 + elsif size <= 64 + return $0F + elsif size <= 80 + return $1F + fin + return 0 +end +defopt heapalloc_11(size) + byte szmask, i + word mapmask + + szmask = sizemask_11(size) + for i = strheapmsz - 1 downto 0 + if strheapmap.[i] <> $FF + mapmask = szmask + repeat + if strheapmap.[i] & mapmask + mapmask = mapmask << 1 + else + strheapmap.[i] = strheapmap.[i] ? mapmask + return heapaddr_21(i, mapmask) + fin + until mapmask & $100 + fin + next + bell() + prstr(@outofmem) + return 0 +end +def freestr_10(strptr) + byte mask, ofst + + if strptr and strptr <> @nullstr + mask = sizemask_11(^strptr + 1) + ofst = (strptr - strheap) >> 4 + mask = mask << (ofst & $07) + ofst = ofst >> 3 + strheapmap.[ofst] = strheapmap.[ofst] & #mask + fin +end +def newstr_11(strptr) + byte strlen + word newptr + + strlen = ^strptr + while (strptr).[strlen] == $8D or (strptr).[strlen] == $A0 + strlen = strlen - 1 + loop + if strlen == 0 + return @nullstr + fin + newptr = heapalloc_11(strlen + 1) + if newptr + memcpy(strptr, newptr, strlen + 1) + ^newptr = strlen + return newptr + fin + return @nullstr +end +def inittxtbuf + word i + + memset(0, strheapmap, strheapmsz) + memset(@nullstr, strlinbuf, maxfill * 2) + entrypoint = 0 + numlines = 0 + cursrow = 0 + curscol = 0 + cursx = 0 + cursy = 0 + scrnleft = 0 + scrntop = 0 + cutbuf = 0 +end +; +; Case conversion/printing routines +; +def caseconv_11(chr) + if flags & uppercase + if chr & $E0 == $E0 + chr = chr - $E0 + fin + fin + return chr +end +def strupper_10(strptr) + byte i, chr + + for i = ^strptr downto 1 + chr = (strptr).[i] + if chr & $E0 == $E0 + (strptr).[i] = chr - $E0 + fin + next +end +def strlower_10(strptr) + byte i, chr + + for i = ^strptr downto 1 + chr = (strptr).[i] + if chr & $E0 == $00 + (strptr).[i] = chr + $E0 + fin + next +end +def txtupper + word i, strptr + + flags = flags ? uppercase + for i = numlines - 1 downto 0 + strupper_10(strlinbuf:[i]) + next +end +def txtlower + word i, strptr + + flags = flags & #uppercase + for i = numlines - 1 downto 0 + strlower_10(strlinbuf:[i]) + next +end +def prbyte_10(h) + cout('$') + drop romcall(h, 0, 0, 0, $FDDA) +end +def prword_10(h) + cout('$') + drop romcall(h >> 8, h, 0, 0, $F941) +end +def print_10(i) + byte numstr[7] + byte place, sign + + place = 6 + if i < 0 + sign = 1 + i = -i + else + sign = 0 + fin + while i >= 10 + i =, numstr[place] = i % 10 + '0' + place = place - 1 + loop + numstr[place] = i + '0' + place = place - 1 + if sign + numstr[place] = '-' + place = place - 1 + fin + numstr[place] = 6 - place + prstr(@numstr[place]) +end +def nametostr_30(namestr, len, strptr) + ^strptr = len + memcpy(namestr, strptr + 1, len) +end +;def toupper_11(c) +; if c >= 'a' +; if c <= 'z' +; return c - $20 +; fin +; fin +; return c +;end +asm toupper_11 + LDA ESTKL,X + AND #$7F + CMP #'a' + BCC :+ + CMP #'z'+1 + BCS :+ + SEC + SBC #$20 +: STA ESTKL,X +end +asm clrhibit_10(strptr) + LDY #$02 ; strptr + LDA (FRMP),Y + STA SRCL + INY + LDA (FRMP),Y + STA SRCH + LDY #$00 + LDA (SRC),Y + BEQ :+ + TAY +CLHILP: LDA (SRC),Y + AND #$7F + STA (SRC),Y + DEY + BNE CLHILP +: +end +asm sethibit_10(strptr) + LDY #$02 ; strptr + LDA (FRMP),Y + STA SRCL + INY + LDA (FRMP),Y + STA SRCH + LDY #$00 + LDA (SRC),Y + BEQ :+ + TAY +STHILP: LDA (SRC),Y + ORA #$80 + STA (SRC),Y + DEY + BNE STHILP +: +end +asm cpyln_20(srcstr, dststr) + LDY #$02 ; srcstr + LDA (FRMP),Y + STA SRCL + INY + LDA (FRMP),Y + STA SRCH + INY ; dststr + LDA (FRMP),Y + STA DSTL + INY + LDA (FRMP),Y + STA DSTH + LDY #$00 + LDA (SRC),Y + TAY + LDA #$00 + INY + STA (DST),Y + DEY + BEQ :++ +CPLNLP: LDA (SRC),Y + CMP #$20 + BCS :+ + ADC #$60 +: AND #$7F + STA (DST),Y + DEY + BNE CPLNLP + LDA (SRC),Y +: STA (DST),Y +end +; +; File routines +; +def readtxt_10(filename) + byte txtbuf[81], refnum, i, j + + refnum = open_21(filename, iobuffer) + if refnum + drop newline_31(refnum, $7F, $0D) + repeat + txtbuf = read_31(refnum, @txtbuf + 1, maxlnlen) + if txtbuf + sethibit_10(@txtbuf) + if flags & uppercase + strupper_10(@txtbuf) + fin + strlinbuf:[numlines] = newstr_11(@txtbuf) + numlines = numlines + 1 + fin + if !(numlines & $0F) + cout('.') + fin + until txtbuf == 0 or numlines == maxlines + drop close_11(refnum) + fin + if numlines == 0 + numlines = 1 + fin +end +def writetxt_10(filename) + byte txtbuf[81], refnum + byte j, chr + word i, strptr + + drop destroy_11(filename) + drop create_41(filename, $C3, $04, $00) ; full access, TXT file + refnum = open_21(filename, iobuffer) + if refnum == 0 + return + fin + for i = 0 to numlines - 1 + cpyln_20(strlinbuf:[i], @txtbuf) + txtbuf = txtbuf + 1 + txtbuf[txtbuf] = $0D + drop write_31(refnum, @txtbuf + 1, txtbuf) + if !(i & $0F) + cout('.') + fin + next + drop close_11(refnum) +end +; +; Screen routines +; +def clrscrn + drop romcall(0, 0, 0, 0, $FC58) +end +def drawrow_30(row, ofst, strptr) + byte numchars + word scrnptr + + scrnptr = txtscrn[row] + if ^strptr <= ofst + numchars = 0 + else + numchars = ^strptr - ofst + fin + if numchars >= 40 + numchars = 40 + else + memset($A0A0, scrnptr + numchars, 40 - numchars) + fin + memcpy(strptr + ofst + 1, scrnptr, numchars) +end +defopt drawscrn_20(toprow, ofst) + byte row, numchars + word strptr, scrnptr + + for row = 0 to 23 + strptr = strlinbuf:[toprow + row] + scrnptr = txtscrn[row] + if ^strptr <= ofst + numchars = 0 + else + numchars = ^strptr - ofst + fin + if numchars >= 40 + numchars = 40 + else + memset($A0A0, scrnptr + numchars, 40 - numchars) + fin + memcpy(strptr + ofst + 1, scrnptr, numchars) + next +end +def cursoff + if flags & showcurs + ^cursptr = underchr + flags = flags & #showcurs + fin +end +def curson + if !(flags & showcurs) + cursptr = txtscrn[cursy] + cursx + underchr = ^cursptr + ^cursptr = curschr + flags = flags ? showcurs + fin +end +def cursflash() + if flags & showcurs + if flash == 0 + ^cursptr = curschr + elsif flash == 128 + ^cursptr = underchr + fin + flash = flash + 1 + fin +end +def redraw + cursoff() + drawscrn_20(scrntop, scrnleft) + curson() +end +def curshome + cursoff() + cursrow = 0 + curscol = 0 + cursx = 0 + cursy = 0 + scrnleft = 0 + scrntop = 0 + drawscrn_20(scrntop, scrnleft) + curson() +end +def cursend + cursoff() + if numlines > 23 + cursrow = numlines - 1 + cursy = 23 + scrntop = cursrow - 23 + else + cursrow = numlines - 1 + cursy = numlines - 1 + scrntop = 0 + fin + curscol = 0 + cursx = 0 + scrnleft = 0 + drawscrn_20(scrntop, scrnleft) + curson() +end +def cursup + if cursrow > 0 + cursoff() + cursrow = cursrow - 1 + if cursy > 0 + cursy = cursy - 1 + else + scrntop = cursrow + drawscrn_20(scrntop, scrnleft) + fin + curson() + fin +end +def pgup + byte i + + for i = pgjmp downto 0 + cursup() + next +end +def cursdown + if cursrow < numlines - 1 + cursoff() + cursrow = cursrow + 1 + if cursy < 23 + cursy = cursy + 1 + else + scrntop = cursrow - 23 + drawscrn_20(scrntop, scrnleft) + fin + curson() + fin +end +def pgdown + byte i + + for i = pgjmp downto 0 + cursdown() + next +end +def cursleft + if curscol > 0 + cursoff() + curscol = curscol - 1 + if cursx > 0 + cursx = cursx - 1 + else + scrnleft = curscol + drawscrn_20(scrntop, scrnleft) + fin + curson() + fin +end +def pgleft + byte i + + for i = 7 downto 0 + cursleft() + next +end +def cursright + if curscol < 80 + cursoff() + curscol = curscol + 1 + if cursx < 39 + cursx = cursx + 1 + else + scrnleft = curscol - 39 + drawscrn_20(scrntop, scrnleft) + fin + curson() + fin +end +def pgright + byte i + + for i = 7 downto 0 + cursright() + next +end +; +; Keyboard routines +; +def keyin2e_01 + repeat + cursflash() + until ^keyboard >= 128 + return ^keystrobe +end +def keyin2_01 + byte key + + repeat + cursflash() + key = ^keyboard + if key == keyctrll + drop ^keystrobe + flags = flags ^ shiftlock + key = 0 + fin + until key >= 128 + drop ^keystrobe + if key == keyctrln + key = $DB ; [ + elsif key == keyctrlp + key = $DF ; _ + elsif key == keyctrlb + key = $DC ; \ + elsif key == keyarrowleft + if ^pushbttn3 < 128 + key = $FF + fin + elsif key >= $C0 and flags < shiftlock + if ^pushbttn3 < 128 + if key == $C0 + key = $D0 ; P + elsif key == $DD + key = $CD ; M + elsif key == $DE + key = $CE ; N + fin + else + key = key ? $E0 + fin + fin + return key +end +; +; Printer routines +; +def printtxt_10(slot) + byte txtbuf[80] + word i, scrncsw + + scrncsw = *(csw) + *(csw) = $C000 ? (slot << 8) + for i = 0 to numlines - 1 + cpyln_20(strlinbuf:[i], @txtbuf) + prstr(@txtbuf) + crout() + next + *(csw) = scrncsw +end +def openline_11(row) + if numlines < maxlines + memcpy(@strlinbuf:[row], @strlinbuf:[row + 1], (numlines - row) * 2) + strlinbuf:[row] = @nullstr + numlines = numlines + 1 + flags = flags ? changed + return 1 + fin + bell() + return 0 +end +def cutline + freestr_10(cutbuf) + cutbuf = strlinbuf:[cursrow] + memcpy(@strlinbuf:[cursrow + 1], @strlinbuf:[cursrow], (numlines - cursrow) * 2) + if numlines > 1 + numlines = numlines - 1 + fin + flags = flags ? changed + if cursrow == numlines + cursup() + fin + redraw() +end +def pasteline + if cutbuf and numlines < maxlines + memcpy(@strlinbuf:[cursrow], @strlinbuf:[cursrow + 1], (numlines - cursrow) * 2) + strlinbuf:[cursrow] = newstr_11(cutbuf) + numlines = numlines + 1 + flags = flags ? changed + redraw() + else + bell() + fin +end +def joinline + byte joinstr[80], joinlen + + if cursrow < numlines - 1 + strcpy_20(strlinbuf:[cursrow], @joinstr) + joinlen = joinstr + ^(strlinbuf:[cursrow + 1]) + if joinlen < 80 + memcpy(strlinbuf:[cursrow + 1] + 1, @joinstr + joinstr + 1, ^(strlinbuf:[cursrow + 1])) + joinstr = joinlen + freestr_10(strlinbuf:[cursrow]) + strlinbuf:[cursrow] = newstr_11(@joinstr) + freestr_10(strlinbuf:[cursrow + 1]) + numlines = numlines - 1 + memcpy(@strlinbuf:[cursrow + 2], @strlinbuf:[cursrow + 1], (numlines - cursrow) * 2) + flags = flags ? changed + redraw() + else + bell() + fin + fin +end +def splitline + byte splitstr[80], splitlen + + if openline_11(cursrow + 1) + if curscol + splitlen = ^(strlinbuf:[cursrow]) + if curscol < splitlen - 1 + memcpy(strlinbuf:[cursrow] + curscol + 1, @splitstr + 1, splitlen - curscol) + splitstr = splitlen - curscol + strlinbuf:[cursrow + 1] = newstr_11(@splitstr) + memcpy(strlinbuf:[cursrow] + 1, @splitstr + 1, curscol) + splitstr = curscol + freestr_10(strlinbuf:[cursrow]) + strlinbuf:[cursrow] = newstr_11(@splitstr) + fin + else + strlinbuf:[cursrow + 1] = strlinbuf:[cursrow] + strlinbuf:[cursrow] = @nullstr + fin + curscol = 0 + cursx = 0 + scrnleft = 0 + redraw() + cursdown() + fin +end +def editkey_11(key) + if key >= keyspace + return 1 + elsif key == keydelete + return 1 + elsif key == keyctrld + return 1 + elsif key == keyctrlr + return 1 + fin + return 0 +end +def editline_11(key) + byte editstr[80] + word undoline + + if (editkey_11(key)) + flags = flags ? changed + memset($A0A0, @editstr, 80) + strcpy_20(strlinbuf:[cursrow], @editstr) + undoline = strlinbuf:[cursrow] + strlinbuf:[cursrow] = @editstr + repeat + if key >= keyspace + if key == keydelete + if curscol > 0 + if curscol <= editstr + memcpy(@editstr[curscol + 1], @editstr[curscol], editstr - curscol) + editstr = editstr - 1 + fin + curscol = curscol - 1 + cursoff() + if cursx > 0 + cursx = cursx - 1 + drawrow_30(cursy, scrnleft, @editstr) + else + scrnleft = scrnleft - 1 + drawscrn_20(scrntop, scrnleft) + fin + curson() + fin + elsif curscol < maxlnlen + curscol = curscol + 1 + cursx = cursx + 1 + if flags & insmode + if editstr < maxlnlen or editstr.maxlnlen == $A0 + editstr = editstr + 1 + if curscol >= editstr + editstr = curscol + else + memcpy(@editstr[curscol], @editstr[curscol + 1], editstr - curscol) + fin + else + curscol = curscol - 1 + cursx = cursx - 1 + key = editstr[curscol] + bell() + fin + else + if curscol > editstr + editstr = curscol + fin + fin + editstr[curscol] = caseconv_11(key) + cursoff() + if cursx <= 39 + drawrow_30(cursy, scrnleft, @editstr) + else + scrnleft = scrnleft + 1 + cursx = 39 + drawscrn_20(scrntop, scrnleft) + fin + curson() + else + bell() + fin + elsif key == keyctrld + if curscol < editstr + memcpy(@editstr[curscol + 2], @editstr[curscol + 1], editstr - curscol) + editstr = editstr - 1 + cursoff() + drawrow_30(cursy, scrnleft, @editstr) + curson() + fin + elsif key == keyctrlr + strcpy_20(undoline, @editstr) + cursoff() + drawrow_30(cursy, scrnleft, @editstr) + curson() + fin + key = keyin_01() + until !editkey_11(key) + if editstr + strlinbuf:[cursrow] = newstr_11(@editstr) + else + strlinbuf:[cursrow] = @nullstr + fin + freestr_10(undoline) + fin + return key +end +def editmode + repeat + when editline_11(keyin_01()) + is keyarrowup + cursup() + is keyarrowdown + cursdown() + is keyarrowleft + cursleft() + is keyarrowright + cursright() + is keyctrlw + pgup() + is keyctrlz + pgdown() + is keyctrla + pgleft() + is keyctrls + pgright() + is keyctrlq + curshome() + is keyctrle + cursend() + is keyctrlx + cutline() + is keyctrlv + pasteline() + is keyctrlo + drop openline_11(cursrow) + redraw() + is keyenter + if flags & insmode + splitline() + else + drop openline_11(cursrow + 1) + cursdown() + redraw() + fin + is keyctrlt + joinline() + is keyctrli + if flags & insmode + flags = flags & #insmode + curschr = ' ' + else + flags = flags ? insmode + curschr = '+' + fin + is keyctrlc + if flags & uppercase + txtlower() + else + txtupper() + fin + redraw() + is keyescape + cursoff() + cmdmode() + redraw() + wend + until 0 +end +; +; Command mode +; +def prfiles_11(optpath) + byte path[64] + byte refnum + byte firstblk + byte entrylen, entriesblk + byte i, type, len + word entry, filecnt + + if ^optpath + strcpy_20(optpath, @path) + else + drop getpfx_11(@path) + prstr(@path) + crout() + fin + refnum = open_21(@path, iobuffer); + if perr + return perr + fin + firstblk = 1 + repeat + if read_31(refnum, databuff, 512) == 512 + entry = databuff + 4 + if firstblk + entrylen = databuff.$23 + entriesblk = databuff.$24 + filecnt = databuff:$25 + entry = entry + entrylen + fin + for i = firstblk to entriesblk + type = ^entry + if type <> 0 + len = type & $0F + ^entry = len + prstr(entry) + if type & $F0 == $D0 ; Is it a directory? + cout('/') + len = len + 1 + fin + for len = 20 - len downto 1 + cout(' ') + next + filecnt = filecnt - 1 + fin + entry = entry + entrylen + next + firstblk = 0 + else + filecnt = 0 + fin + until filecnt == 0 + drop close_11(refnum) + crout() + return 0 +end +def striplead_20(strptr, chr) + while ^strptr and ^(strptr + 1) == chr + memcpy(strptr + 2, strptr + 1, ^strptr) + ^strptr = ^strptr - 1 + loop +end +def parsecmd_11(strptr) + byte cmd + + cmd = 0 + striplead_20(strptr, ' ') + if ^strptr + cmd = ^(strptr + 1) + memcpy(strptr + 2, strptr + 1, ^strptr) + ^strptr = ^strptr - 1 + fin + if ^strptr + striplead_20(strptr, ' ') + fin + return cmd +end +def chkchng_01 + if flags & changed + prstr(@losechng) + if toupper_11(keyin_01()) == 'N' + crout() + return 0 + fin + crout() + fin + return 1 +end +def exec + when execentry() + is 1 + crout() + prstr(@brkmsg) + crout() + is 2 + crout() + prstr(@stkovflwmsg) + crout() + wend + ; + ; Close all files + ; + ^$BFD8 = 0 + drop close_11(0) +end +def quit + if chkchng_01() + exit + fin +end +def cmdmode + byte slot + word cmdptr + + clrscrn(); + prstr(@version) + crout() + while 1 + prstr(@txtfile) + cmdptr = rdstr($BA) + when toupper_11(parsecmd_11(cmdptr)) + is 'A' + readtxt_10(cmdptr) + flags = flags ? changed + is 'R' + if chkchng_01() + inittxtbuf() + strcpy_20(cmdptr, @txtfile) + readtxt_10(@txtfile) + entrypoint = 0 + flags = flags & #changed + fin + is 'W' + if ^cmdptr + strcpy_20(cmdptr, @txtfile) + fin + writetxt_10(@txtfile) + if flags & changed + entrypoint = 0 + fin + flags = flags & #changed + is 'Q' + quit() + is 'C' + drop prfiles_11(cmdptr) + is 'P' + drop setpfx_11(cmdptr) + is 'H' + if ^cmdptr + slot = cmdptr.1 - '0' + else + slot = 1 + fin + printtxt_10(slot) + is 'E' + return + is 0 + return + is 'N' + if chkchng_01() + inittxtbuf() + numlines = 1 + strcpy_20(@untitled, @txtfile) + fin + is 'X' + if flags & changed or !entrypoint + drop parse_module_01() + if parserr + bell() + cursrow = parserrln + scrntop = cursrow & $FFF8 + cursy = cursrow - scrntop + curscol = parserrpos + scrnleft = curscol & $FFE0 + cursx = curscol - scrnleft + else + crout() + exec(entrypoint) + fin + else + exec(entrypoint) + fin + crout() + is 'V' + prstr(@version) + wend + if perr + prstr(@errorstr) + drop romcall(perr, 0, 0, 0, $FDDA) + else + prstr(@okstr) + fin + crout() + loop +end + +;===================================== +; +; PLASMA Compiler +; +;===================================== + +; +; Error handler +; +def parse_err_11(err) + if !parserr + parserr = TRUE + parserrln = lineno - 1 + parserrpos = tknptr - inbuff + print_10(lineno) + cout(':') + prstr(err) + crout() + fin + return ERR_TKN +end +; +; Emit bytecode +; +def ctag_new_01 + if codetag >= ctag_max + return parse_err_11(@ctag_full) + fin + codetag = codetag + 1 + ctag_value:[codetag] = 0 + ctag_flags.[codetag] = 0 + return codetag ? is_ctag +end +defopt ctag_resolve_21(tag, addr) + word updtptr, nextptr + + tag = tag & mask_ctag + if ctag_flags.[tag] & resolved + return parse_err_11(@dup_id) + fin + updtptr = ctag_value:[tag] + while updtptr + ; + ; Update list of addresses needing resolution + ; + nextptr = *updtptr + *updtptr = addr + updtptr = nextptr + loop + ctag_value:[tag] = addr + ctag_flags.[tag] = ctag_flags.[tag] ? resolved + return 0 +end +defopt emit_byte_10(bval) + ^codeptr = bval + codeptr = codeptr + 1 +end +defopt emit_word_10(wval) + *codeptr = wval + codeptr = codeptr + 2 +end +def emit_fill_10(size) + memset(0, codeptr, size) + codeptr = codeptr + size +end +def emit_codetag_10(tag) + drop ctag_resolve_21(tag, codeptr) +end +defopt emit_op_10(op) + lastop = op + ^codeptr = op + codeptr = codeptr + 1 +end +def emit_tag_10(tag) + word updtptr + + if tag & is_ctag + tag = tag & mask_ctag + updtptr = ctag_value:[tag] + if !(ctag_flags.[tag] & resolved) + ; + ; Add to list of tags needing resolution + ; + ctag_value:[tag] = codeptr + fin + emit_word_10(updtptr) + else + emit_word_10(tag + codebuff) + fin +end +def emit_iddata_30(value, size, namestr) + emit_fill_10(size) +end +def emit_data_41(vartype, consttype, constval, constsize) + byte i + word size, chrptr + + if consttype == 0 + size = constsize + emit_fill_10(constsize) + elsif consttype == STR_TYPE + size = constsize + chrptr = constval + constsize = constsize - 1 + emit_byte_10(constsize) + while constsize > 0 + emit_byte_10(^chrptr) + chrptr = chrptr + 1 + constsize = constsize - 1 + loop + else + if vartype == WORD_TYPE + size = 2 + emit_word_10(constval) + else + size = 1 + emit_byte_10(constval) + fin + fin + return size +end +def emit_const_10(cval) + if cval == 0 + emit_op_10($00) + elsif cval > 0 and cval < 256 + emit_op_10($2A) + emit_byte_10(cval) + else + emit_op_10($2C) + emit_word_10(cval) + fin +end +def emit_lb + emit_op_10($60) +end +def emit_lw + emit_op_10($62) +end +def emit_llb_10(index) + emit_op_10($64) + emit_byte_10(index) +end +def emit_llw_10(index) + emit_op_10($66) + emit_byte_10(index) +end +def emit_lab_10(tag) + emit_op_10($68) + emit_tag_10(tag) +end +def emit_law_10(tag) + emit_op_10($6A) + emit_tag_10(tag) +end +def emit_sb + emit_op_10($70) +end +def emit_sw + emit_op_10($72) +end +def emit_slb_10(index) + emit_op_10($74) + emit_byte_10(index) +end +def emit_slw_10(index) + emit_op_10($76) + emit_byte_10(index) +end +def emit_dlb_10(index) + emit_op_10($6C) + emit_byte_10(index) +end +def emit_dlw_10(index) + emit_op_10($6E) + emit_byte_10(index) +end +def emit_sab_10(tag) + emit_op_10($78) + emit_tag_10(tag) +end +def emit_saw_10(tag) + emit_op_10($7A) + emit_tag_10(tag) +end +def emit_dab_10(tag) + emit_op_10($7C) + emit_tag_10(tag) +end +def emit_daw_10(tag) + emit_op_10($7E) + emit_tag_10(tag) +end +def emit_call_10(tag) + emit_op_10($54) + emit_tag_10(tag) +end +def emit_ical + emit_op_10($56) +end +def emit_push + emit_op_10($34) +end +def emit_pull + ; + ; Skip if last op was push + ; + if lastop == $34 + codeptr = codeptr - 1 + lastop = $FF + else + emit_op_10($36) + fin +end +def emit_localaddr_10(index) + emit_op_10($28) + emit_byte_10(index) +end +def emit_globaladdr_10(tag) + emit_op_10($26) + emit_tag_10(tag) +end +def emit_indexbyte + emit_op_10($02) +end +def emit_indexword + emit_op_10($1E) +end +defopt emit_unaryop_11(op) + when op + is NEG_TKN + emit_op_10($10) + is COMP_TKN + emit_op_10($12) + is LOGIC_NOT_TKN + emit_op_10($20) + is INC_TKN + emit_op_10($0C) + is DEC_TKN + emit_op_10($0E) + is BPTR_TKN + emit_op_10($60) + is WPTR_TKN + emit_op_10($62) + otherwise + return FALSE + wend + return TRUE +end +defopt emit_binaryop_11(op) + when op + is MUL_TKN + ; + ; Replace MUL 2 with SHL 1 + ; + if lastop == $2A and ^(codeptr - 1) == 2 ; CB 2 + codeptr = codeptr - 1 + emit_byte_10(1) ; CB 1 + emit_op_10($1A) ; SHL + else + emit_op_10($06) + fin + is DIV_TKN + ; + ; Replace DIV 2 with SHR 1 + ; + if lastop == $2A and ^(codeptr - 1) == 2 ; CB 2 + codeptr = codeptr - 1 + emit_byte_10(1) ; CB 1 + emit_op_10($1C) ; SHR + else + emit_op_10($08) + fin + is MOD_TKN + emit_op_10($0A) + is ADD_TKN + ; + ; Replace ADD 1 with INCR + ; + if lastop == $2A and ^(codeptr - 1) == 1 ; CB 1 + codeptr = codeptr - 2 + emit_op_10($0C) ; INC_OP + else + emit_op_10($02) + fin + is SUB_TKN + ; + ; Replace SUB 1 with DECR + ; + if lastop == $2A and ^(codeptr - 1) == 1 ; CB 1 + codeptr = codeptr - 2 + emit_op_10($0E) ; DEC_OP + else + emit_op_10($04) + fin + is SHL_TKN + emit_op_10($1A) + is SHR_TKN + emit_op_10($1C) + is AND_TKN + emit_op_10($14) + is OR_TKN + emit_op_10($16) + is EOR_TKN + emit_op_10($18) + is EQ_TKN + emit_op_10($40) + is NE_TKN + emit_op_10($42) + is GE_TKN + emit_op_10($48) + is LT_TKN + emit_op_10($46) + is GT_TKN + emit_op_10($44) + is LE_TKN + emit_op_10($4A) + is LOGIC_OR_TKN + emit_op_10($22) + is LOGIC_AND_TKN + emit_op_10($24) + is COMMA_TKN + ; Do nothing except move to next stanza in expression + otherwise + return FALSE + wend + return TRUE +end +def emit_brtru_10(tag) + emit_op_10($4E) + emit_tag_10(tag) +end +def emit_brfls_10(tag) + emit_op_10($4C) + emit_tag_10(tag) +end +def emit_brgt_10(tag) + emit_op_10($3A) + emit_tag_10(tag) +end +def emit_brlt_10(tag) + emit_op_10($38) + emit_tag_10(tag) +end +def emit_brne_10(tag) + emit_op_10($3E) + emit_tag_10(tag) +end +def emit_jump_10(tag) + emit_op_10($50) + emit_tag_10(tag) +end +def emit_drop + emit_op_10($30) +end +def emit_swap + emit_op_10($2E) +end +def emit_leave_10(framesize) + if framesize > 2 + emit_op_10($5A) + else + emit_op_10($5C) + fin +end +def emit_enter_20(framesize, cparams) + emit_byte_10($20) + emit_byte_10($D0) + emit_byte_10($03) + if framesize > 2 + emit_op_10($58) + emit_byte_10(framesize) + emit_byte_10(cparams) + fin +end +def emit_start + ; + ; Save address + ; + entrypoint = codeptr + emit_byte_10(emit_start.[0]) + emit_byte_10(emit_start.[1]) + emit_byte_10(emit_start.[2]) +end +def emit_exit + emit_op_10($00) + emit_op_10($5C) +end +; +; Lexical anaylzer +; +;def isalpha_11(c) +; if c >= 'A' and c <= 'Z' +; return TRUE +; elsif c >= 'a' and c <= 'z' +; return TRUE +; elsif c == '_' +; return TRUE +; fin +; return FALSE +;end +asm isalpha_11 + LDY #$00 + LDA ESTKL,X + CMP #'A' + BCC ISALRET + CMP #'Z'+1 + BCS :+ + DEY + BNE ISALRET +: CMP #'a' + BCC ISALRET + CMP #'z'+1 + BCS :+ + DEY + BNE ISALRET +: CMP #'_' + BNE ISALRET + DEY +ISALRET: + STY ESTKL,X + STY ESTKH,X + RTS +end +;def isnum_11(c) +; if c >= '0' and c <= '9' +; return TRUE +; fin +; return FALSE +;end +asm isnum_11 + LDY #$00 + LDA ESTKL,X + CMP #'0' + BCC :+ + CMP #'9'+1 + BCS :+ + DEY +: STY ESTKL,X + STY ESTKH,X + RTS +end +;def isalphanum_11(c) +; if c >= 'A' and c <= 'Z' +; return TRUE +; elsif c >= '0' and c <= '9' +; return TRUE +; elsif c >= 'a' and c <= 'z' +; return TRUE +; elsif c == '_' +; return TRUE +; fin +; return FALSE +;end +asm isalphanum_11 + LDY #$00 + LDA ESTKL,X + CMP #'0' + BCC ISANRET + CMP #'9'+1 + BCS :+ + DEY + BNE ISANRET +: CMP #'A' + BCC ISANRET + CMP #'Z'+1 + BCS :+ + DEY + BNE ISANRET +: CMP #'a' + BCC :+ + CMP #'z'+1 + BCS ISANRET + DEY + BNE ISANRET +: CMP #'_' + BNE ISANRET + DEY +ISANRET: + STY ESTKL,X + STY ESTKH,X + RTS +end +defopt keymatch_21(chrptr, len) + byte i, keypos + + keypos = 0 + while keywrds[keypos] < len + keypos = keypos + keywrds[keypos] + 2 + loop + while keywrds[keypos] == len + for i = 1 to len + if toupper_11((chrptr).[i - 1]) <> keywrds[keypos + i] + break + fin + next + if i > len + return keywrds[keypos + keywrds[keypos] + 1] + fin + keypos = keypos + keywrds[keypos] + 2 + loop + return ID_TKN +end +defopt skipspace_01 + ; + ; Skip whitespace + ; + while ^scanptr and ^scanptr <= ' ' + scanptr = scanptr + 1 + loop + tknptr = scanptr + return !^scanptr or ^scanptr == ';' +end +def scan_01 + ; + ; Scan for token based on first character + ; + if skipspace_01() + if token <> EOF_TKN + token = EOL_TKN + fin + elsif isalpha_11(^scanptr) + ; + ; ID, either variable name or reserved word + ; + repeat + scanptr = scanptr + 1 + until !isalphanum_11(^scanptr) + tknlen = scanptr - tknptr; + token = keymatch_21(tknptr, tknlen) + elsif isnum_11(^scanptr) + ; + ; Number constant + ; + token = INT_TKN + constval = 0 + repeat + constval = constval * 10 + ^scanptr - '0' + scanptr = scanptr + 1 + until !isnum_11(^scanptr) + elsif ^scanptr == '$' + ; + ; Hexadecimal constant + ; + token = INT_TKN; + constval = 0 + repeat + scanptr = scanptr + 1 + if ^scanptr >= '0' and ^scanptr <= '9' + constval = (constval << 4) + ^scanptr - '0' + elsif ^scanptr >= 'A' and ^scanptr <= 'F' + constval = (constval << 4) + ^scanptr - '7'; 'A'-10 + elsif ^scanptr >= 'a' and ^scanptr <= 'f' + constval = (constval << 4) + ^scanptr - 'W'; 'a'-10 + else + break; + fin + until !^scanptr + elsif ^scanptr == $27 ; ' + ; + ; Character constant + ; + token = CHR_TKN + if ^(scanptr + 1) <> $5C ; \ + constval = ^(scanptr + 1) + if ^(scanptr + 2) <> $27 ; ' + return parse_err_11(@bad_cnst) + fin + scanptr = scanptr + 3 + else + when ^(scanptr + 2) + is 'n' + constval = $0D + is 'r' + constval = $0A + is 't' + constval = $09 + otherwise + constval = ^(scanptr + 2) + wend + if ^(scanptr + 3) <> $27 ; ' + return parse_err_11(@bad_cnst) + fin + scanptr = scanptr + 4 + fin + elsif ^scanptr == '"' + ; + ; String constant + ; + token = STR_TKN + scanptr = scanptr + 1 + constval = scanptr + while ^scanptr and ^scanptr <> '"' + scanptr = scanptr + 1 + loop + if !^scanptr + return parse_err_11(@bad_cnst) + fin + scanptr = scanptr + 1 + else + ; + ; Potential two and three character tokens + ; + when ^scanptr + is '>' + if ^(scanptr + 1) == '>' + token = SHR_TKN + scanptr = scanptr + 2 + elsif ^(scanptr + 1) == '=' + token = GE_TKN + scanptr = scanptr + 2 + else + token = GT_TKN + scanptr = scanptr + 1 + fin + is '<' + if ^(scanptr + 1) == '<' + token = SHL_TKN + scanptr = scanptr + 2 + elsif ^(scanptr + 1) == '=' + token = LE_TKN + scanptr = scanptr + 2 + elsif ^(scanptr + 1) == '>' + token = NE_TKN + scanptr = scanptr + 2 + else + token = LT_TKN + scanptr = scanptr + 1 + fin + is '=' + if ^(scanptr + 1) == '=' + token = EQ_TKN + scanptr = scanptr + 2; + elsif ^(scanptr + 1) == ',' + token = SETLIST_TKN + scanptr = scanptr + 2; + else + token = SET_TKN; + scanptr = scanptr + 1 + fin + otherwise + ; + ; Simple single character tokens + ; + token = ^scanptr ? $80 + scanptr = scanptr + 1 + wend + fin + tknlen = scanptr - tknptr + return token +end +def rewind_10(ptr) + scanptr = ptr +end +; +; Get next line of input +; +defopt nextln_01 +; if ^keyboard == $A0 +; ^keystrobe +; while ^keyboard < 128 +; loop +; ^keystrobe +; elsif ^keyboard == $82 +; lineno = numlines +; ^keystrobe +; fin + scanptr = inbuff + if lineno < numlines + cpyln_20(strlinbuf:[lineno], instr) + lineno = lineno + 1 + if !(lineno & $0F) + cout('.') + fin + ; cout('>') + ; prstr(instr) + ; crout() + drop scan_01() + else + ^instr = 0 + ^inbuff = $00 + token = DONE_TKN + fin + return ^instr +end +; +; Alebraic op to stack op +; +def push_op_21(op, prec) + opsp = opsp + 1 + if opsp == 16 + return parse_err_11(@estk_overflw) + fin + opstack[opsp] = op + precstack[opsp] = prec + return 0 +end +def pop_op_01 + if opsp < 0 + return parse_err_11(@estk_underflw) + fin + opsp = opsp - 1 + return opstack[opsp + 1] +end +def tos_op_01 + if opsp < 0 + return 0 + fin + return opstack[opsp] +end +def tos_op_prec_11(tos) + if opsp <= tos + return 100 + fin + return precstack[opsp] +end +; +; Symbol table +; +defopt idmatch_41(nameptr, len, idptr, idcnt) + byte i + + while idcnt + if len == (idptr).idname + for i = 1 to len + if (nameptr).[i - 1] <> (idptr).idname.[i] + break + fin + next + if i > len + return idptr + fin + fin + idptr = idptr + (idptr).idname + idrecsz + idcnt = idcnt - 1 + loop + return 0 +end +;def dumpsym_20(idptr, idcnt) +; while idcnt +; prword_10((idptr):idval) +; cout(' ') +; prbyte_10((idptr).idtype) +; cout(' ') +; prstr(@(idptr).idname) +; cout('=') +; if (idptr).idtype & ADDR_TYPE +; if (idptr):idval & is_ctag +; prword_10(ctag_value:[(idptr):idval & mask_ctag]) +; else +; prword_10((idptr):idval + codebuff) +; fin +; else +; prword_10((idptr):idval) +; fin +; crout() +; idptr = idptr + (idptr).idname + idrecsz +; idcnt = idcnt - 1 +; loop +;end +def id_lookup_21(nameptr, len) + word idptr + + idptr = idmatch_41(nameptr, len, idlocal_tbl, locals) + if idptr + return idptr + fin + idptr = idmatch_41(nameptr, len, idglobal_tbl, globals) + if idptr + return idptr + fin + return parse_err_11(@undecl_id) +end +def idglobal_lookup_21(nameptr, len) + return idmatch_41(nameptr, len, idglobal_tbl, globals) +end +def idlocal_add_41(namestr, len, type, size) + if idmatch_41(namestr, len, @idlocal_tbl, locals) + return parse_err_11(@dup_id) + fin + (lastlocal):idval = framesize + (lastlocal).idtype = type ? LOCAL_TYPE + nametostr_30(namestr, len, lastlocal + idname) + locals = locals + 1 + lastlocal = lastlocal + idrecsz + len + if lastlocal > idlocal_tbl + idlocal_tblsz + prstr(@local_sym_overflw) + exit + fin + framesize = framesize + size + if framesize > 255 + prstr(@local_overflw) + return FALSE + fin + return TRUE +end +def iddata_add_41(namestr, len, type, size) + if idmatch_41(namestr, len, idglobal_tbl, globals) + return parse_err_11(@dup_id) + fin + (lastglobal):idval = datasize + (lastglobal).idtype = type + nametostr_30(namestr, len, lastglobal + idname) + emit_iddata_30(datasize, size, lastglobal + idname) + globals = globals + 1 + lastglobal = lastglobal + idrecsz + len + if lastglobal > idglobal_tbl + idglobal_tblsz + prstr(@global_sym_overflw) + exit + fin + datasize = datasize + size + return TRUE +end +def iddata_size_30(type, varsize, initsize) + if varsize > initsize + datasize = datasize + emit_data_41(0, 0, 0, varsize - initsize) + else + datasize = datasize + initsize + fin +; if datasize <> codeptr - codebuff +; prstr(@emiterr) +; keyin_01() +; fin +end +def idglobal_add_41(namestr, len, type, value) + if idmatch_41(namestr, len, idglobal_tbl, globals) + return parse_err_11(@dup_id) + fin + (lastglobal):idval = value + (lastglobal).idtype = type + nametostr_30(namestr, len, lastglobal + idname) + globals = globals + 1 + lastglobal = lastglobal + idrecsz + len + if lastglobal > idglobal_tbl + idglobal_tblsz + prstr(@global_sym_overflw) + exit + fin + return TRUE +end +def idfunc_add_31(namestr, len, tag) + return idglobal_add_41(namestr, len, FUNC_TYPE, tag) +end +def idconst_add_31(namestr, len, value) + return idglobal_add_41(namestr, len, CONST_TYPE, value) +end +def idglobal_init + word ctag + + lineno = 0 + parserr = 0 + codeptr = codebuff + lastop = $FF + entrypoint = 0 + datasize = 0 + globals = 0 + lastglobal = idglobal_tbl + codetag = -1 + ctag = ctag_new_01() + drop idfunc_add_31(@runtime0 + 1, runtime0, ctag) + drop idfunc_add_31(@RUNTIME0 + 1, RUNTIME0, ctag) + drop ctag_resolve_21(ctag, @romcall) + ctag = ctag_new_01() + drop idfunc_add_31(@runtime1 + 1, runtime1, ctag) + drop idfunc_add_31(@RUNTIME1 + 1, RUNTIME1, ctag) + drop ctag_resolve_21(ctag, @syscall) + ctag = ctag_new_01() + drop idfunc_add_31(@runtime2 + 1, runtime2, ctag) + drop idfunc_add_31(@RUNTIME2 + 1, RUNTIME2, ctag) + drop ctag_resolve_21(ctag, @memset) + ctag = ctag_new_01() + drop idfunc_add_31(@runtime3 + 1, runtime3, ctag) + drop idfunc_add_31(@RUNTIME3 + 1, RUNTIME3, ctag) + drop ctag_resolve_21(ctag, @memcpy) + ctag = ctag_new_01() + drop idfunc_add_31(@runtime4 + 1, runtime4, ctag) + drop idfunc_add_31(@RUNTIME4 + 1, RUNTIME4, ctag) + drop ctag_resolve_21(ctag, @cout) + ctag = ctag_new_01() + drop idfunc_add_31(@runtime5 + 1, runtime5, ctag) + drop idfunc_add_31(@RUNTIME5 + 1, RUNTIME5, ctag) + drop ctag_resolve_21(ctag, @cin) + ctag = ctag_new_01() + drop idfunc_add_31(@runtime6 + 1, runtime6, ctag) + drop idfunc_add_31(@RUNTIME6 + 1, RUNTIME6, ctag) + drop ctag_resolve_21(ctag, @prstr) + ctag = ctag_new_01() + drop idfunc_add_31(@runtime7 + 1, runtime7, ctag) + drop idfunc_add_31(@RUNTIME7 + 1, RUNTIME7, ctag) + drop ctag_resolve_21(ctag, @rdstr) +end +def idlocal_init + locals = 0 + framesize = 2 + lastlocal = idlocal_tbl +end +; +; Parser +; +def parse_term_01 + when scan_01() + is ID_TKN + return TRUE + is INT_TKN + return TRUE + is CHR_TKN + return TRUE + is STR_TKN + return TRUE + is OPEN_PAREN_TKN + if !parse_expr_01() + return FALSE + fin + if token <> CLOSE_PAREN_TKN + return parse_err_11(@no_close_paren) + fin + return TRUE + wend + return FALSE +end +def parse_constval_21(valptr, sizeptr) + byte mod, type + word idptr + + mod = 0 + type = 0 + *valptr = 0 + while !parse_term_01() + when token + is SUB_TKN + mod = mod ? 1 + is COMP_TKN + mod = mod ? 2 + is LOGIC_NOT_TKN + mod = mod ? 4 + is AT_TKN + mod = mod ? 8 + otherwise + return 0 + wend + loop + when token + is STR_TKN + *valptr = constval + ^sizeptr = tknlen - 1 + type = STR_TYPE + if mod + return parse_err_11(@bad_op) + fin + is CHR_TKN + *valptr = constval + ^sizeptr = 1 + type = BYTE_TYPE + is INT_TKN + *valptr = constval + ^sizeptr = 2 + type = WORD_TYPE + is ID_TKN + ^sizeptr = 2 + idptr = id_lookup_21(tknptr, tknlen) + if !idptr + return parse_err_11(@bad_cnst) + fin + type = (idptr).idtype + *valptr = (idptr):idval + if type & VAR_TYPE and !(mod & 8) + return parse_err_11(@bad_cnst) + fin + otherwise + return parse_err_11(@bad_cnst) + wend + if mod & 1 + *valptr = -*valptr + fin + if mod & 2 + *valptr = #*valptr + fin + if mod & 4 + *valptr = !*valptr + fin + return type +end +def ispostop_01 + when token + is OPEN_PAREN_TKN + return TRUE + is OPEN_BRACKET_TKN + return TRUE + is DOT_TKN + return TRUE + is COLON_TKN + return TRUE + wend + return FALSE +end +def parse_value_11(rvalue) + byte cparams, deref, type, emit_val + word optos, idptr, value + byte elem_type, elem_size + word elem_offset + + deref = rvalue + optos = opsp + type = 0 + emit_val = 0 + value = 0 + + ; + ; Parse pre-ops + ; + while !parse_term_01() + when token + is ADD_TKN + is BPTR_TKN + if deref + drop push_op_21(token, 0) + else + type = type ? BPTR_TYPE + deref = deref + 1 + fin + is WPTR_TKN + if deref + drop push_op_21(token, 0) + else + type = type ? WPTR_TYPE + deref = deref + 1 + fin + is AT_TKN + deref = deref - 1 + is SUB_TKN + drop push_op_21(token, 0) + is COMP_TKN + drop push_op_21(token, 0) + is LOGIC_NOT_TKN + drop push_op_21(token, 0) + otherwise + return 0 + wend + loop + ; + ; Determine terminal type + ; + when token + is INT_TKN + type = type ? CONST_TYPE + value = constval + is CHR_TKN + type = type ? CONST_TYPE + value = constval + is ID_TKN + idptr = id_lookup_21(tknptr, tknlen) + if !idptr + return 0 + fin + if !(idptr).idtype + return 0 + fin + type = type ? (idptr).idtype + value = (idptr):idval + is CLOSE_PAREN_TKN + type = type ? WORD_TYPE + emit_val = 1 + otherwise + return 0 + wend + ; + ; Constant optimizations + ; + if type & CONST_TYPE + cparams = TRUE + while optos < opsp and cparams + when tos_op_01() + is NEG_TKN + drop pop_op_01() + value = -value + is COMP_TKN + drop pop_op_01() + value = #value + is LOGIC_NOT_TKN + drop pop_op_01() + value = !value + otherwise + cparams = FALSE + wend + loop + fin + ; + ; Parse post-ops + ; + drop scan_01() + while ispostop_01() + if token == OPEN_BRACKET_TKN + ; + ; Array + ; + if !emit_val + if type & ADDR_TYPE + if type & LOCAL_TYPE + emit_localaddr_10(value) + else + emit_globaladdr_10(value) + fin + elsif type & CONST_TYPE + emit_const_10(value) + fin + emit_val = 1 + fin ; !emit_val + if type & PTR_TYPE + emit_lw() + fin + if !parse_expr_01() + return 0 + fin + if token <> CLOSE_BRACKET_TKN + return parse_err_11(@no_close_bracket) + fin + if type & WORD_TYPE + type = WPTR_TYPE + emit_indexword() + else + type = BPTR_TYPE + emit_indexbyte() + fin + drop scan_01() + elsif token == DOT_TKN or token == COLON_TKN + ; + ; Dot and Colon + ; + if token == DOT_TKN + elem_type = BPTR_TYPE + else + elem_type = WPTR_TYPE + fin + if parse_constval_21(@elem_offset, @elem_size) + ; + ; Constant structure offset + ; + if !emit_val + if type & VAR_TYPE + if type & LOCAL_TYPE + emit_localaddr_10(value + elem_offset) + else + ; emit_globaladdr_10(value + elem_offset) + emit_globaladdr_10(value) + emit_const_10(elem_offset) + drop emit_binaryop_11(ADD_TKN) + fin + elsif type & CONST_TYPE + value = value + elem_offset + emit_const_10(value) + else ; FUNC_TYPE + emit_globaladdr_10(value) + emit_const_10(elem_offset) + drop emit_binaryop_11(ADD_TKN) + fin + emit_val = 1 + else + if elem_offset <> 0 + emit_const_10(elem_offset) + drop emit_binaryop_11(ADD_TKN) + fin + fin ; !emit_val + drop scan_01() + elsif token == OPEN_BRACKET_TKN + ; + ; Array of arrays + ; + if !emit_val + if type & ADDR_TYPE + if type & LOCAL_TYPE + emit_localaddr_10(value) + else + emit_globaladdr_10(value) + fin + elsif type & CONST_TYPE + emit_const_10(value) + fin + emit_val = 1 + fin ; !emit_val + repeat + if emit_val > 1 + emit_indexword() + emit_lw() + fin + emit_val = emit_val + 1 + if !parse_expr_01() + return parse_err_11(@bad_expr) + fin + if token <> CLOSE_BRACKET_TKN + return parse_err_11(@no_close_bracket) + fin + until scan_01() <> OPEN_BRACKET_TKN + if elem_type & WPTR_TYPE + emit_indexword() + else + emit_indexbyte() + fin + else + return parse_err_11(@bad_offset) + fin + type = elem_type + elsif token == OPEN_PAREN_TKN + ; + ; Function call + ; + if !emit_val and type & VAR_TYPE + if type & LOCAL_TYPE + emit_localaddr_10(value) + else + emit_globaladdr_10(value) + fin + fin + if !(type & FUNC_CONST_TYPE) + emit_push() + fin + drop parse_expr_01() + if token <> CLOSE_PAREN_TKN + return parse_err_11(@no_close_paren) + fin + if type & FUNC_CONST_TYPE + emit_call_10(value) + else + emit_pull() + emit_ical() + fin + emit_val = 1 + type = WORD_TYPE + drop scan_01() + fin + loop + if emit_val + if rvalue + if deref and type & PTR_TYPE + if type & BPTR_TYPE + emit_lb() + else + emit_lw() + fin + fin + fin + else ; emit_val + if type & CONST_TYPE + emit_const_10(value) + elsif deref + if type & FUNC_TYPE + emit_call_10(value) + elsif type & VAR_TYPE + if type & LOCAL_TYPE + if type & BYTE_TYPE + emit_llb_10(value) + else + emit_llw_10(value) + fin + else + if type & BYTE_TYPE + emit_lab_10(value) + else + emit_law_10(value) + fin + fin + elsif type & PTR_TYPE + if type & BPTR_TYPE + emit_lb() + else + emit_lw() + fin + fin + else + if type & LOCAL_TYPE + emit_localaddr_10(value) + else + emit_globaladdr_10(value) + fin + fin + fin ; emit_val + while optos < opsp + if !emit_unaryop_11(pop_op_01()) + return parse_err_11(@bad_op) + fin + loop + return type +end +def parse_constexpr_21(valptr, sizeptr) + byte type, size1, size2 + word val1, val2 + + type = parse_constval_21(@val1, @size1) + if !type + return 0 + fin + size2 = 0 + when scan_01() + is ADD_TKN + type = parse_constval_21(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 + val2 + is SUB_TKN + type = parse_constval_21(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 - val2 + is MUL_TKN + type = parse_constval_21(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 * val2 + is DIV_TKN + type = parse_constval_21(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 + val2 + is MOD_TKN + type = parse_constval_21(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 % val2 + drop + is AND_TKN + type = parse_constval_21(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 & val2 + is OR_TKN + type = parse_constval_21(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 ? val2 + is EOR_TKN + type = parse_constval_21(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 ^ val2 + otherwise + *valptr = val1 + wend + if size1 > size2 + ^sizeptr = size1 + else + ^sizeptr = size2 + fin + return type +end +def parse_expr_01 + byte prevmatch, matchop, i + word optos + + matchop = 0 + optos = opsp + repeat + prevmatch = matchop + matchop = 0 + if parse_value_11(1) + matchop = 1 + for i = 0 to bops_tblsz + if token == bops_tbl[i] + matchop = 2 + if bops_prec[i] >= tos_op_prec_11(optos) + if !emit_binaryop_11(pop_op_01()) + return parse_err_11(@bad_op) + fin + fin + drop push_op_21(token, bops_prec[i]) + break + fin + next + fin + until matchop <> 2 + if matchop == 0 and prevmatch == 2 + return parse_err_11(@missing_op) + fin + while optos < opsp + if !emit_binaryop_11(pop_op_01()) + return parse_err_11(@bad_op) + fin + loop + return matchop or prevmatch +end +def parse_setlist_21(addr, type) + word nexttype, nextaddr, idptr, saveptr + + if !(type & VAR_TYPE) + emit_push() + fin + nexttype = 0 + nextaddr = 0 + if scan_01() == ID_TKN + idptr = id_lookup_21(tknptr, tknlen) + if !idptr + return FALSE + fin + nexttype = (idptr).idtype + if type & VAR_TYPE + nextaddr = (idptr):idval + fin + fin + saveptr = tknptr + drop scan_01() + if nexttype & VAR_TYPE and token == SET_TKN + drop parse_expr_01() + if type & LOCAL_TYPE + if type & BYTE_TYPE + emit_slb_10(nextaddr) + else + emit_slw_10(nextaddr) + fin + else + if type & BYTE_TYPE + emit_sab_10(nextaddr) + else + emit_saw_10(nextaddr) + fin + fin + elsif nexttype & VAR_TYPE and token == SETLIST_TKN + if !parse_setlist_21(nextaddr, nexttype) + return FALSE + fin + else + tknptr = saveptr + rewind_10(tknptr) + nexttype = parse_value_11(0) + if nexttype <> 0 + if token == SET_TKN + emit_push() + drop parse_expr_01() + emit_pull() + emit_swap() + if nexttype & (BYTE_TYPE ? BPTR_TYPE) + emit_sb() + else + emit_sw() + fin + fin + elsif token == SETLIST_TKN + if !parse_setlist_21(0, nexttype) + return FALSE + fin + else + return parse_err_11(@bad_syntax) + fin + fin + if type & VAR_TYPE + if type & LOCAL_TYPE + if type & BYTE_TYPE + emit_slb_10(addr) + else + emit_slw_10(addr) + fin + else + if type & BYTE_TYPE + emit_sab_10(addr) + else + emit_saw_10(addr) + fin + fin + else + emit_pull() + emit_swap() + if type & (BYTE_TYPE ? BPTR_TYPE) + emit_sb() + else + emit_sw() + fin + fin + return TRUE +end +def parse_stmnt_01 + byte type, i + word tag_prevbrk, tag_else, tag_endif, tag_while, tag_wend + word tag_repeat, tag_for, tag_choice, idptr, saveptr, addr, stepdir + + if token <> END_TKN and token <> DONE_TKN + prevstmnt = token + fin + when token + is IF_TKN + drop parse_expr_01() + tag_else = ctag_new_01() + tag_endif = ctag_new_01() + emit_brfls_10(tag_else) + drop scan_01() + repeat + while parse_stmnt_01() + drop nextln_01() + loop + if token <> ELSEIF_TKN + break + fin + emit_jump_10(tag_endif) + emit_codetag_10(tag_else) + if !parse_expr_01() + return 0 + fin + tag_else = ctag_new_01() + emit_brfls_10(tag_else) + until FALSE + if token == ELSE_TKN + emit_jump_10(tag_endif) + emit_codetag_10(tag_else) + drop scan_01() + while parse_stmnt_01() + drop nextln_01() + loop + emit_codetag_10(tag_endif) + else + emit_codetag_10(tag_else) + emit_codetag_10(tag_endif) + fin + if token <> FIN_TKN + return parse_err_11(@no_fin) + fin + is FOR_TKN + stack_loop = stack_loop + 1 + tag_for = ctag_new_01() + tag_prevbrk = break_tag + break_tag = ctag_new_01() + if scan_01() <> ID_TKN + return parse_err_11(@bad_stmnt) + fin + idptr = id_lookup_21(tknptr, tknlen) + if idptr + type = (idptr).idtype + addr = (idptr):idval + else + return FALSE + fin + if scan_01() <> SET_TKN + return parse_err_11(@bad_stmnt) + fin + if !parse_expr_01() + return parse_err_11(@bad_stmnt) + fin + emit_codetag_10(tag_for) + if type & LOCAL_TYPE + if type & BYTE_TYPE + emit_dlb_10(addr) + else + emit_dlw_10(addr) + fin + else + if type & BYTE_TYPE + emit_dab_10(addr) + else + emit_daw_10(addr) + fin + fin + stepdir = 1 + if token == TO_TKN + drop parse_expr_01() + elsif token == DOWNTO_TKN + drop parse_expr_01() + stepdir = -1 + fin + if stepdir > 0 + emit_brgt_10(break_tag) + else + emit_brlt_10(break_tag) + fin + if token == STEP_TKN + drop parse_expr_01() + if stepdir > 0 + drop emit_binaryop_11(ADD_TKN) + else + drop emit_binaryop_11(SUB_TKN) + fin + else + if stepdir > 0 + drop emit_unaryop_11(INC_TKN) + else + drop emit_unaryop_11(DEC_TKN) + fin + fin + while parse_stmnt_01() + drop nextln_01() + loop + if token <> NEXT_TKN + return parse_err_11(@bad_stmnt) + fin + emit_jump_10(tag_for) + emit_codetag_10(break_tag) + emit_drop() + break_tag = tag_prevbrk + stack_loop = stack_loop - 1 + is WHILE_TKN + tag_while = ctag_new_01() + tag_wend = ctag_new_01() + tag_prevbrk = break_tag + break_tag = tag_wend + emit_codetag_10(tag_while) + drop parse_expr_01() + emit_brfls_10(tag_wend) + while parse_stmnt_01() + drop nextln_01() + loop + if token <> LOOP_TKN + return parse_err_11(@no_loop) + fin + emit_jump_10(tag_while) + emit_codetag_10(tag_wend) + break_tag = tag_prevbrk + is REPEAT_TKN + tag_repeat = ctag_new_01() + tag_prevbrk = break_tag + break_tag = ctag_new_01() + emit_codetag_10(tag_repeat) + drop scan_01() + while parse_stmnt_01() + drop nextln_01() + loop + if token <> UNTIL_TKN + return parse_err_11(@no_until) + fin + drop parse_expr_01() + emit_brfls_10(tag_repeat) + emit_codetag_10(break_tag) + break_tag = tag_prevbrk + is CASE_TKN + stack_loop = stack_loop + 1 + tag_choice = ctag_new_01() + tag_prevbrk = break_tag + break_tag = ctag_new_01() + drop parse_expr_01() + drop nextln_01() + while token <> ENDCASE_TKN + when token + is OF_TKN + if !parse_expr_01() + return parse_err_11(@bad_stmnt) + fin + emit_brne_10(tag_choice) + while parse_stmnt_01() + drop nextln_01() + loop + emit_jump_10(break_tag) + emit_codetag_10(tag_choice) + tag_choice = ctag_new_01() + is DEFAULT_TKN + drop scan_01() + while parse_stmnt_01() + drop nextln_01() + loop + if token <> ENDCASE_TKN + return parse_err_11(@bad_stmnt) + fin + otherwise + return parse_err_11(@bad_stmnt) + wend + loop + emit_codetag_10(break_tag) + emit_drop() + break_tag = tag_prevbrk + stack_loop = stack_loop - 1 + is BREAK_TKN + if break_tag + emit_jump_10(break_tag) + else + return parse_err_11(@bad_stmnt) + fin + is RETURN_TKN + if infunc + for i = 1 to stack_loop + emit_drop() + next + drop parse_expr_01() + emit_leave_10(framesize) + else + return parse_err_11(@bad_stmnt) + fin + is EXIT_TKN + drop parse_expr_01() + emit_exit() + is DROP_TKN + drop parse_expr_01() + emit_drop() + is ELSE_TKN + return FALSE + is ELSEIF_TKN + return FALSE + is FIN_TKN + return FALSE + is LOOP_TKN + return FALSE + is UNTIL_TKN + return FALSE + is NEXT_TKN + return FALSE + is OF_TKN + return FALSE + is DEFAULT_TKN + return FALSE + is ENDCASE_TKN + return FALSE + is END_TKN + return FALSE + is DONE_TKN + return FALSE + is IFUNC_TKN + return FALSE + is NFUNC_TKN + return FALSE + is EOF_TKN + return FALSE + is EOL_TKN + return TRUE + otherwise + if token == ID_TKN + saveptr = tknptr + idptr = id_lookup_21(tknptr, tknlen) + if !idptr + return FALSE + fin + type = (idptr).idtype + if type & ADDR_TYPE + addr = (idptr):idval + if scan_01() == SET_TKN + if type & VAR_TYPE + drop parse_expr_01() + if type & LOCAL_TYPE + if type & BYTE_TYPE + emit_slb_10(addr) + else + emit_slw_10(addr) + fin + else + if type & BYTE_TYPE + emit_sab_10(addr) + else + emit_saw_10(addr) + fin + fin + return TRUE + fin + elsif token == SETLIST_TKN and type & VAR_TYPE + return parse_setlist_21(addr, type); + elsif token == EOL_TKN and type & FUNC_TYPE + emit_call_10(addr) + return TRUE + fin + fin + tknptr = saveptr + fin + rewind_10(tknptr) + type = parse_value_11(0) + if type + if token == SET_TKN + drop parse_expr_01() + if type & XBYTE_TYPE + emit_sb() + else + emit_sw() + fin + elsif token == SETLIST_TKN + return parse_setlist_21(0, type); + else + if type & BPTR_TYPE + emit_lb() + elsif type & WPTR_TYPE + emit_lw() + fin + fin + else + return parse_err_11(@bad_syntax) + fin + wend + if scan_01() <> EOL_TKN + return parse_err_11(@bad_syntax) + fin + return TRUE +end +def parse_var_11(type) + byte consttype, constsize, idlen + word idptr, constval, arraysize, size + + idlen = 0 + size = 1 + if scan_01() == ID_TKN + idptr = tknptr + idlen = tknlen + if scan_01() == OPEN_BRACKET_TKN + size = 0 + drop parse_constexpr_21(@size, @constsize) + if token <> CLOSE_BRACKET_TKN + return parse_err_11(@no_close_bracket) + fin + drop scan_01() + fin + fin + if type == WORD_TYPE + size = size * 2 + fin + if token == SET_TKN + if infunc + return parse_err_11(@no_local_init) + fin + if idlen + drop iddata_add_41(idptr, idlen, type, 0) + fin + consttype = parse_constexpr_21(@constval, @constsize) + if consttype + arraysize = emit_data_41(type, consttype, constval, constsize) + while token == COMMA_TKN + consttype = parse_constexpr_21(@constval, @constsize) + if consttype + arraysize = arraysize + emit_data_41(type, consttype, constval, constsize) + else + return parse_err_11(@bad_decl) + fin + loop + if token <> EOL_TKN + return parse_err_11(@no_close_bracket) + fin + iddata_size_30(PTR_TYPE, size, arraysize); + else + return parse_err_11(@bad_decl) + fin + elsif idlen + if infunc + drop idlocal_add_41(idptr, idlen, type, size) + else + drop iddata_add_41(idptr, idlen, type, size) + fin + fin + return TRUE +end +def parse_vars_01 + byte idlen, type, size + word value, idptr + + when token + is CONST_TKN + if scan_01() <> ID_TKN + return parse_err_11(@bad_cnst) + fin + idptr = tknptr; + idlen = tknlen + if scan_01() <> SET_TKN + return parse_err_11(@bad_cnst) + fin + if !parse_constexpr_21(@value, @size) + return parse_err_11(@bad_cnst) + fin + drop idconst_add_31(idptr, idlen, value) + is BYTE_TKN + type = BYTE_TYPE + repeat + if !parse_var_11(type) + return FALSE + fin + until token <> COMMA_TKN + is WORD_TKN + type = WORD_TYPE + repeat + if !parse_var_11(type) + return FALSE + fin + until token <> COMMA_TKN + is FUNC_TKN + repeat + if scan_01() == ID_TKN + drop idfunc_add_31(tknptr, tknlen, ctag_new_01()) + else + return parse_err_11(@bad_decl) + fin + until scan_01() <> COMMA_TKN + is EOL_TKN + return TRUE + otherwise + return FALSE + wend + return TRUE +end +def parse_func_01 + byte opt, cfnparms + word func_tag, idptr + + if token == IFUNC_TKN or token == NFUNC_TKN + opt = token - IFUNC_TKN + if scan_01() <> ID_TKN + return parse_err_11(@bad_decl) + fin + cfnparms = 0 + infunc = TRUE + idptr = idglobal_lookup_21(tknptr, tknlen) + if idptr + func_tag = (idptr):idval + else + func_tag = ctag_new_01() + drop idfunc_add_31(tknptr, tknlen, func_tag) + fin + emit_codetag_10(func_tag) + retfunc_tag = ctag_new_01() + idlocal_init() + if scan_01() == OPEN_PAREN_TKN + repeat + if scan_01() == ID_TKN + cfnparms = cfnparms + 1 + drop idlocal_add_41(tknptr, tknlen, WORD_TYPE, 2) + drop scan_01() + fin + until token <> COMMA_TKN + if token <> CLOSE_PAREN_TKN + return parse_err_11(@bad_decl) + fin + drop scan_01() + fin + while parse_vars_01() + drop nextln_01() + loop + emit_enter_20(framesize, cfnparms) + prevstmnt = 0 + while parse_stmnt_01() + drop nextln_01() + loop + infunc = FALSE + if token <> END_TKN + return parse_err_11(@bad_syntax) + fin + if scan_01() <> EOL_TKN + return parse_err_11(@bad_syntax) + fin + if prevstmnt <> RETURN_TKN + emit_leave_10(framesize) + fin + return TRUE + elsif token == EOL_TKN + return TRUE + fin + return FALSE +end +def parse_module_01 + entrypoint = 0 + idglobal_init() + idlocal_init() + if nextln_01() + while parse_vars_01() + drop nextln_01() + loop + while parse_func_01() + drop nextln_01() + loop + if token <> DONE_TKN + emit_start() + prevstmnt = 0 + while parse_stmnt_01() + drop nextln_01() + loop + if token <> DONE_TKN + drop parse_err_11(@no_done) + fin + if prevstmnt <> EXIT_TKN + emit_const_10(0) + emit_exit() + fin + fin + ; dumpsym(idglobal_tbl, globals) + ; prstr(@entrypt_str) + ; prword(entrypoint) + ; crout() + ; keyin_01() + return TRUE + fin + return FALSE +end +; +; Init editor +; +if !(^machid & $80) + flags = uppercase ? shiftlock + keyin_01 = @keyin2_01 +else + keyin_01 = @keyin2e_01 +fin +inittxtbuf() +if ^argbuff + strcpy_20(argbuff, @txtfile) + prstr(@txtfile) + readtxt_10(@txtfile) +else + numlines = 1 +fin +curschr = '+' +flags = flags ? insmode +drawscrn_20(scrntop, scrnleft) +curson() +editmode() +done diff --git a/plasma2/plide.s b/plasma2/plide.s new file mode 100755 index 0000000..5c21018 --- /dev/null +++ b/plasma2/plide.s @@ -0,0 +1,14766 @@ + .INCLUDE "plstub.s" +; 1: ; +; 2: ; Global constants +; 3: ; +; 4: const FALSE = 0 + ; FALSE = 0 +; 5: const TRUE = !FALSE + ; TRUE = -1 +; 6: ; +; 7: ; Hardware constants +; 8: ; +; 9: const csw = $0036 + ; csw = 54 +; 10: const speaker = $C030 + ; speaker = 49200 +; 11: const showgraphics = $C050 + ; showgraphics = 49232 +; 12: const showtext = $C051 + ; showtext = 49233 +; 13: const showfull = $C052 + ; showfull = 49234 +; 14: const showmix = $C053 + ; showmix = 49235 +; 15: const showpage1 = $C054 + ; showpage1 = 49236 +; 16: const showpage2 = $C055 + ; showpage2 = 49237 +; 17: const showlores = $C056 + ; showlores = 49238 +; 18: const showhires = $C057 + ; showhires = 49239 +; 19: const pushbttn1 = $C061 + ; pushbttn1 = 49249 +; 20: const pushbttn2 = $C062 + ; pushbttn2 = 49250 +; 21: const pushbttn3 = $C063 + ; pushbttn3 = 49251 +; 22: const keyboard = $C000 + ; keyboard = 49152 +; 23: const keystrobe = $C010 + ; keystrobe = 49168 +; 24: const keyenter = $8D + ; keyenter = 141 +; 25: const keyspace = $A0 + ; keyspace = 160 +; 26: const keyarrowup = $8B + ; keyarrowup = 139 +; 27: const keyarrowdown = $8A + ; keyarrowdown = 138 +; 28: const keyarrowleft = $88 + ; keyarrowleft = 136 +; 29: const keyarrowright = $95 + ; keyarrowright = 149 +; 30: const keyescape = $9B + ; keyescape = 155 +; 31: const keyctrla = $81 + ; keyctrla = 129 +; 32: const keyctrlb = $82 + ; keyctrlb = 130 +; 33: const keyctrlc = $83 + ; keyctrlc = 131 +; 34: const keyctrld = $84 + ; keyctrld = 132 +; 35: const keyctrle = $85 + ; keyctrle = 133 +; 36: const keyctrli = $89 + ; keyctrli = 137 +; 37: const keyctrlk = $8B + ; keyctrlk = 139 +; 38: const keyctrll = $8C + ; keyctrll = 140 +; 39: const keyctrln = $8E + ; keyctrln = 142 +; 40: const keyctrlo = $8F + ; keyctrlo = 143 +; 41: const keyctrlp = $90 + ; keyctrlp = 144 +; 42: const keyctrlq = $91 + ; keyctrlq = 145 +; 43: const keyctrlr = $92 + ; keyctrlr = 146 +; 44: const keyctrls = $93 + ; keyctrls = 147 +; 45: const keyctrlt = $94 + ; keyctrlt = 148 +; 46: const keyctrlu = $95 + ; keyctrlu = 149 +; 47: const keyctrlv = $96 + ; keyctrlv = 150 +; 48: const keyctrlw = $97 + ; keyctrlw = 151 +; 49: const keyctrlx = $98 + ; keyctrlx = 152 +; 50: const keyctrlz = $9A + ; keyctrlz = 154 +; 51: const keydelete = $FF + ; keydelete = 255 +; 52: const getbuff = $01FF + ; getbuff = 511 +; 53: const argbuff = $2006 + ; argbuff = 8198 +; 54: word txtscrn[] = $0400,$0480,$0500,$0580,$0600,$0680,$0700,$0780 +D0000: ; txtscrn + DW $0400 + DW $0480 + DW $0500 + DW $0580 + DW $0600 + DW $0680 + DW $0700 + DW $0780 +; 55: word = $0428,$04A8,$0528,$05A8,$0628,$06A8,$0728,$07A8 + DW $0428 + DW $04A8 + DW $0528 + DW $05A8 + DW $0628 + DW $06A8 + DW $0728 + DW $07A8 +; 56: word = $0450,$04D0,$0550,$05D0,$0650,$06D0,$0750,$07D0 + DW $0450 + DW $04D0 + DW $0550 + DW $05D0 + DW $0650 + DW $06D0 + DW $0750 + DW $07D0 +; 57: ; +; 58: ; Data and text buffer constants +; 59: ; +; 60: const machid = $BF98 + ; machid = 49048 +; 61: const maxlines = 626 + ; maxlines = 626 +; 62: const maxfill = 640 + ; maxfill = 640 +; 63: const iobuffer = $0800 + ; iobuffer = 2048 +; 64: const databuff = $0C00 + ; databuff = 3072 +; 65: const strlinbuf = $1000 + ; strlinbuf = 4096 +; 66: const strheapmap = $1500 + ; strheapmap = 5376 +; 67: const strheapmsz = $70 ; = memory@16 bytes per bit map, 128 bytes per 8 bit map, 1K bytes per 8 byte map + ; strheapmsz = 112 +; 68: const maxlnlen = 79 + ; maxlnlen = 79 +; 69: const strheap = $7000 + ; strheap = 28672 +; 70: const strheasz = $3800 + ; strheasz = 14336 +; 71: const codebuff = $A800 + ; codebuff = 43008 +; 72: const codebuffsz = $1000 + ; codebuffsz = 4096 +; 73: const pgjmp = 16 + ; pgjmp = 16 +; 74: const changed = 1 + ; changed = 1 +; 75: const insmode = 2 + ; insmode = 2 +; 76: const showcurs = 4 + ; showcurs = 4 +; 77: const uppercase = 8 + ; uppercase = 8 +; 78: const shiftlock = 128 + ; shiftlock = 128 +; 79: ; +; 80: ; Editor variables +; 81: ; +; 82: byte nullstr[] = "" +D0048: ; nullstr + DB $00 +; 83: byte version[] = "PLASMA ][ IDE VERSION 0.8 " +D0049: ; version + DB $1A + DB $50,$4C,$41,$53,$4D,$41,$20,$5D + DB $5B,$20,$49,$44,$45,$20,$56,$45 + DB $52,$53,$49,$4F,$4E,$20,$30,$2E + DB $38,$20 +; 84: byte errorstr[] = "ERROR: $" +D0076: ; errorstr + DB $08 + DB $45,$52,$52,$4F,$52,$3A,$20,$24 +; 85: byte okstr[] = "OK" +D0085: ; okstr + DB $02 + DB $4F,$4B +; 86: byte perr +D0088: DS 1 ; perr +; 87: byte outofmem[] = "OUT OF MEMORY!" +D0089: ; outofmem + DB $0E + DB $4F,$55,$54,$20,$4F,$46,$20,$4D + DB $45,$4D,$4F,$52,$59,$21 +; 88: byte losechng[] = "LOSE CHANGES TO FILE (Y/N)?" +D0104: ; losechng + DB $1B + DB $4C,$4F,$53,$45,$20,$43,$48,$41 + DB $4E,$47,$45,$53,$20,$54,$4F,$20 + DB $46,$49,$4C,$45,$20,$28,$59,$2F + DB $4E,$29,$3F +; 89: ;byte emiterr[] = "EMIT CODE/DATA MISMATCH" +; 90: byte untitled[] = "UNTITLED" +D0132: ; untitled + DB $08 + DB $55,$4E,$54,$49,$54,$4C,$45,$44 +; 91: byte txtfile[64] = "UNTITLED.PLA" +D0141: ; txtfile + DB $0C + DB $55,$4E,$54,$49,$54,$4C,$45,$44 + DB $2E,$50,$4C,$41 + DS $33 +; 92: byte flags = 0 +D0192: ; flags + DB $00 +; 93: byte flash = 0 +D0193: ; flash + DB $00 +; 94: byte cursx, cursy, scrnleft, curscol, underchr, curschr +D0194: DS 1 ; cursx +D0195: DS 1 ; cursy +D0196: DS 1 ; scrnleft +D0197: DS 1 ; curscol +D0198: DS 1 ; underchr +D0199: DS 1 ; curschr +; 95: word cursrow, scrntop, cursptr +D0200: DS 2 ; cursrow +D0202: DS 2 ; scrntop +D0204: DS 2 ; cursptr +; 96: word numlines = 0 +D0206: ; numlines + DW $0000 +; 97: word cutbuf = 0 +D0208: ; cutbuf + DW $0000 +; 98: word keyin_01 +D0210: DS 2 ; keyin_01 +; 99: ; +; 100: ; Predeclared functions +; 101: ; +; 102: func cmdmode +; 103: ; +; 104: ; Compiler variables +; 105: ; +; 106: ; +; 107: ; Tokens +; 108: ; +; 109: const ID_TKN = $D6 ; V + ; ID_TKN = 214 +; 110: const CHR_TKN = $C3 ; C + ; CHR_TKN = 195 +; 111: const INT_TKN = $C9 ; I + ; INT_TKN = 201 +; 112: const STR_TKN = $D3 ; S + ; STR_TKN = 211 +; 113: const EOL_TKN = $02 + ; EOL_TKN = 2 +; 114: const EOF_TKN = $01 + ; EOF_TKN = 1 +; 115: const ERR_TKN = $00 + ; ERR_TKN = 0 +; 116: ; +; 117: ; Binary operand operators +; 118: ; +; 119: const SET_TKN = $BD ; = + ; SET_TKN = 189 +; 120: const SETLIST_TKN = $B9 ; =, + ; SETLIST_TKN = 185 +; 121: const ADD_TKN = $AB ; + + ; ADD_TKN = 171 +; 122: const SUB_TKN = $AD ; - + ; SUB_TKN = 173 +; 123: const MUL_TKN = $AA ; * + ; MUL_TKN = 170 +; 124: const DIV_TKN = $AF ; / + ; DIV_TKN = 175 +; 125: const MOD_TKN = $A5 ; % + ; MOD_TKN = 165 +; 126: const OR_TKN = $BF ; ? + ; OR_TKN = 191 +; 127: const EOR_TKN = $DE ; ^ + ; EOR_TKN = 222 +; 128: const AND_TKN = $A6 ; & + ; AND_TKN = 166 +; 129: const SHR_TKN = $D2 ; R + ; SHR_TKN = 210 +; 130: const SHL_TKN = $CC ; L + ; SHL_TKN = 204 +; 131: const GT_TKN = $BE ; > + ; GT_TKN = 190 +; 132: const GE_TKN = $C8 ; H + ; GE_TKN = 200 +; 133: const LT_TKN = $BC ; < + ; LT_TKN = 188 +; 134: const LE_TKN = $C2 ; B + ; LE_TKN = 194 +; 135: const NE_TKN = $D5 ; U + ; NE_TKN = 213 +; 136: const EQ_TKN = $C5 ; E + ; EQ_TKN = 197 +; 137: const LOGIC_AND_TKN = $CE ; N + ; LOGIC_AND_TKN = 206 +; 138: const LOGIC_OR_TKN = $CF ; O + ; LOGIC_OR_TKN = 207 +; 139: ; +; 140: ; Unary operand operators +; 141: ; +; 142: const AT_TKN = $C0 ; @ + ; AT_TKN = 192 +; 143: const DOT_TKN = $AE ; . + ; DOT_TKN = 174 +; 144: const COLON_TKN = $BA ; : + ; COLON_TKN = 186 +; 145: const NEG_TKN = $AD ; - + ; NEG_TKN = 173 +; 146: const COMP_TKN = $A3 ; # + ; COMP_TKN = 163 +; 147: const LOGIC_NOT_TKN = $A1 ; ! + ; LOGIC_NOT_TKN = 161 +; 148: const BPTR_TKN = $DE ; ^ + ; BPTR_TKN = 222 +; 149: const WPTR_TKN = $AA ; * + ; WPTR_TKN = 170 +; 150: const INC_TKN = $C1 ; A + ; INC_TKN = 193 +; 151: const DEC_TKN = $C4 ; D + ; DEC_TKN = 196 +; 152: ; +; 153: ; Enclosure tokens +; 154: ; +; 155: const OPEN_PAREN_TKN = $A8 ; ( + ; OPEN_PAREN_TKN = 168 +; 156: const CLOSE_PAREN_TKN = $A9 ; ) + ; CLOSE_PAREN_TKN = 169 +; 157: const OPEN_BRACKET_TKN = $DB ; [ + ; OPEN_BRACKET_TKN = 219 +; 158: const CLOSE_BRACKET_TKN = $DD ; ] + ; CLOSE_BRACKET_TKN = 221 +; 159: ; +; 160: ; Misc. tokens +; 161: ; +; 162: const COMMA_TKN = $AC ; , + ; COMMA_TKN = 172 +; 163: const COMMENT_TKN = $BB ; ; + ; COMMENT_TKN = 187 +; 164: ; +; 165: ; Keyword tokens +; 166: ; +; 167: const CONST_TKN = $80 + ; CONST_TKN = 128 +; 168: const BYTE_TKN = $81 + ; BYTE_TKN = 129 +; 169: const WORD_TKN = $82 + ; WORD_TKN = 130 +; 170: const IF_TKN = $83 + ; IF_TKN = 131 +; 171: const ELSEIF_TKN = $84 + ; ELSEIF_TKN = 132 +; 172: const ELSE_TKN = $85 + ; ELSE_TKN = 133 +; 173: const FIN_TKN = $86 + ; FIN_TKN = 134 +; 174: const END_TKN = $87 + ; END_TKN = 135 +; 175: const WHILE_TKN = $88 + ; WHILE_TKN = 136 +; 176: const LOOP_TKN = $89 + ; LOOP_TKN = 137 +; 177: const CASE_TKN = $8A + ; CASE_TKN = 138 +; 178: const OF_TKN = $8B + ; OF_TKN = 139 +; 179: const DEFAULT_TKN = $8C + ; DEFAULT_TKN = 140 +; 180: const ENDCASE_TKN = $8D + ; ENDCASE_TKN = 141 +; 181: const FOR_TKN = $8E + ; FOR_TKN = 142 +; 182: const TO_TKN = $8F + ; TO_TKN = 143 +; 183: const DOWNTO_TKN = $90 + ; DOWNTO_TKN = 144 +; 184: const STEP_TKN = $91 + ; STEP_TKN = 145 +; 185: const NEXT_TKN = $92 + ; NEXT_TKN = 146 +; 186: const REPEAT_TKN = $93 + ; REPEAT_TKN = 147 +; 187: const UNTIL_TKN = $94 + ; UNTIL_TKN = 148 +; 188: const IFUNC_TKN = $95 + ; IFUNC_TKN = 149 +; 189: const NFUNC_TKN = $96 + ; NFUNC_TKN = 150 +; 190: const DROP_TKN = $97 + ; DROP_TKN = 151 +; 191: const DONE_TKN = $98 + ; DONE_TKN = 152 +; 192: const RETURN_TKN = $99 + ; RETURN_TKN = 153 +; 193: const BREAK_TKN = $9A + ; BREAK_TKN = 154 +; 194: const START_TKN = $9B + ; START_TKN = 155 +; 195: const EXIT_TKN = $9C + ; EXIT_TKN = 156 +; 196: const EVAL_TKN = $9D + ; EVAL_TKN = 157 +; 197: const FUNC_TKN = $9E + ; FUNC_TKN = 158 +; 198: ; +; 199: ; Types +; 200: ; +; 201: const CONST_TYPE = $01 + ; CONST_TYPE = 1 +; 202: const BYTE_TYPE = $02 + ; BYTE_TYPE = 2 +; 203: const WORD_TYPE = $04 + ; WORD_TYPE = 4 +; 204: const VAR_TYPE = $06 ; (WORD_TYPE | BYTE_TYPE) + ; VAR_TYPE = 6 +; 205: const FUNC_TYPE = $08 + ; FUNC_TYPE = 8 +; 206: const FUNC_CONST_TYPE = $09 + ; FUNC_CONST_TYPE = 9 +; 207: const ADDR_TYPE = $0E ; (VAR_TYPE | FUNC_TYPE) + ; ADDR_TYPE = 14 +; 208: const LOCAL_TYPE = $10 + ; LOCAL_TYPE = 16 +; 209: const BPTR_TYPE = $20 + ; BPTR_TYPE = 32 +; 210: const WPTR_TYPE = $40 + ; WPTR_TYPE = 64 +; 211: const PTR_TYPE = $60 ; (BPTR_TYPE | WPTR_TYPE) + ; PTR_TYPE = 96 +; 212: const XBYTE_TYPE = $22 ; (BPTR_TYPE | BYTE_TYPE) + ; XBYTE_TYPE = 34 +; 213: const XWORD_TYPE = $44 ; (WPTR_TYPE | WORD_TYPE) + ; XWORD_TYPE = 68 +; 214: const STR_TYPE = $80 + ; STR_TYPE = 128 +; 215: ; +; 216: ; Keywords +; 217: ; +; 218: byte keywrds[] +D0212: ; keywrds +; 219: byte = "IF", IF_TKN + DB $02 + DB $49,$46 + DB $83 +; 220: byte = "TO", TO_TKN + DB $02 + DB $54,$4F + DB $8F +; 221: byte = "IS", OF_TKN + DB $02 + DB $49,$53 + DB $8B +; 222: byte = "OR", LOGIC_OR_TKN + DB $02 + DB $4F,$52 + DB $CF +; 223: byte = "FOR", FOR_TKN + DB $03 + DB $46,$4F,$52 + DB $8E +; 224: byte = "FIN", FIN_TKN + DB $03 + DB $46,$49,$4E + DB $86 +; 225: byte = "DEF", IFUNC_TKN + DB $03 + DB $44,$45,$46 + DB $95 +; 226: byte = "END", END_TKN + DB $03 + DB $45,$4E,$44 + DB $87 +; 227: byte = "AND", LOGIC_AND_TKN + DB $03 + DB $41,$4E,$44 + DB $CE +; 228: byte = "NOT", LOGIC_NOT_TKN + DB $03 + DB $4E,$4F,$54 + DB $A1 +; 229: byte = "BYTE", BYTE_TKN + DB $04 + DB $42,$59,$54,$45 + DB $81 +; 230: byte = "WORD", WORD_TKN + DB $04 + DB $57,$4F,$52,$44 + DB $82 +; 231: byte = "DROP", DROP_TKN + DB $04 + DB $44,$52,$4F,$50 + DB $97 +; 232: byte = "ELSE", ELSE_TKN + DB $04 + DB $45,$4C,$53,$45 + DB $85 +; 233: byte = "NEXT", NEXT_TKN + DB $04 + DB $4E,$45,$58,$54 + DB $92 +; 234: byte = "WHEN", CASE_TKN + DB $04 + DB $57,$48,$45,$4E + DB $8A +; 235: byte = "LOOP", LOOP_TKN + DB $04 + DB $4C,$4F,$4F,$50 + DB $89 +; 236: byte = "FUNC", FUNC_TKN + DB $04 + DB $46,$55,$4E,$43 + DB $9E +; 237: byte = "STEP", STEP_TKN + DB $04 + DB $53,$54,$45,$50 + DB $91 +; 238: byte = "EXIT", EXIT_TKN + DB $04 + DB $45,$58,$49,$54 + DB $9C +; 239: byte = "DONE", DONE_TKN + DB $04 + DB $44,$4F,$4E,$45 + DB $98 +; 240: byte = "WEND", ENDCASE_TKN + DB $04 + DB $57,$45,$4E,$44 + DB $8D +; 241: byte = "CONST", CONST_TKN + DB $05 + DB $43,$4F,$4E,$53,$54 + DB $80 +; 242: byte = "ELSIF", ELSEIF_TKN + DB $05 + DB $45,$4C,$53,$49,$46 + DB $84 +; 243: byte = "WHILE", WHILE_TKN + DB $05 + DB $57,$48,$49,$4C,$45 + DB $88 +; 244: byte = "UNTIL", UNTIL_TKN + DB $05 + DB $55,$4E,$54,$49,$4C + DB $94 +; 245: byte = "BREAK", BREAK_TKN + DB $05 + DB $42,$52,$45,$41,$4B + DB $9A +; 246: byte = "OTHER", DEFAULT_TKN + DB $05 + DB $4F,$54,$48,$45,$52 + DB $8C +; 247: byte = "DOWNTO", DOWNTO_TKN + DB $06 + DB $44,$4F,$57,$4E,$54,$4F + DB $90 +; 248: byte = "REPEAT", REPEAT_TKN + DB $06 + DB $52,$45,$50,$45,$41,$54 + DB $93 +; 249: byte = "DEFOPT", NFUNC_TKN + DB $06 + DB $44,$45,$46,$4F,$50,$54 + DB $96 +; 250: byte = "RETURN", RETURN_TKN + DB $06 + DB $52,$45,$54,$55,$52,$4E + DB $99 +; 251: byte = $FF + DB $FF +; 252: ; +; 253: ; Mathematical ops +; 254: ; +; 255: const bops_tblsz = 18 ; minus 1 + ; bops_tblsz = 18 +; 256: byte bops_tbl[] ; Highest precedence +D0405: ; bops_tbl +; 257: byte = MUL_TKN, DIV_TKN, MOD_TKN + DB $AA + DB $AF + DB $A5 +; 258: byte = ADD_TKN, SUB_TKN + DB $AB + DB $AD +; 259: byte = SHR_TKN, SHL_TKN + DB $D2 + DB $CC +; 260: byte = AND_TKN + DB $A6 +; 261: byte = EOR_TKN + DB $DE +; 262: byte = OR_TKN + DB $BF +; 263: byte = GT_TKN, GE_TKN, LT_TKN, LE_TKN + DB $BE + DB $C8 + DB $BC + DB $C2 +; 264: byte = EQ_TKN, NE_TKN + DB $C5 + DB $D5 +; 265: byte = LOGIC_AND_TKN + DB $CE +; 266: byte = LOGIC_OR_TKN + DB $CF +; 267: byte = COMMA_TKN + DB $AC +; 268: ; Lowest precedence +; 269: byte bops_prec[] ; Highest precedence +D0424: ; bops_prec +; 270: byte = 1, 1, 1 + DB $01 + DB $01 + DB $01 +; 271: byte = 2, 2 + DB $02 + DB $02 +; 272: byte = 3, 3 + DB $03 + DB $03 +; 273: byte = 4 + DB $04 +; 274: byte = 5 + DB $05 +; 275: byte = 6 + DB $06 +; 276: byte = 7, 7, 7, 7 + DB $07 + DB $07 + DB $07 + DB $07 +; 277: byte = 8, 8 + DB $08 + DB $08 +; 278: byte = 9 + DB $09 +; 279: byte = 10 + DB $0A +; 280: byte = 11 + DB $0B +; 281: ; Lowest precedence +; 282: byte opstack[16] +D0443: DS 16 ; opstack +; 283: byte precstack[16] +D0459: DS 16 ; precstack +; 284: word opsp = -1 +D0475: ; opsp + DW $FFFF +; 285: ; +; 286: ; Symbol table variables +; 287: ; +; 288: const idglobal_tblsz = 2048 + ; idglobal_tblsz = 2048 +; 289: const idlocal_tblsz = 512 + ; idlocal_tblsz = 512 +; 290: const idglobal_tbl = $1600 + ; idglobal_tbl = 5632 +; 291: const idlocal_tbl = $1E00 + ; idlocal_tbl = 7680 +; 292: const ctag_max = 640 + ; ctag_max = 640 +; 293: const ctag_value = $800 + ; ctag_value = 2048 +; 294: const ctag_flags = $D80 + ; ctag_flags = 3456 +; 295: const idval = 0 + ; idval = 0 +; 296: const idtype = 2 + ; idtype = 2 +; 297: const idname = 3 + ; idname = 3 +; 298: const idrecsz = 4 + ; idrecsz = 4 +; 299: word globals = 0 +D0477: ; globals + DW $0000 +; 300: word datasize = 0 +D0479: ; datasize + DW $0000 +; 301: word lastglobal +D0481: DS 2 ; lastglobal +; 302: byte locals = 0 +D0483: ; locals + DB $00 +; 303: word framesize = 0 +D0484: ; framesize + DW $0000 +; 304: word lastlocal +D0486: DS 2 ; lastlocal +; 305: const resolved = 1 + ; resolved = 1 +; 306: const is_ctag = $8000 + ; is_ctag = 32768 +; 307: const mask_ctag = $7FFF + ; mask_ctag = 32767 +; 308: word codetag = -1 +D0488: ; codetag + DW $FFFF +; 309: word codeptr, entrypoint = 0 +D0490: DS 2 ; codeptr +D0492: ; entrypoint + DW $0000 +; 310: byte lastop = $FF +D0494: ; lastop + DB $FF +; 311: ; +; 312: ; Scanner variables +; 313: ; +; 314: const inbuff = $0200 + ; inbuff = 512 +; 315: const instr = $01FF + ; instr = 511 +; 316: byte token, tknlen +D0495: DS 1 ; token +D0496: DS 1 ; tknlen +; 317: byte parserrpos, parserr = 0 +D0497: DS 1 ; parserrpos +D0498: ; parserr + DB $00 +; 318: word scanptr, tknptr, parserrln +D0499: DS 2 ; scanptr +D0501: DS 2 ; tknptr +D0503: DS 2 ; parserrln +; 319: word constval +D0505: DS 2 ; constval +; 320: word lineno = 0 +D0507: ; lineno + DW $0000 +; 321: ; +; 322: ; Compiler output messages +; 323: ; +; 324: byte entrypt_str[] = "START: " +D0509: ; entrypt_str + DB $07 + DB $53,$54,$41,$52,$54,$3A,$20 +; 325: byte comp_ok_msg[] = "COMPILATION COMPLETE" +D0517: ; comp_ok_msg + DB $14 + DB $43,$4F,$4D,$50,$49,$4C,$41,$54 + DB $49,$4F,$4E,$20,$43,$4F,$4D,$50 + DB $4C,$45,$54,$45 +; 326: byte dup_id[] = "DUPLICATE IDENTIFIER" +D0538: ; dup_id + DB $14 + DB $44,$55,$50,$4C,$49,$43,$41,$54 + DB $45,$20,$49,$44,$45,$4E,$54,$49 + DB $46,$49,$45,$52 +; 327: byte undecl_id[] = "UNDECLARED IDENTIFIER" +D0559: ; undecl_id + DB $15 + DB $55,$4E,$44,$45,$43,$4C,$41,$52 + DB $45,$44,$20,$49,$44,$45,$4E,$54 + DB $49,$46,$49,$45,$52 +; 328: byte bad_cnst[] = "BAD CONSTANT" +D0581: ; bad_cnst + DB $0C + DB $42,$41,$44,$20,$43,$4F,$4E,$53 + DB $54,$41,$4E,$54 +; 329: byte bad_offset[] = "BAD STRUCT OFFSET" +D0594: ; bad_offset + DB $11 + DB $42,$41,$44,$20,$53,$54,$52,$55 + DB $43,$54,$20,$4F,$46,$46,$53,$45 + DB $54 +; 330: byte bad_decl[] = "BAD DECLARATION" +D0612: ; bad_decl + DB $0F + DB $42,$41,$44,$20,$44,$45,$43,$4C + DB $41,$52,$41,$54,$49,$4F,$4E +; 331: byte bad_op[] = "BAD OPERATION" +D0628: ; bad_op + DB $0D + DB $42,$41,$44,$20,$4F,$50,$45,$52 + DB $41,$54,$49,$4F,$4E +; 332: byte bad_stmnt[] = "BAD STATMENT" +D0642: ; bad_stmnt + DB $0C + DB $42,$41,$44,$20,$53,$54,$41,$54 + DB $4D,$45,$4E,$54 +; 333: byte bad_expr[] = "BAD EXPRESSION" +D0655: ; bad_expr + DB $0E + DB $42,$41,$44,$20,$45,$58,$50,$52 + DB $45,$53,$53,$49,$4F,$4E +; 334: byte bad_syntax[] = "BAD SYNTAX" +D0670: ; bad_syntax + DB $0A + DB $42,$41,$44,$20,$53,$59,$4E,$54 + DB $41,$58 +; 335: byte estk_overflw[] = "EVAL STACK OVERFLOW" +D0681: ; estk_overflw + DB $13 + DB $45,$56,$41,$4C,$20,$53,$54,$41 + DB $43,$4B,$20,$4F,$56,$45,$52,$46 + DB $4C,$4F,$57 +; 336: byte estk_underflw[] = "EVAL STACK UNDERFLOW" +D0701: ; estk_underflw + DB $14 + DB $45,$56,$41,$4C,$20,$53,$54,$41 + DB $43,$4B,$20,$55,$4E,$44,$45,$52 + DB $46,$4C,$4F,$57 +; 337: byte local_overflw[] = "LOCAL FRAME OVERFLOW" +D0722: ; local_overflw + DB $14 + DB $4C,$4F,$43,$41,$4C,$20,$46,$52 + DB $41,$4D,$45,$20,$4F,$56,$45,$52 + DB $46,$4C,$4F,$57 +; 338: byte global_sym_overflw[] = "GLOBAL SYMBOL TABLE OVERFLOW" +D0743: ; global_sym_overflw + DB $1C + DB $47,$4C,$4F,$42,$41,$4C,$20,$53 + DB $59,$4D,$42,$4F,$4C,$20,$54,$41 + DB $42,$4C,$45,$20,$4F,$56,$45,$52 + DB $46,$4C,$4F,$57 +; 339: byte local_sym_overflw[] = "LOCAL SYMBOL TABLE OVERFLOW" +D0772: ; local_sym_overflw + DB $1B + DB $4C,$4F,$43,$41,$4C,$20,$53,$59 + DB $4D,$42,$4F,$4C,$20,$54,$41,$42 + DB $4C,$45,$20,$4F,$56,$45,$52,$46 + DB $4C,$4F,$57 +; 340: byte ctag_full[] = "CODE LABEL OVERFLOW" +D0800: ; ctag_full + DB $13 + DB $43,$4F,$44,$45,$20,$4C,$41,$42 + DB $45,$4C,$20,$4F,$56,$45,$52,$46 + DB $4C,$4F,$57 +; 341: byte no_close_paren[] = "MISSING CLOSING PAREN" +D0820: ; no_close_paren + DB $15 + DB $4D,$49,$53,$53,$49,$4E,$47,$20 + DB $43,$4C,$4F,$53,$49,$4E,$47,$20 + DB $50,$41,$52,$45,$4E +; 342: byte no_close_bracket[] = "MISSING CLOSING BRACKET" +D0842: ; no_close_bracket + DB $17 + DB $4D,$49,$53,$53,$49,$4E,$47,$20 + DB $43,$4C,$4F,$53,$49,$4E,$47,$20 + DB $42,$52,$41,$43,$4B,$45,$54 +; 343: byte missing_op[] = "MISSING OPERAND" +D0866: ; missing_op + DB $0F + DB $4D,$49,$53,$53,$49,$4E,$47,$20 + DB $4F,$50,$45,$52,$41,$4E,$44 +; 344: byte no_fin[] = "MISSING FIN" +D0882: ; no_fin + DB $0B + DB $4D,$49,$53,$53,$49,$4E,$47,$20 + DB $46,$49,$4E +; 345: byte no_loop[] = "MISSING LOOP" +D0894: ; no_loop + DB $0C + DB $4D,$49,$53,$53,$49,$4E,$47,$20 + DB $4C,$4F,$4F,$50 +; 346: byte no_until[] = "MISSING UNTIL" +D0907: ; no_until + DB $0D + DB $4D,$49,$53,$53,$49,$4E,$47,$20 + DB $55,$4E,$54,$49,$4C +; 347: byte no_done[] = "MISSING DONE" +D0921: ; no_done + DB $0C + DB $4D,$49,$53,$53,$49,$4E,$47,$20 + DB $44,$4F,$4E,$45 +; 348: byte no_local_init[] = "NO INITIALIZED LOCALS" +D0934: ; no_local_init + DB $15 + DB $4E,$4F,$20,$49,$4E,$49,$54,$49 + DB $41,$4C,$49,$5A,$45,$44,$20,$4C + DB $4F,$43,$41,$4C,$53 +; 349: ; +; 350: ; Runtime messages +; 351: ; +; 352: byte brkmsg[] = "CTRL-C BREAK" +D0956: ; brkmsg + DB $0C + DB $43,$54,$52,$4C,$2D,$43,$20,$42 + DB $52,$45,$41,$4B +; 353: byte stkovflwmsg[] = "STACK OVERFLOW/UNDERFLOW ERROR" +D0969: ; stkovflwmsg + DB $1E + DB $53,$54,$41,$43,$4B,$20,$4F,$56 + DB $45,$52,$46,$4C,$4F,$57,$2F,$55 + DB $4E,$44,$45,$52,$46,$4C,$4F,$57 + DB $20,$45,$52,$52,$4F,$52 +; 354: ; +; 355: ; Runtime functions +; 356: ; +; 357: byte runtime0[] = "romcall" +D1000: ; runtime0 + DB $07 + DB $72,$6F,$6D,$63,$61,$6C,$6C +; 358: byte RUNTIME0[] = "ROMCALL" +D1008: ; RUNTIME0 + DB $07 + DB $52,$4F,$4D,$43,$41,$4C,$4C +; 359: byte runtime1[] = "syscall" +D1016: ; runtime1 + DB $07 + DB $73,$79,$73,$63,$61,$6C,$6C +; 360: byte RUNTIME1[] = "SYSCALL" +D1024: ; RUNTIME1 + DB $07 + DB $53,$59,$53,$43,$41,$4C,$4C +; 361: byte runtime2[] = "memset" +D1032: ; runtime2 + DB $06 + DB $6D,$65,$6D,$73,$65,$74 +; 362: byte RUNTIME2[] = "MEMSET" +D1039: ; RUNTIME2 + DB $06 + DB $4D,$45,$4D,$53,$45,$54 +; 363: byte runtime3[] = "memcpy" +D1046: ; runtime3 + DB $06 + DB $6D,$65,$6D,$63,$70,$79 +; 364: byte RUNTIME3[] = "MEMCPY" +D1053: ; RUNTIME3 + DB $06 + DB $4D,$45,$4D,$43,$50,$59 +; 365: byte runtime4[] = "cout" +D1060: ; runtime4 + DB $04 + DB $63,$6F,$75,$74 +; 366: byte RUNTIME4[] = "COUT" +D1065: ; RUNTIME4 + DB $04 + DB $43,$4F,$55,$54 +; 367: byte runtime5[] = "cin" +D1070: ; runtime5 + DB $03 + DB $63,$69,$6E +; 368: byte RUNTIME5[] = "CIN" +D1074: ; RUNTIME5 + DB $03 + DB $43,$49,$4E +; 369: byte runtime6[] = "prstr" +D1078: ; runtime6 + DB $05 + DB $70,$72,$73,$74,$72 +; 370: byte RUNTIME6[] = "PRSTR" +D1084: ; RUNTIME6 + DB $05 + DB $50,$52,$53,$54,$52 +; 371: byte runtime7[] = "rdstr" +D1090: ; runtime7 + DB $05 + DB $72,$64,$73,$74,$72 +; 372: byte RUNTIME7[] = "RDSTR" +D1096: ; RUNTIME7 + DB $05 + DB $52,$44,$53,$54,$52 +; 373: ; +; 374: ; Parser variables +; 375: ; +; 376: byte infunc = 0 +D1102: ; infunc + DB $00 +; 377: byte stack_loop = 0 +D1103: ; stack_loop + DB $00 +; 378: byte prevstmnt = 0 +D1104: ; prevstmnt + DB $00 +; 379: word retfunc_tag = 0 +D1105: ; retfunc_tag + DW $0000 +; 380: word break_tag = 0 +D1107: ; break_tag + DW $0000 +; 381: func parse_expr_01, parse_module_01 +; 382: ; +; 383: ; Utility functions +; 384: ; +; 385: ; Defines for ASM routines +; 386: ; +; 387: asm equates +C0003: ; equates() +; 388: TMP EQU $F0 + TMP EQU $F0 +; 389: TMPL EQU TMP + TMPL EQU TMP +; 390: TMPH EQU TMP+1 + TMPH EQU TMP+1 +; 391: SRC EQU TMP + SRC EQU TMP +; 392: SRCL EQU SRC + SRCL EQU SRC +; 393: SRCH EQU SRC+1 + SRCH EQU SRC+1 +; 394: DST EQU SRC+2 + DST EQU SRC+2 +; 395: DSTL EQU DST + DSTL EQU DST +; 396: DSTH EQU DST+1 + DSTH EQU DST+1 +; 397: ESP EQU DST+2 + ESP EQU DST+2 +; 398: SAVEESP EQU ESP+1 + SAVEESP EQU ESP+1 +; 399: SAVESP EQU SAVEESP+1 + SAVESP EQU SAVEESP+1 +; 400: SAVEFP EQU SAVESP+1 + SAVEFP EQU SAVESP+1 +; 401: SAVETMR EQU SAVEFP+2 + SAVETMR EQU SAVEFP+2 +; 402: SAVEINT EQU SAVETMR+2 + SAVEINT EQU SAVETMR+2 +; 403: TMRVEC EQU $03E8 + TMRVEC EQU $03E8 +; 404: INTVEC EQU $03EA + INTVEC EQU $03EA +; 405: JMPTMP: JMP (TMP) +JMPTMP: JMP (TMP) +; 406: STKOVFLW: +STKOVFLW: +; 407: LDY #$02 + LDY #$02 +; 408: JMP EXECRET + JMP EXECRET +; 409: BRKCHK: +BRKCHK: +; 410: LDA $C000 + LDA $C000 +; 411: CMP #$83 ; CTRL-C + CMP #$83 ; CTRL-C +; 412: BNE :+ + BNE :+ +; 413: BIT $C010 + BIT $C010 +; 414: LDY #$01 + LDY #$01 +; 415: JMP EXECRET + JMP EXECRET +; 416: : +: +; 417: end + RTS +; 418: ; +; 419: ; ENTER MODULE UNDER TEST +; 420: ; +; 421: asm execentry +C0005: ; execentry() +; 422: LDA ESTKL,X + LDA ESTKL,X +; 423: STA TMPL + STA TMPL +; 424: LDA ESTKH,X + LDA ESTKH,X +; 425: STA TMPH + STA TMPH +; 426: STX SAVEESP + STX SAVEESP +; 427: TSX + TSX +; 428: STX SAVESP + STX SAVESP +; 429: LDA FRMPL + LDA FRMPL +; 430: STA SAVEFP + STA SAVEFP +; 431: LDA FRMPH + LDA FRMPH +; 432: STA SAVEFP+1 + STA SAVEFP+1 +; 433: LDA TMRVEC + LDA TMRVEC +; 434: STA SAVETMR + STA SAVETMR +; 435: LDA TMRVEC+1 + LDA TMRVEC+1 +; 436: STA SAVETMR+1 + STA SAVETMR+1 +; 437: LDA INTVEC + LDA INTVEC +; 438: STA SAVEINT + STA SAVEINT +; 439: LDA INTVEC+1 + LDA INTVEC+1 +; 440: STA SAVEINT+1 + STA SAVEINT+1 +; 441: LDA #BRKCHK + LDA #>BRKCHK +; 444: STA TMRVEC+1 + STA TMRVEC+1 +; 445: LDA #STKOVFLW + LDA #>STKOVFLW +; 448: STA INTVEC+1 + STA INTVEC+1 +; 449: LDX #ESTKSZ/2 + LDX #ESTKSZ/2 +; 450: JSR JMPTMP + JSR JMPTMP +; 451: LDY #$00 + LDY #$00 +; 452: EXECRET: +EXECRET: +; 453: STY TMP + STY TMP +; 454: BIT ROMIN + BIT ROMIN +; 455: BIT $C054 + BIT $C054 +; 456: BIT $C051 + BIT $C051 +; 457: BIT $C058 + BIT $C058 +; 458: JSR $FB39 ; SET TEXT MODE + JSR $FB39 ; SET TEXT MODE +; 459: BIT LCBNK2 + BIT LCBNK2 +; 460: LDA SAVEFP + LDA SAVEFP +; 461: STA FRMPL + STA FRMPL +; 462: LDA SAVEFP+1 + LDA SAVEFP+1 +; 463: STA FRMPH + STA FRMPH +; 464: LDA SAVETMR + LDA SAVETMR +; 465: STA TMRVEC + STA TMRVEC +; 466: LDA SAVETMR+1 + LDA SAVETMR+1 +; 467: STA TMRVEC+1 + STA TMRVEC+1 +; 468: LDA SAVEINT + LDA SAVEINT +; 469: STA INTVEC + STA INTVEC +; 470: LDA SAVEINT+1 + LDA SAVEINT+1 +; 471: STA INTVEC+1 + STA INTVEC+1 +; 472: LDX SAVESP + LDX SAVESP +; 473: TXS + TXS +; 474: LDX SAVEESP + LDX SAVEESP +; 475: LDY TMP + LDY TMP +; 476: STY ESTKL,X + STY ESTKL,X +; 477: LDY #$00 + LDY #$00 +; 478: STY ESTKH,X + STY ESTKH,X +; 479: end + RTS +; 480: ; +; 481: ; CALL 6502 ROUTINE +; 482: ; ROMCALL(AREG, XREG, YREG, STATUS, ADDR) +; 483: ; +; 484: asm romcall +C0007: ; romcall() +; 485: PHP + PHP +; 486: LDA ESTKL,X + LDA ESTKL,X +; 487: STA TMPL + STA TMPL +; 488: LDA ESTKH,X + LDA ESTKH,X +; 489: STA TMPH + STA TMPH +; 490: INX + INX +; 491: LDA ESTKL,X + LDA ESTKL,X +; 492: PHA + PHA +; 493: INX + INX +; 494: LDA ESTKL,X + LDA ESTKL,X +; 495: TAY + TAY +; 496: INX + INX +; 497: LDA ESTKL+1,X + LDA ESTKL+1,X +; 498: PHA + PHA +; 499: LDA ESTKL,X + LDA ESTKL,X +; 500: INX + INX +; 501: STX ESP + STX ESP +; 502: TAX + TAX +; 503: PLA + PLA +; 504: BIT ROMIN + BIT ROMIN +; 505: PLP + PLP +; 506: JSR JMPTMP + JSR JMPTMP +; 507: PHP + PHP +; 508: BIT LCBNK2 + BIT LCBNK2 +; 509: STA REGVALS+0 + STA REGVALS+0 +; 510: STX REGVALS+1 + STX REGVALS+1 +; 511: STY REGVALS+2 + STY REGVALS+2 +; 512: PLA + PLA +; 513: STA REGVALS+3 + STA REGVALS+3 +; 514: LDX ESP + LDX ESP +; 515: LDA #REGVALS + LDY #>REGVALS +; 517: STA ESTKL,X + STA ESTKL,X +; 518: STY ESTKH,X + STY ESTKH,X +; 519: PLP + PLP +; 520: RTS + RTS +; 521: REGVALS: DS 4 +REGVALS: DS 4 +; 522: end + RTS +; 523: ; +; 524: ; CALL PRODOS +; 525: ; SYSCALL(CMD, PARAMS) +; 526: ; +; 527: asm syscall +C0009: ; syscall() +; 528: LDA ESTKL,X + LDA ESTKL,X +; 529: LDY ESTKH,X + LDY ESTKH,X +; 530: STA PARAMS + STA PARAMS +; 531: STY PARAMS+1 + STY PARAMS+1 +; 532: INX + INX +; 533: LDA ESTKL,X + LDA ESTKL,X +; 534: STA CMD + STA CMD +; 535: STX ESP + STX ESP +; 536: JSR $BF00 + JSR $BF00 +; 537: CMD: DB 00 +CMD: DB 00 +; 538: PARAMS: DW 0000 +PARAMS: DW 0000 +; 539: BIT LCBNK2 + BIT LCBNK2 +; 540: LDX ESP + LDX ESP +; 541: STA ESTKL,X + STA ESTKL,X +; 542: LDY #$00 + LDY #$00 +; 543: STY ESTKH,X + STY ESTKH,X +; 544: end + RTS +; 545: ; +; 546: ; SET MEMORY TO VALUE +; 547: ; MEMSET(VALUE, ADDR, SIZE) +; 548: ; +; 549: asm memset +C0011: ; memset() +; 550: LDY #$00 + LDY #$00 +; 551: LDA ESTKL+1,X + LDA ESTKL+1,X +; 552: STA DSTL + STA DSTL +; 553: LDA ESTKH+1,X + LDA ESTKH+1,X +; 554: STA DSTH + STA DSTH +; 555: INC ESTKL,X + INC ESTKL,X +; 556: INC ESTKH,X + INC ESTKH,X +; 557: SETMEM: DEC ESTKL,X +SETMEM: DEC ESTKL,X +; 558: BNE :+ + BNE :+ +; 559: DEC ESTKH,X + DEC ESTKH,X +; 560: BEQ MEMEXIT + BEQ MEMEXIT +; 561: : LDA ESTKL+2,X +: LDA ESTKL+2,X +; 562: STA (DST),Y + STA (DST),Y +; 563: INY + INY +; 564: BNE :+ + BNE :+ +; 565: INC DSTH + INC DSTH +; 566: : DEC ESTKL,X +: DEC ESTKL,X +; 567: BNE :+ + BNE :+ +; 568: DEC ESTKH,X + DEC ESTKH,X +; 569: BEQ MEMEXIT + BEQ MEMEXIT +; 570: : LDA ESTKH+2,X +: LDA ESTKH+2,X +; 571: STA (DST),Y + STA (DST),Y +; 572: INY + INY +; 573: BNE SETMEM + BNE SETMEM +; 574: INC DSTH + INC DSTH +; 575: BNE SETMEM + BNE SETMEM +; 576: MEMEXIT: INX +MEMEXIT: INX +; 577: INX + INX +; 578: INX + INX +; 579: end + RTS +; 580: ; +; 581: ; COPY MEMORY +; 582: ; MEMCPY(SRCADDR, DSTADDR, SIZE) +; 583: ; +; 584: asm memcpy +C0013: ; memcpy() +; 585: LDY #$00 + LDY #$00 +; 586: LDA ESTKL,X + LDA ESTKL,X +; 587: BNE :+ + BNE :+ +; 588: LDA ESTKH,X + LDA ESTKH,X +; 589: BEQ MEMEXIT + BEQ MEMEXIT +; 590: : LDA ESTKL+1,X +: LDA ESTKL+1,X +; 591: STA DSTL + STA DSTL +; 592: LDA ESTKH+1,X + LDA ESTKH+1,X +; 593: STA DSTH + STA DSTH +; 594: LDA ESTKL+2,X + LDA ESTKL+2,X +; 595: STA SRCL + STA SRCL +; 596: LDA ESTKH+2,X + LDA ESTKH+2,X +; 597: STA SRCH + STA SRCH +; 598: CMP DSTH + CMP DSTH +; 599: BCC REVCPY + BCC REVCPY +; 600: BNE FORCPY + BNE FORCPY +; 601: LDA SRCL + LDA SRCL +; 602: CMP DSTL + CMP DSTL +; 603: BCS FORCPY + BCS FORCPY +; 604: REVCPY: ; REVERSE DIRECTION COPY +REVCPY: ; REVERSE DIRECTION COPY +; 605: ; CLC +; 606: LDA ESTKL,X + LDA ESTKL,X +; 607: ADC DSTL + ADC DSTL +; 608: STA DSTL + STA DSTL +; 609: LDA ESTKH,X + LDA ESTKH,X +; 610: ADC DSTH + ADC DSTH +; 611: STA DSTH + STA DSTH +; 612: CLC + CLC +; 613: LDA ESTKL,X + LDA ESTKL,X +; 614: ADC SRCL + ADC SRCL +; 615: STA SRCL + STA SRCL +; 616: LDA ESTKH,X + LDA ESTKH,X +; 617: ADC SRCH + ADC SRCH +; 618: STA SRCH + STA SRCH +; 619: INC ESTKH,X + INC ESTKH,X +; 620: REVCPYLP: +REVCPYLP: +; 621: LDA DSTL + LDA DSTL +; 622: BNE :+ + BNE :+ +; 623: DEC DSTH + DEC DSTH +; 624: : DEC DSTL +: DEC DSTL +; 625: LDA SRCL + LDA SRCL +; 626: BNE :+ + BNE :+ +; 627: DEC SRCH + DEC SRCH +; 628: : DEC SRCL +: DEC SRCL +; 629: LDA (SRC),Y + LDA (SRC),Y +; 630: STA (DST),Y + STA (DST),Y +; 631: DEC ESTKL,X + DEC ESTKL,X +; 632: BNE REVCPYLP + BNE REVCPYLP +; 633: DEC ESTKH,X + DEC ESTKH,X +; 634: BNE REVCPYLP + BNE REVCPYLP +; 635: BEQ MEMEXIT + BEQ MEMEXIT +; 636: FORCPY: INC ESTKH,X +FORCPY: INC ESTKH,X +; 637: FORCPYLP: +FORCPYLP: +; 638: LDA (SRC),Y + LDA (SRC),Y +; 639: STA (DST),Y + STA (DST),Y +; 640: INC DSTL + INC DSTL +; 641: BNE :+ + BNE :+ +; 642: INC DSTH + INC DSTH +; 643: : INC SRCL +: INC SRCL +; 644: BNE :+ + BNE :+ +; 645: INC SRCH + INC SRCH +; 646: : DEC ESTKL,X +: DEC ESTKL,X +; 647: BNE FORCPYLP + BNE FORCPYLP +; 648: DEC ESTKH,X + DEC ESTKH,X +; 649: BNE FORCPYLP + BNE FORCPYLP +; 650: BEQ MEMEXIT + BEQ MEMEXIT +; 651: end + RTS +; 652: ; +; 653: ; CHAR OUT +; 654: ; COUT(CHAR) +; 655: ; +; 656: asm cout +C0015: ; cout() +; 657: LDA ESTKL,X + LDA ESTKL,X +; 658: INX + INX +; 659: ORA #$80 + ORA #$80 +; 660: BIT ROMIN + BIT ROMIN +; 661: JSR $FDED + JSR $FDED +; 662: BIT LCBNK2 + BIT LCBNK2 +; 663: end + RTS +; 664: ; +; 665: ; CHAR IN +; 666: ; RDKEY() +; 667: ; +; 668: asm cin +C0017: ; cin() +; 669: BIT ROMIN + BIT ROMIN +; 670: STX ESP + STX ESP +; 671: JSR $FD0C + JSR $FD0C +; 672: LDX ESP + LDX ESP +; 673: BIT LCBNK2 + BIT LCBNK2 +; 674: DEX + DEX +; 675: AND #$7F + AND #$7F +; 676: STA ESTKL,X + STA ESTKL,X +; 677: LDY #$00 + LDY #$00 +; 678: STY ESTKH,X + STY ESTKH,X +; 679: end + RTS +; 680: ; +; 681: ; PRINT STRING +; 682: ; PRSTR(STR) +; 683: ; +; 684: asm prstr +C0019: ; prstr() +; 685: LDY #$00 + LDY #$00 +; 686: LDA ESTKL,X + LDA ESTKL,X +; 687: STA SRCL + STA SRCL +; 688: LDA ESTKH,X + LDA ESTKH,X +; 689: STA SRCH + STA SRCH +; 690: BIT ROMIN + BIT ROMIN +; 691: LDA (SRC),Y + LDA (SRC),Y +; 692: STA ESTKL,X + STA ESTKL,X +; 693: BEQ :+ + BEQ :+ +; 694: _PRS1: INY +_PRS1: INY +; 695: LDA (SRC),Y + LDA (SRC),Y +; 696: ORA #$80 + ORA #$80 +; 697: JSR $FDED + JSR $FDED +; 698: TYA + TYA +; 699: CMP ESTKL,X + CMP ESTKL,X +; 700: BNE _PRS1 + BNE _PRS1 +; 701: : INX +: INX +; 702: BIT LCBNK2 + BIT LCBNK2 +; 703: end + RTS +; 704: ; +; 705: ; READ STRING +; 706: ; STR = RDSTR(PROMPTCHAR) +; 707: ; +; 708: asm rdstr +C0021: ; rdstr() +; 709: LDA ESTKL,X + LDA ESTKL,X +; 710: STA $33 + STA $33 +; 711: STX ESP + STX ESP +; 712: BIT ROMIN + BIT ROMIN +; 713: JSR $FD6A + JSR $FD6A +; 714: BIT LCBNK2 + BIT LCBNK2 +; 715: STX $01FF + STX $01FF +; 716: : LDA $01FF,X +: LDA $01FF,X +; 717: AND #$7F + AND #$7F +; 718: STA $01FF,X + STA $01FF,X +; 719: DEX + DEX +; 720: BPL :- + BPL :- +; 721: LDX ESP + LDX ESP +; 722: LDA #$FF + LDA #$FF +; 723: STA ESTKL,X + STA ESTKL,X +; 724: LDA #$01 + LDA #$01 +; 725: STA ESTKH,X + STA ESTKH,X +; 726: end + RTS +; 727: ; +; 728: ; EXIT +; 729: ; +; 730: asm exit +C0023: ; exit() +; 731: JSR $BF00 + JSR $BF00 +; 732: DB $65 + DB $65 +; 733: DW EXITTBL + DW EXITTBL +; 734: EXITTBL: +EXITTBL: +; 735: DB 4 + DB 4 +; 736: DB 0 + DB 0 +; 737: end + RTS +; 738: ; +; 739: ; ProDOS routines +; 740: ; +; 741: def getpfx_11(path) +C0025: ; getpfx_11() + ; path = 2 +; 742: byte params[3] + ; params = 4 +; 743: +; 744: ^path = 0 + JSR INTERP + DB $58,$07,$01 ; ENTER 7,1 + DB $66,$02 ; LLW 2 + DB $00 ; ZERO + DB $70 ; SB +; 745: params.0 = 1 + DB $28,$04 ; LLA 4 + DB $2A,$01 ; CB 1 + DB $70 ; SB +; 746: params:1 = path + DB $28,$05 ; LLA 5 + DB $66,$02 ; LLW 2 + DB $72 ; SW +; 747: perr = syscall($C7, @params) + DB $2A,$C7 ; CB 199 + DB $28,$04 ; LLA 4 + DB $54,C0009 ; CALL C0009 + DB $78,D0088 ; SAB D0088 +; 748: return path + DB $66,$02 ; LLW 2 + DB $5A ; LEAVE +; 749: end +; 750: def setpfx_11(path) +C0027: ; setpfx_11() + ; path = 2 +; 751: byte params[3] + ; params = 4 +; 752: +; 753: params.0 = 1 + JSR INTERP + DB $58,$07,$01 ; ENTER 7,1 + DB $28,$04 ; LLA 4 + DB $2A,$01 ; CB 1 + DB $70 ; SB +; 754: params:1 = path + DB $28,$05 ; LLA 5 + DB $66,$02 ; LLW 2 + DB $72 ; SW +; 755: perr = syscall($C6, @params) + DB $2A,$C6 ; CB 198 + DB $28,$04 ; LLA 4 + DB $54,C0009 ; CALL C0009 + DB $78,D0088 ; SAB D0088 +; 756: return path + DB $66,$02 ; LLW 2 + DB $5A ; LEAVE +; 757: end +; 758: def open_21(path, buff) +C0029: ; open_21() + ; path = 2 + ; buff = 4 +; 759: byte params[6] + ; params = 6 +; 760: +; 761: params.0 = 3 + JSR INTERP + DB $58,$0C,$02 ; ENTER 12,2 + DB $28,$06 ; LLA 6 + DB $2A,$03 ; CB 3 + DB $70 ; SB +; 762: params:1 = path + DB $28,$07 ; LLA 7 + DB $66,$02 ; LLW 2 + DB $72 ; SW +; 763: params:3 = buff + DB $28,$09 ; LLA 9 + DB $66,$04 ; LLW 4 + DB $72 ; SW +; 764: params.5 = 0 + DB $28,$0B ; LLA 11 + DB $00 ; ZERO + DB $70 ; SB +; 765: perr = syscall($C8, @params) + DB $2A,$C8 ; CB 200 + DB $28,$06 ; LLA 6 + DB $54,C0009 ; CALL C0009 + DB $78,D0088 ; SAB D0088 +; 766: return params.5 + DB $28,$0B ; LLA 11 + DB $60 ; LB + DB $5A ; LEAVE +; 767: end +; 768: def close_11(refnum) +C0031: ; close_11() + ; refnum = 2 +; 769: byte params[2] + ; params = 4 +; 770: +; 771: params.0 = 1 + JSR INTERP + DB $58,$06,$01 ; ENTER 6,1 + DB $28,$04 ; LLA 4 + DB $2A,$01 ; CB 1 + DB $70 ; SB +; 772: params.1 = refnum + DB $28,$05 ; LLA 5 + DB $66,$02 ; LLW 2 + DB $70 ; SB +; 773: perr = syscall($CC, @params) + DB $2A,$CC ; CB 204 + DB $28,$04 ; LLA 4 + DB $54,C0009 ; CALL C0009 + DB $78,D0088 ; SAB D0088 +; 774: return perr + DB $68,D0088 ; LAB D0088 + DB $5A ; LEAVE +; 775: end +; 776: def read_31(refnum, buff, len) +C0033: ; read_31() + ; refnum = 2 + ; buff = 4 + ; len = 6 +; 777: byte params[8] + ; params = 8 +; 778: +; 779: params.0 = 4 + JSR INTERP + DB $58,$10,$03 ; ENTER 16,3 + DB $28,$08 ; LLA 8 + DB $2A,$04 ; CB 4 + DB $70 ; SB +; 780: params.1 = refnum + DB $28,$09 ; LLA 9 + DB $66,$02 ; LLW 2 + DB $70 ; SB +; 781: params:2 = buff + DB $28,$0A ; LLA 10 + DB $66,$04 ; LLW 4 + DB $72 ; SW +; 782: params:4 = len + DB $28,$0C ; LLA 12 + DB $66,$06 ; LLW 6 + DB $72 ; SW +; 783: params:6 = 0 + DB $28,$0E ; LLA 14 + DB $00 ; ZERO + DB $72 ; SW +; 784: perr = syscall($CA, @params) + DB $2A,$CA ; CB 202 + DB $28,$08 ; LLA 8 + DB $54,C0009 ; CALL C0009 + DB $78,D0088 ; SAB D0088 +; 785: return params:6 + DB $28,$0E ; LLA 14 + DB $62 ; LW + DB $5A ; LEAVE +; 786: end +; 787: def write_31(refnum, buff, len) +C0035: ; write_31() + ; refnum = 2 + ; buff = 4 + ; len = 6 +; 788: byte params[8] + ; params = 8 +; 789: +; 790: params.0 = 4 + JSR INTERP + DB $58,$10,$03 ; ENTER 16,3 + DB $28,$08 ; LLA 8 + DB $2A,$04 ; CB 4 + DB $70 ; SB +; 791: params.1 = refnum + DB $28,$09 ; LLA 9 + DB $66,$02 ; LLW 2 + DB $70 ; SB +; 792: params:2 = buff + DB $28,$0A ; LLA 10 + DB $66,$04 ; LLW 4 + DB $72 ; SW +; 793: params:4 = len + DB $28,$0C ; LLA 12 + DB $66,$06 ; LLW 6 + DB $72 ; SW +; 794: params:6 = 0 + DB $28,$0E ; LLA 14 + DB $00 ; ZERO + DB $72 ; SW +; 795: perr = syscall($CB, @params) + DB $2A,$CB ; CB 203 + DB $28,$08 ; LLA 8 + DB $54,C0009 ; CALL C0009 + DB $78,D0088 ; SAB D0088 +; 796: return params:6 + DB $28,$0E ; LLA 14 + DB $62 ; LW + DB $5A ; LEAVE +; 797: end +; 798: def create_41(path, access, type, aux) +C0037: ; create_41() + ; path = 2 + ; access = 4 + ; type = 6 + ; aux = 8 +; 799: byte params[12] + ; params = 10 +; 800: +; 801: params.0 = 7 + JSR INTERP + DB $58,$16,$04 ; ENTER 22,4 + DB $28,$0A ; LLA 10 + DB $2A,$07 ; CB 7 + DB $70 ; SB +; 802: params:1 = path + DB $28,$0B ; LLA 11 + DB $66,$02 ; LLW 2 + DB $72 ; SW +; 803: params.3 = access + DB $28,$0D ; LLA 13 + DB $66,$04 ; LLW 4 + DB $70 ; SB +; 804: params.4 = type + DB $28,$0E ; LLA 14 + DB $66,$06 ; LLW 6 + DB $70 ; SB +; 805: params:5 = aux + DB $28,$0F ; LLA 15 + DB $66,$08 ; LLW 8 + DB $72 ; SW +; 806: params.7 = $1 + DB $28,$11 ; LLA 17 + DB $2A,$01 ; CB 1 + DB $70 ; SB +; 807: params:8 = 0 + DB $28,$12 ; LLA 18 + DB $00 ; ZERO + DB $72 ; SW +; 808: params:10 = 0 + DB $28,$14 ; LLA 20 + DB $00 ; ZERO + DB $72 ; SW +; 809: perr = syscall($C0, @params) + DB $2A,$C0 ; CB 192 + DB $28,$0A ; LLA 10 + DB $54,C0009 ; CALL C0009 + DB $78,D0088 ; SAB D0088 +; 810: return perr + DB $68,D0088 ; LAB D0088 + DB $5A ; LEAVE +; 811: end +; 812: def destroy_11(path) +C0039: ; destroy_11() + ; path = 2 +; 813: byte params[12] + ; params = 4 +; 814: +; 815: params.0 = 1 + JSR INTERP + DB $58,$10,$01 ; ENTER 16,1 + DB $28,$04 ; LLA 4 + DB $2A,$01 ; CB 1 + DB $70 ; SB +; 816: params:1 = path + DB $28,$05 ; LLA 5 + DB $66,$02 ; LLW 2 + DB $72 ; SW +; 817: perr = syscall($C1, @params) + DB $2A,$C1 ; CB 193 + DB $28,$04 ; LLA 4 + DB $54,C0009 ; CALL C0009 + DB $78,D0088 ; SAB D0088 +; 818: return perr + DB $68,D0088 ; LAB D0088 + DB $5A ; LEAVE +; 819: end +; 820: def newline_31(refnum, emask, nlchar) +C0041: ; newline_31() + ; refnum = 2 + ; emask = 4 + ; nlchar = 6 +; 821: byte params[4] + ; params = 8 +; 822: +; 823: params.0 = 3 + JSR INTERP + DB $58,$0C,$03 ; ENTER 12,3 + DB $28,$08 ; LLA 8 + DB $2A,$03 ; CB 3 + DB $70 ; SB +; 824: params.1 = refnum + DB $28,$09 ; LLA 9 + DB $66,$02 ; LLW 2 + DB $70 ; SB +; 825: params.2 = emask + DB $28,$0A ; LLA 10 + DB $66,$04 ; LLW 4 + DB $70 ; SB +; 826: params.3 = nlchar + DB $28,$0B ; LLA 11 + DB $66,$06 ; LLW 6 + DB $70 ; SB +; 827: perr = syscall($C9, @params) + DB $2A,$C9 ; CB 201 + DB $28,$08 ; LLA 8 + DB $54,C0009 ; CALL C0009 + DB $78,D0088 ; SAB D0088 +; 828: return perr + DB $68,D0088 ; LAB D0088 + DB $5A ; LEAVE +; 829: end +; 830: +; 831: ;===================================== +; 832: ; +; 833: ; Editor +; 834: ; +; 835: ;===================================== +; 836: +; 837: def crout +C0043: ; crout() +; 838: cout($0D) + JSR INTERP + DB $2A,$0D ; CB 13 + DB $54,C0015 ; CALL C0015 +; 839: end + DB $5C ; RET +; 840: def bell +C0045: ; bell() +; 841: drop romcall(0, 0, 0, 0, $FBDD) + JSR INTERP + DB $00 ; ZERO + DB $00 ; ZERO + DB $00 ; ZERO + DB $00 ; ZERO + DB $2C,$DD,$FB ; CW 64477 + DB $54,C0007 ; CALL C0007 + DB $30 ; DROP +; 842: end + DB $5C ; RET +; 843: ; +; 844: ; Memory management routines +; 845: ; +; 846: defopt strcpy_20(srcstr, dststr) +C0047: ; strcpy_20() + ; srcstr = 2 + ; dststr = 4 +; 847: byte strlen + ; strlen = 6 +; 848: +; 849: strlen = ^srcstr + LDY #7 + LDA #2 + JSR ENTER + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR LB + LDY #$06 + LDA ESTKL,X + STA (FRMP),Y +; 850: while (srcstr).[strlen] == $8D or (srcstr).[strlen] == $A0 + INX +C0049: + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDA #$8D + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDA #$A0 + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + JSR LOR + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0050 +: +; 851: strlen = strlen - 1 + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR SUB + LDY #$06 + LDA ESTKL,X + STA (FRMP),Y +; 852: loop + INX + JMP C0049 +C0050: +; 853: ^dststr = strlen + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SB +; 854: memcpy(srcstr + 1, dststr + 1, strlen) + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR C0013 +; 855: end + JMP LEAVE +; 856: defopt heapaddr_21(ofst, mask) +C0051: ; heapaddr_21() + ; ofst = 2 + ; mask = 4 +; 857: word addr + ; addr = 6 +; 858: +; 859: addr = (ofst << 7) + strheap + LDY #8 + LDA #2 + JSR ENTER + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$07 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SHL + DEX + STY ESTKL,X + LDA #$70 + STA ESTKH,X + JSR ADD + LDY #$06 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 860: while !(mask & 1) + INX +C0053: + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR BAND + JSR NOT + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0054 +: +; 861: addr = addr + 16 + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$10 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + LDY #$06 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 862: mask = mask >> 1 + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SHR + LDY #$04 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 863: loop + INX + JMP C0053 +C0054: +; 864: return addr + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JMP LEAVE +; 865: end +; 866: defopt sizemask_11(size) +C0055: ; sizemask_11() + ; size = 2 +; 867: if size <= 16 + LDY #4 + LDA #1 + JSR ENTER + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$10 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ISLE + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0057 +: +; 868: return $01 + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JMP LEAVE +; 869: elsif size <= 32 + JMP C0058 +C0057: + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$20 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ISLE + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0059 +: +; 870: return $03 + DEX + LDA #$03 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JMP LEAVE +; 871: elsif size <= 48 + JMP C0058 +C0059: + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$30 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ISLE + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0060 +: +; 872: return $07 + DEX + LDA #$07 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JMP LEAVE +; 873: elsif size <= 64 + JMP C0058 +C0060: + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$40 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ISLE + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0061 +: +; 874: return $0F + DEX + LDA #$0F + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JMP LEAVE +; 875: elsif size <= 80 + JMP C0058 +C0061: + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$50 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ISLE + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0062 +: +; 876: return $1F + DEX + LDA #$1F + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JMP LEAVE +; 877: fin +C0062: +C0058: +; 878: return 0 + DEX + LDY #$00 + STY ESTKL,X + STY ESTKH,X + JMP LEAVE +; 879: end +; 880: defopt heapalloc_11(size) +C0063: ; heapalloc_11() + ; size = 2 +; 881: byte szmask, i + ; szmask = 4 + ; i = 5 +; 882: word mapmask + ; mapmask = 6 +; 883: +; 884: szmask = sizemask_11(size) + LDY #8 + LDA #1 + JSR ENTER + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JSR C0055 + LDY #$04 + LDA ESTKL,X + STA (FRMP),Y +; 885: for i = strheapmsz - 1 downto 0 + LDA #$70 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR SUB +C0066: + LDY #$05 + LDA ESTKL,X + STA (FRMP),Y + DEX + LDY #$00 + STY ESTKL,X + STY ESTKH,X + INX + LDA ESTKL,X + CMP ESTKL-1,X + LDA ESTKH,X + SBC ESTKH-1,X + BPL :+ + JMP C0065 +: + LDA ESTKL,X + BNE :+ + DEC ESTKH,X +: DEC ESTKL,X +; 886: if strheapmap.[i] <> $FF + DEX + STY ESTKL,X + LDA #$15 + STA ESTKH,X + DEX + LDY #$05 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDA #$FF + STA ESTKL,X + STY ESTKH,X + JSR ISNE + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0067 +: +; 887: mapmask = szmask + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDY #$06 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 888: repeat + INX +C0070: +; 889: if strheapmap.[i] & mapmask + DEX + LDY #$00 + STY ESTKL,X + LDA #$15 + STA ESTKH,X + DEX + LDY #$05 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JSR BAND + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0071 +: +; 890: mapmask = mapmask << 1 + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SHL + LDY #$06 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 891: else + INX + JMP C0072 +C0071: +; 892: strheapmap.[i] = strheapmap.[i] ? mapmask + DEX + LDY #$00 + STY ESTKL,X + LDA #$15 + STA ESTKH,X + DEX + LDY #$05 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + DEX + STY ESTKL,X + LDA #$15 + STA ESTKH,X + DEX + LDY #$05 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JSR IOR + LDY #$00 + JSR SB +; 893: return heapaddr_21(i, mapmask) + LDY #$05 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JSR C0051 + JMP LEAVE +; 894: fin +C0072: +; 895: until mapmask & $100 + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$00 + STY ESTKL,X + LDA #$01 + STA ESTKH,X + JSR BAND + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0070 +: +C0069: +; 896: fin +C0067: +C0068: +; 897: next + JMP C0066 +C0065: +; 898: bell() + INX + JSR C0045 +; 899: prstr(@outofmem) + DEX + LDA #D0089 + STA ESTKH,X + JSR C0019 +; 900: return 0 + DEX + LDY #$00 + STY ESTKL,X + STY ESTKH,X + JMP LEAVE +; 901: end +; 902: def freestr_10(strptr) +C0073: ; freestr_10() + ; strptr = 2 +; 903: byte mask, ofst + ; mask = 4 + ; ofst = 5 +; 904: +; 905: if strptr and strptr <> @nullstr + JSR INTERP + DB $58,$06,$01 ; ENTER 6,1 + DB $66,$02 ; LLW 2 + DB $66,$02 ; LLW 2 + DB $26,D0048 ; LA D0048 + DB $42 ; ISNE + DB $24 ; LAND + DB $4C,C0075 ; SKPFLS C0075 +; 906: mask = sizemask_11(^strptr + 1) + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $54,C0055 ; CALL C0055 + DB $74,$04 ; SLB 4 +; 907: ofst = (strptr - strheap) >> 4 + DB $66,$02 ; LLW 2 + DB $2C,$00,$70 ; CW 28672 + DB $04 ; SUB + DB $2A,$04 ; CB 4 + DB $1C ; SHR + DB $74,$05 ; SLB 5 +; 908: mask = mask << (ofst & $07) + DB $64,$04 ; LLB 4 + DB $64,$05 ; LLB 5 + DB $2A,$07 ; CB 7 + DB $14 ; BAND + DB $1A ; SHL + DB $74,$04 ; SLB 4 +; 909: ofst = ofst >> 3 + DB $64,$05 ; LLB 5 + DB $2A,$03 ; CB 3 + DB $1C ; SHR + DB $74,$05 ; SLB 5 +; 910: strheapmap.[ofst] = strheapmap.[ofst] & #mask + DB $2C,$00,$15 ; CW 5376 + DB $64,$05 ; LLB 5 + DB $02 ; IDXB + DB $2C,$00,$15 ; CW 5376 + DB $64,$05 ; LLB 5 + DB $02 ; IDXB + DB $60 ; LB + DB $64,$04 ; LLB 4 + DB $12 ; COMP + DB $14 ; BAND + DB $70 ; SB +; 911: fin +C0075: +C0076: +; 912: end + DB $5A ; LEAVE +; 913: def newstr_11(strptr) +C0077: ; newstr_11() + ; strptr = 2 +; 914: byte strlen + ; strlen = 4 +; 915: word newptr + ; newptr = 5 +; 916: +; 917: strlen = ^strptr + JSR INTERP + DB $58,$07,$01 ; ENTER 7,1 + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $74,$04 ; SLB 4 +; 918: while (strptr).[strlen] == $8D or (strptr).[strlen] == $A0 +C0079: + DB $66,$02 ; LLW 2 + DB $64,$04 ; LLB 4 + DB $02 ; IDXB + DB $60 ; LB + DB $2A,$8D ; CB 141 + DB $40 ; ISEQ + DB $66,$02 ; LLW 2 + DB $64,$04 ; LLB 4 + DB $02 ; IDXB + DB $60 ; LB + DB $2A,$A0 ; CB 160 + DB $40 ; ISEQ + DB $22 ; LOR + DB $4C,C0080 ; SKPFLS C0080 +; 919: strlen = strlen - 1 + DB $64,$04 ; LLB 4 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $74,$04 ; SLB 4 +; 920: loop + DB $50,C0079 ; SKIP C0079 +C0080: +; 921: if strlen == 0 + DB $64,$04 ; LLB 4 + DB $00 ; ZERO + DB $40 ; ISEQ + DB $4C,C0081 ; SKPFLS C0081 +; 922: return @nullstr + DB $26,D0048 ; LA D0048 + DB $5A ; LEAVE +; 923: fin +C0081: +C0082: +; 924: newptr = heapalloc_11(strlen + 1) + DB $64,$04 ; LLB 4 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $54,C0063 ; CALL C0063 + DB $76,$05 ; SLW 5 +; 925: if newptr + DB $66,$05 ; LLW 5 + DB $4C,C0083 ; SKPFLS C0083 +; 926: memcpy(strptr, newptr, strlen + 1) + DB $66,$02 ; LLW 2 + DB $66,$05 ; LLW 5 + DB $64,$04 ; LLB 4 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $54,C0013 ; CALL C0013 +; 927: ^newptr = strlen + DB $66,$05 ; LLW 5 + DB $64,$04 ; LLB 4 + DB $70 ; SB +; 928: return newptr + DB $66,$05 ; LLW 5 + DB $5A ; LEAVE +; 929: fin +C0083: +C0084: +; 930: return @nullstr + DB $26,D0048 ; LA D0048 + DB $5A ; LEAVE +; 931: end +; 932: def inittxtbuf +C0085: ; inittxtbuf() +; 933: word i + ; i = 2 +; 934: +; 935: memset(0, strheapmap, strheapmsz) + JSR INTERP + DB $58,$04,$00 ; ENTER 4,0 + DB $00 ; ZERO + DB $2C,$00,$15 ; CW 5376 + DB $2A,$70 ; CB 112 + DB $54,C0011 ; CALL C0011 +; 936: memset(@nullstr, strlinbuf, maxfill * 2) + DB $26,D0048 ; LA D0048 + DB $2C,$00,$10 ; CW 4096 + DB $2C,$80,$02 ; CW 640 + DB $2A,$02 ; CB 2 + DB $06 ; MUL + DB $54,C0011 ; CALL C0011 +; 937: entrypoint = 0 + DB $00 ; ZERO + DB $7A,D0492 ; SAW D0492 +; 938: numlines = 0 + DB $00 ; ZERO + DB $7A,D0206 ; SAW D0206 +; 939: cursrow = 0 + DB $00 ; ZERO + DB $7A,D0200 ; SAW D0200 +; 940: curscol = 0 + DB $00 ; ZERO + DB $78,D0197 ; SAB D0197 +; 941: cursx = 0 + DB $00 ; ZERO + DB $78,D0194 ; SAB D0194 +; 942: cursy = 0 + DB $00 ; ZERO + DB $78,D0195 ; SAB D0195 +; 943: scrnleft = 0 + DB $00 ; ZERO + DB $78,D0196 ; SAB D0196 +; 944: scrntop = 0 + DB $00 ; ZERO + DB $7A,D0202 ; SAW D0202 +; 945: cutbuf = 0 + DB $00 ; ZERO + DB $7A,D0208 ; SAW D0208 +; 946: end + DB $5A ; LEAVE +; 947: ; +; 948: ; Case conversion/printing routines +; 949: ; +; 950: def caseconv_11(chr) +C0087: ; caseconv_11() + ; chr = 2 +; 951: if flags & uppercase + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $68,D0192 ; LAB D0192 + DB $2A,$08 ; CB 8 + DB $14 ; BAND + DB $4C,C0089 ; SKPFLS C0089 +; 952: if chr & $E0 == $E0 + DB $66,$02 ; LLW 2 + DB $2A,$E0 ; CB 224 + DB $14 ; BAND + DB $2A,$E0 ; CB 224 + DB $40 ; ISEQ + DB $4C,C0091 ; SKPFLS C0091 +; 953: chr = chr - $E0 + DB $66,$02 ; LLW 2 + DB $2A,$E0 ; CB 224 + DB $04 ; SUB + DB $76,$02 ; SLW 2 +; 954: fin +C0091: +C0092: +; 955: fin +C0089: +C0090: +; 956: return chr + DB $66,$02 ; LLW 2 + DB $5A ; LEAVE +; 957: end +; 958: def strupper_10(strptr) +C0093: ; strupper_10() + ; strptr = 2 +; 959: byte i, chr + ; i = 4 + ; chr = 5 +; 960: +; 961: for i = ^strptr downto 1 + JSR INTERP + DB $58,$06,$01 ; ENTER 6,1 + DB $66,$02 ; LLW 2 + DB $60 ; LB +C0096: + DB $6C,$04 ; DLB 4 + DB $2A,$01 ; CB 1 + DB $38,C0095 ; SKPLT C0095 + DB $0E ; DECR +; 962: chr = (strptr).[i] + DB $66,$02 ; LLW 2 + DB $64,$04 ; LLB 4 + DB $02 ; IDXB + DB $60 ; LB + DB $74,$05 ; SLB 5 +; 963: if chr & $E0 == $E0 + DB $64,$05 ; LLB 5 + DB $2A,$E0 ; CB 224 + DB $14 ; BAND + DB $2A,$E0 ; CB 224 + DB $40 ; ISEQ + DB $4C,C0097 ; SKPFLS C0097 +; 964: (strptr).[i] = chr - $E0 + DB $66,$02 ; LLW 2 + DB $64,$04 ; LLB 4 + DB $02 ; IDXB + DB $64,$05 ; LLB 5 + DB $2A,$E0 ; CB 224 + DB $04 ; SUB + DB $70 ; SB +; 965: fin +C0097: +C0098: +; 966: next + DB $50,C0096 ; SKIP C0096 +C0095: + DB $30 ; DROP +; 967: end + DB $5A ; LEAVE +; 968: def strlower_10(strptr) +C0099: ; strlower_10() + ; strptr = 2 +; 969: byte i, chr + ; i = 4 + ; chr = 5 +; 970: +; 971: for i = ^strptr downto 1 + JSR INTERP + DB $58,$06,$01 ; ENTER 6,1 + DB $66,$02 ; LLW 2 + DB $60 ; LB +C0102: + DB $6C,$04 ; DLB 4 + DB $2A,$01 ; CB 1 + DB $38,C0101 ; SKPLT C0101 + DB $0E ; DECR +; 972: chr = (strptr).[i] + DB $66,$02 ; LLW 2 + DB $64,$04 ; LLB 4 + DB $02 ; IDXB + DB $60 ; LB + DB $74,$05 ; SLB 5 +; 973: if chr & $E0 == $00 + DB $64,$05 ; LLB 5 + DB $2A,$E0 ; CB 224 + DB $14 ; BAND + DB $00 ; ZERO + DB $40 ; ISEQ + DB $4C,C0103 ; SKPFLS C0103 +; 974: (strptr).[i] = chr + $E0 + DB $66,$02 ; LLW 2 + DB $64,$04 ; LLB 4 + DB $02 ; IDXB + DB $64,$05 ; LLB 5 + DB $2A,$E0 ; CB 224 + DB $02 ; ADD + DB $70 ; SB +; 975: fin +C0103: +C0104: +; 976: next + DB $50,C0102 ; SKIP C0102 +C0101: + DB $30 ; DROP +; 977: end + DB $5A ; LEAVE +; 978: def txtupper +C0105: ; txtupper() +; 979: word i, strptr + ; i = 2 + ; strptr = 4 +; 980: +; 981: flags = flags ? uppercase + JSR INTERP + DB $58,$06,$00 ; ENTER 6,0 + DB $68,D0192 ; LAB D0192 + DB $2A,$08 ; CB 8 + DB $16 ; IOR + DB $78,D0192 ; SAB D0192 +; 982: for i = numlines - 1 downto 0 + DB $6A,D0206 ; LAW D0206 + DB $2A,$01 ; CB 1 + DB $04 ; SUB +C0108: + DB $6E,$02 ; DLW 2 + DB $00 ; ZERO + DB $38,C0107 ; SKPLT C0107 + DB $0E ; DECR +; 983: strupper_10(strlinbuf:[i]) + DB $2C,$00,$10 ; CW 4096 + DB $66,$02 ; LLW 2 + DB $1E ; IDXW + DB $62 ; LW + DB $54,C0093 ; CALL C0093 +; 984: next + DB $50,C0108 ; SKIP C0108 +C0107: + DB $30 ; DROP +; 985: end + DB $5A ; LEAVE +; 986: def txtlower +C0109: ; txtlower() +; 987: word i, strptr + ; i = 2 + ; strptr = 4 +; 988: +; 989: flags = flags & #uppercase + JSR INTERP + DB $58,$06,$00 ; ENTER 6,0 + DB $68,D0192 ; LAB D0192 + DB $2C,$F7,$FF ; CW -9 + DB $14 ; BAND + DB $78,D0192 ; SAB D0192 +; 990: for i = numlines - 1 downto 0 + DB $6A,D0206 ; LAW D0206 + DB $2A,$01 ; CB 1 + DB $04 ; SUB +C0112: + DB $6E,$02 ; DLW 2 + DB $00 ; ZERO + DB $38,C0111 ; SKPLT C0111 + DB $0E ; DECR +; 991: strlower_10(strlinbuf:[i]) + DB $2C,$00,$10 ; CW 4096 + DB $66,$02 ; LLW 2 + DB $1E ; IDXW + DB $62 ; LW + DB $54,C0099 ; CALL C0099 +; 992: next + DB $50,C0112 ; SKIP C0112 +C0111: + DB $30 ; DROP +; 993: end + DB $5A ; LEAVE +; 994: def prbyte_10(h) +C0113: ; prbyte_10() + ; h = 2 +; 995: cout('$') + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$24 ; CB 36 + DB $54,C0015 ; CALL C0015 +; 996: drop romcall(h, 0, 0, 0, $FDDA) + DB $66,$02 ; LLW 2 + DB $00 ; ZERO + DB $00 ; ZERO + DB $00 ; ZERO + DB $2C,$DA,$FD ; CW 64986 + DB $54,C0007 ; CALL C0007 + DB $30 ; DROP +; 997: end + DB $5A ; LEAVE +; 998: def prword_10(h) +C0115: ; prword_10() + ; h = 2 +; 999: cout('$') + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$24 ; CB 36 + DB $54,C0015 ; CALL C0015 +; 1000: drop romcall(h >> 8, h, 0, 0, $F941) + DB $66,$02 ; LLW 2 + DB $2A,$08 ; CB 8 + DB $1C ; SHR + DB $66,$02 ; LLW 2 + DB $00 ; ZERO + DB $00 ; ZERO + DB $2C,$41,$F9 ; CW 63809 + DB $54,C0007 ; CALL C0007 + DB $30 ; DROP +; 1001: end + DB $5A ; LEAVE +; 1002: def print_10(i) +C0117: ; print_10() + ; i = 2 +; 1003: byte numstr[7] + ; numstr = 4 +; 1004: byte place, sign + ; place = 11 + ; sign = 12 +; 1005: +; 1006: place = 6 + JSR INTERP + DB $58,$0D,$01 ; ENTER 13,1 + DB $2A,$06 ; CB 6 + DB $74,$0B ; SLB 11 +; 1007: if i < 0 + DB $66,$02 ; LLW 2 + DB $00 ; ZERO + DB $46 ; ISLT + DB $4C,C0119 ; SKPFLS C0119 +; 1008: sign = 1 + DB $2A,$01 ; CB 1 + DB $74,$0C ; SLB 12 +; 1009: i = -i + DB $66,$02 ; LLW 2 + DB $10 ; NEG + DB $76,$02 ; SLW 2 +; 1010: else + DB $50,C0120 ; SKIP C0120 +C0119: +; 1011: sign = 0 + DB $00 ; ZERO + DB $74,$0C ; SLB 12 +; 1012: fin +C0120: +; 1013: while i >= 10 +C0121: + DB $66,$02 ; LLW 2 + DB $2A,$0A ; CB 10 + DB $48 ; ISGE + DB $4C,C0122 ; SKPFLS C0122 +; 1014: i =, numstr[place] = i % 10 + '0' + DB $28,$04 ; LLA 4 + DB $64,$0B ; LLB 11 + DB $02 ; IDXB + DB $34 ; PUSH + DB $66,$02 ; LLW 2 + DB $2A,$0A ; CB 10 + DB $0A ; DIV,MOD + DB $2A,$30 ; CB 48 + DB $02 ; ADD + DB $36 ; PULL + DB $2E ; SWAP + DB $70 ; SB + DB $76,$02 ; SLW 2 +; 1015: place = place - 1 + DB $64,$0B ; LLB 11 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $74,$0B ; SLB 11 +; 1016: loop + DB $50,C0121 ; SKIP C0121 +C0122: +; 1017: numstr[place] = i + '0' + DB $28,$04 ; LLA 4 + DB $64,$0B ; LLB 11 + DB $02 ; IDXB + DB $66,$02 ; LLW 2 + DB $2A,$30 ; CB 48 + DB $02 ; ADD + DB $70 ; SB +; 1018: place = place - 1 + DB $64,$0B ; LLB 11 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $74,$0B ; SLB 11 +; 1019: if sign + DB $64,$0C ; LLB 12 + DB $4C,C0123 ; SKPFLS C0123 +; 1020: numstr[place] = '-' + DB $28,$04 ; LLA 4 + DB $64,$0B ; LLB 11 + DB $02 ; IDXB + DB $2A,$2D ; CB 45 + DB $70 ; SB +; 1021: place = place - 1 + DB $64,$0B ; LLB 11 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $74,$0B ; SLB 11 +; 1022: fin +C0123: +C0124: +; 1023: numstr[place] = 6 - place + DB $28,$04 ; LLA 4 + DB $64,$0B ; LLB 11 + DB $02 ; IDXB + DB $2A,$06 ; CB 6 + DB $64,$0B ; LLB 11 + DB $04 ; SUB + DB $70 ; SB +; 1024: prstr(@numstr[place]) + DB $28,$04 ; LLA 4 + DB $64,$0B ; LLB 11 + DB $02 ; IDXB + DB $54,C0019 ; CALL C0019 +; 1025: end + DB $5A ; LEAVE +; 1026: def nametostr_30(namestr, len, strptr) +C0125: ; nametostr_30() + ; namestr = 2 + ; len = 4 + ; strptr = 6 +; 1027: ^strptr = len + JSR INTERP + DB $58,$08,$03 ; ENTER 8,3 + DB $66,$06 ; LLW 6 + DB $66,$04 ; LLW 4 + DB $70 ; SB +; 1028: memcpy(namestr, strptr + 1, len) + DB $66,$02 ; LLW 2 + DB $66,$06 ; LLW 6 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $66,$04 ; LLW 4 + DB $54,C0013 ; CALL C0013 +; 1029: end + DB $5A ; LEAVE +; 1030: ;def toupper_11(c) +; 1031: ; if c >= 'a' +; 1032: ; if c <= 'z' +; 1033: ; return c - $20 +; 1034: ; fin +; 1035: ; fin +; 1036: ; return c +; 1037: ;end +; 1038: asm toupper_11 +C0127: ; toupper_11() +; 1039: LDA ESTKL,X + LDA ESTKL,X +; 1040: AND #$7F + AND #$7F +; 1041: CMP #'a' + CMP #'a' +; 1042: BCC :+ + BCC :+ +; 1043: CMP #'z'+1 + CMP #'z'+1 +; 1044: BCS :+ + BCS :+ +; 1045: SEC + SEC +; 1046: SBC #$20 + SBC #$20 +; 1047: : STA ESTKL,X +: STA ESTKL,X +; 1048: end + RTS +; 1049: asm clrhibit_10(strptr) +C0129: ; clrhibit_10() + ; strptr = 2 +; 1050: LDY #$02 ; strptr + LDY #4 + LDA #1 + JSR ENTER + LDY #$02 ; strptr +; 1051: LDA (FRMP),Y + LDA (FRMP),Y +; 1052: STA SRCL + STA SRCL +; 1053: INY + INY +; 1054: LDA (FRMP),Y + LDA (FRMP),Y +; 1055: STA SRCH + STA SRCH +; 1056: LDY #$00 + LDY #$00 +; 1057: LDA (SRC),Y + LDA (SRC),Y +; 1058: BEQ :+ + BEQ :+ +; 1059: TAY + TAY +; 1060: CLHILP: LDA (SRC),Y +CLHILP: LDA (SRC),Y +; 1061: AND #$7F + AND #$7F +; 1062: STA (SRC),Y + STA (SRC),Y +; 1063: DEY + DEY +; 1064: BNE CLHILP + BNE CLHILP +; 1065: : +: +; 1066: end + JMP LEAVE +; 1067: asm sethibit_10(strptr) +C0131: ; sethibit_10() + ; strptr = 2 +; 1068: LDY #$02 ; strptr + LDY #4 + LDA #1 + JSR ENTER + LDY #$02 ; strptr +; 1069: LDA (FRMP),Y + LDA (FRMP),Y +; 1070: STA SRCL + STA SRCL +; 1071: INY + INY +; 1072: LDA (FRMP),Y + LDA (FRMP),Y +; 1073: STA SRCH + STA SRCH +; 1074: LDY #$00 + LDY #$00 +; 1075: LDA (SRC),Y + LDA (SRC),Y +; 1076: BEQ :+ + BEQ :+ +; 1077: TAY + TAY +; 1078: STHILP: LDA (SRC),Y +STHILP: LDA (SRC),Y +; 1079: ORA #$80 + ORA #$80 +; 1080: STA (SRC),Y + STA (SRC),Y +; 1081: DEY + DEY +; 1082: BNE STHILP + BNE STHILP +; 1083: : +: +; 1084: end + JMP LEAVE +; 1085: asm cpyln_20(srcstr, dststr) +C0133: ; cpyln_20() + ; srcstr = 2 + ; dststr = 4 +; 1086: LDY #$02 ; srcstr + LDY #6 + LDA #2 + JSR ENTER + LDY #$02 ; srcstr +; 1087: LDA (FRMP),Y + LDA (FRMP),Y +; 1088: STA SRCL + STA SRCL +; 1089: INY + INY +; 1090: LDA (FRMP),Y + LDA (FRMP),Y +; 1091: STA SRCH + STA SRCH +; 1092: INY ; dststr + INY ; dststr +; 1093: LDA (FRMP),Y + LDA (FRMP),Y +; 1094: STA DSTL + STA DSTL +; 1095: INY + INY +; 1096: LDA (FRMP),Y + LDA (FRMP),Y +; 1097: STA DSTH + STA DSTH +; 1098: LDY #$00 + LDY #$00 +; 1099: LDA (SRC),Y + LDA (SRC),Y +; 1100: TAY + TAY +; 1101: LDA #$00 + LDA #$00 +; 1102: INY + INY +; 1103: STA (DST),Y + STA (DST),Y +; 1104: DEY + DEY +; 1105: BEQ :++ + BEQ :++ +; 1106: CPLNLP: LDA (SRC),Y +CPLNLP: LDA (SRC),Y +; 1107: CMP #$20 + CMP #$20 +; 1108: BCS :+ + BCS :+ +; 1109: ADC #$60 + ADC #$60 +; 1110: : AND #$7F +: AND #$7F +; 1111: STA (DST),Y + STA (DST),Y +; 1112: DEY + DEY +; 1113: BNE CPLNLP + BNE CPLNLP +; 1114: LDA (SRC),Y + LDA (SRC),Y +; 1115: : STA (DST),Y +: STA (DST),Y +; 1116: end + JMP LEAVE +; 1117: ; +; 1118: ; File routines +; 1119: ; +; 1120: def readtxt_10(filename) +C0135: ; readtxt_10() + ; filename = 2 +; 1121: byte txtbuf[81], refnum, i, j + ; txtbuf = 4 + ; refnum = 85 + ; i = 86 + ; j = 87 +; 1122: +; 1123: refnum = open_21(filename, iobuffer) + JSR INTERP + DB $58,$58,$01 ; ENTER 88,1 + DB $66,$02 ; LLW 2 + DB $2C,$00,$08 ; CW 2048 + DB $54,C0029 ; CALL C0029 + DB $74,$55 ; SLB 85 +; 1124: if refnum + DB $64,$55 ; LLB 85 + DB $4C,C0137 ; SKPFLS C0137 +; 1125: drop newline_31(refnum, $7F, $0D) + DB $64,$55 ; LLB 85 + DB $2A,$7F ; CB 127 + DB $2A,$0D ; CB 13 + DB $54,C0041 ; CALL C0041 + DB $30 ; DROP +; 1126: repeat +C0140: +; 1127: txtbuf = read_31(refnum, @txtbuf + 1, maxlnlen) + DB $64,$55 ; LLB 85 + DB $28,$04 ; LLA 4 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $2A,$4F ; CB 79 + DB $54,C0033 ; CALL C0033 + DB $74,$04 ; SLB 4 +; 1128: if txtbuf + DB $64,$04 ; LLB 4 + DB $4C,C0141 ; SKPFLS C0141 +; 1129: sethibit_10(@txtbuf) + DB $28,$04 ; LLA 4 + DB $54,C0131 ; CALL C0131 +; 1130: if flags & uppercase + DB $68,D0192 ; LAB D0192 + DB $2A,$08 ; CB 8 + DB $14 ; BAND + DB $4C,C0143 ; SKPFLS C0143 +; 1131: strupper_10(@txtbuf) + DB $28,$04 ; LLA 4 + DB $54,C0093 ; CALL C0093 +; 1132: fin +C0143: +C0144: +; 1133: strlinbuf:[numlines] = newstr_11(@txtbuf) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0206 ; LAW D0206 + DB $1E ; IDXW + DB $28,$04 ; LLA 4 + DB $54,C0077 ; CALL C0077 + DB $72 ; SW +; 1134: numlines = numlines + 1 + DB $6A,D0206 ; LAW D0206 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $7A,D0206 ; SAW D0206 +; 1135: fin +C0141: +C0142: +; 1136: if !(numlines & $0F) + DB $6A,D0206 ; LAW D0206 + DB $2A,$0F ; CB 15 + DB $14 ; BAND + DB $20 ; NOT + DB $4C,C0145 ; SKPFLS C0145 +; 1137: cout('.') + DB $2A,$2E ; CB 46 + DB $54,C0015 ; CALL C0015 +; 1138: fin +C0145: +C0146: +; 1139: until txtbuf == 0 or numlines == maxlines + DB $64,$04 ; LLB 4 + DB $00 ; ZERO + DB $40 ; ISEQ + DB $6A,D0206 ; LAW D0206 + DB $2C,$72,$02 ; CW 626 + DB $40 ; ISEQ + DB $22 ; LOR + DB $4C,C0140 ; SKPFLS C0140 +C0139: +; 1140: drop close_11(refnum) + DB $64,$55 ; LLB 85 + DB $54,C0031 ; CALL C0031 + DB $30 ; DROP +; 1141: fin +C0137: +C0138: +; 1142: if numlines == 0 + DB $6A,D0206 ; LAW D0206 + DB $00 ; ZERO + DB $40 ; ISEQ + DB $4C,C0147 ; SKPFLS C0147 +; 1143: numlines = 1 + DB $2A,$01 ; CB 1 + DB $7A,D0206 ; SAW D0206 +; 1144: fin +C0147: +C0148: +; 1145: end + DB $5A ; LEAVE +; 1146: def writetxt_10(filename) +C0149: ; writetxt_10() + ; filename = 2 +; 1147: byte txtbuf[81], refnum + ; txtbuf = 4 + ; refnum = 85 +; 1148: byte j, chr + ; j = 86 + ; chr = 87 +; 1149: word i, strptr + ; i = 88 + ; strptr = 90 +; 1150: +; 1151: drop destroy_11(filename) + JSR INTERP + DB $58,$5C,$01 ; ENTER 92,1 + DB $66,$02 ; LLW 2 + DB $54,C0039 ; CALL C0039 + DB $30 ; DROP +; 1152: drop create_41(filename, $C3, $04, $00) ; full access, TXT file + DB $66,$02 ; LLW 2 + DB $2A,$C3 ; CB 195 + DB $2A,$04 ; CB 4 + DB $00 ; ZERO + DB $54,C0037 ; CALL C0037 + DB $30 ; DROP +; 1153: refnum = open_21(filename, iobuffer) + DB $66,$02 ; LLW 2 + DB $2C,$00,$08 ; CW 2048 + DB $54,C0029 ; CALL C0029 + DB $74,$55 ; SLB 85 +; 1154: if refnum == 0 + DB $64,$55 ; LLB 85 + DB $00 ; ZERO + DB $40 ; ISEQ + DB $4C,C0151 ; SKPFLS C0151 +; 1155: return + DB $5A ; LEAVE +; 1156: fin +C0151: +C0152: +; 1157: for i = 0 to numlines - 1 + DB $00 ; ZERO +C0154: + DB $6E,$58 ; DLW 88 + DB $6A,D0206 ; LAW D0206 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $3A,C0153 ; SKPGT C0153 + DB $0C ; INCR +; 1158: cpyln_20(strlinbuf:[i], @txtbuf) + DB $2C,$00,$10 ; CW 4096 + DB $66,$58 ; LLW 88 + DB $1E ; IDXW + DB $62 ; LW + DB $28,$04 ; LLA 4 + DB $54,C0133 ; CALL C0133 +; 1159: txtbuf = txtbuf + 1 + DB $64,$04 ; LLB 4 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $74,$04 ; SLB 4 +; 1160: txtbuf[txtbuf] = $0D + DB $28,$04 ; LLA 4 + DB $64,$04 ; LLB 4 + DB $02 ; IDXB + DB $2A,$0D ; CB 13 + DB $70 ; SB +; 1161: drop write_31(refnum, @txtbuf + 1, txtbuf) + DB $64,$55 ; LLB 85 + DB $28,$04 ; LLA 4 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $64,$04 ; LLB 4 + DB $54,C0035 ; CALL C0035 + DB $30 ; DROP +; 1162: if !(i & $0F) + DB $66,$58 ; LLW 88 + DB $2A,$0F ; CB 15 + DB $14 ; BAND + DB $20 ; NOT + DB $4C,C0155 ; SKPFLS C0155 +; 1163: cout('.') + DB $2A,$2E ; CB 46 + DB $54,C0015 ; CALL C0015 +; 1164: fin +C0155: +C0156: +; 1165: next + DB $50,C0154 ; SKIP C0154 +C0153: + DB $30 ; DROP +; 1166: drop close_11(refnum) + DB $64,$55 ; LLB 85 + DB $54,C0031 ; CALL C0031 + DB $30 ; DROP +; 1167: end + DB $5A ; LEAVE +; 1168: ; +; 1169: ; Screen routines +; 1170: ; +; 1171: def clrscrn +C0157: ; clrscrn() +; 1172: drop romcall(0, 0, 0, 0, $FC58) + JSR INTERP + DB $00 ; ZERO + DB $00 ; ZERO + DB $00 ; ZERO + DB $00 ; ZERO + DB $2C,$58,$FC ; CW 64600 + DB $54,C0007 ; CALL C0007 + DB $30 ; DROP +; 1173: end + DB $5C ; RET +; 1174: def drawrow_30(row, ofst, strptr) +C0159: ; drawrow_30() + ; row = 2 + ; ofst = 4 + ; strptr = 6 +; 1175: byte numchars + ; numchars = 8 +; 1176: word scrnptr + ; scrnptr = 9 +; 1177: +; 1178: scrnptr = txtscrn[row] + JSR INTERP + DB $58,$0B,$03 ; ENTER 11,3 + DB $26,D0000 ; LA D0000 + DB $66,$02 ; LLW 2 + DB $1E ; IDXW + DB $62 ; LW + DB $76,$09 ; SLW 9 +; 1179: if ^strptr <= ofst + DB $66,$06 ; LLW 6 + DB $60 ; LB + DB $66,$04 ; LLW 4 + DB $4A ; ISLE + DB $4C,C0161 ; SKPFLS C0161 +; 1180: numchars = 0 + DB $00 ; ZERO + DB $74,$08 ; SLB 8 +; 1181: else + DB $50,C0162 ; SKIP C0162 +C0161: +; 1182: numchars = ^strptr - ofst + DB $66,$06 ; LLW 6 + DB $60 ; LB + DB $66,$04 ; LLW 4 + DB $04 ; SUB + DB $74,$08 ; SLB 8 +; 1183: fin +C0162: +; 1184: if numchars >= 40 + DB $64,$08 ; LLB 8 + DB $2A,$28 ; CB 40 + DB $48 ; ISGE + DB $4C,C0163 ; SKPFLS C0163 +; 1185: numchars = 40 + DB $2A,$28 ; CB 40 + DB $74,$08 ; SLB 8 +; 1186: else + DB $50,C0164 ; SKIP C0164 +C0163: +; 1187: memset($A0A0, scrnptr + numchars, 40 - numchars) + DB $2C,$A0,$A0 ; CW 41120 + DB $66,$09 ; LLW 9 + DB $64,$08 ; LLB 8 + DB $02 ; ADD + DB $2A,$28 ; CB 40 + DB $64,$08 ; LLB 8 + DB $04 ; SUB + DB $54,C0011 ; CALL C0011 +; 1188: fin +C0164: +; 1189: memcpy(strptr + ofst + 1, scrnptr, numchars) + DB $66,$06 ; LLW 6 + DB $66,$04 ; LLW 4 + DB $02 ; ADD + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $66,$09 ; LLW 9 + DB $64,$08 ; LLB 8 + DB $54,C0013 ; CALL C0013 +; 1190: end + DB $5A ; LEAVE +; 1191: defopt drawscrn_20(toprow, ofst) +C0165: ; drawscrn_20() + ; toprow = 2 + ; ofst = 4 +; 1192: byte row, numchars + ; row = 6 + ; numchars = 7 +; 1193: word strptr, scrnptr + ; strptr = 8 + ; scrnptr = 10 +; 1194: +; 1195: for row = 0 to 23 + LDY #12 + LDA #2 + JSR ENTER + DEX + STY ESTKL,X + STY ESTKH,X +C0168: + LDY #$06 + LDA ESTKL,X + STA (FRMP),Y + DEX + LDA #$17 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + LDA ESTKH-1,X + SBC ESTKH,X + BPL :+ + JMP C0167 +: + INC ESTKL,X + BNE :+ + INC ESTKH,X +: +; 1196: strptr = strlinbuf:[toprow + row] + DEX + STY ESTKL,X + LDA #$10 + STA ESTKH,X + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR IDXW + JSR LW + LDY #$08 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 1197: scrnptr = txtscrn[row] + LDA #D0000 + STA ESTKH,X + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR IDXW + JSR LW + LDY #$0A + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 1198: if ^strptr <= ofst + LDY #$08 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR LB + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR ISLE + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0169 +: +; 1199: numchars = 0 + DEX + LDY #$00 + STY ESTKL,X + STY ESTKH,X + LDY #$07 + LDA ESTKL,X + STA (FRMP),Y +; 1200: else + INX + JMP C0170 +C0169: +; 1201: numchars = ^strptr - ofst + DEX + LDY #$08 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR LB + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JSR SUB + LDY #$07 + LDA ESTKL,X + STA (FRMP),Y +; 1202: fin + INX +C0170: +; 1203: if numchars >= 40 + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA #$28 + STA ESTKL,X + STY ESTKH,X + JSR ISGE + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0171 +: +; 1204: numchars = 40 + DEX + LDA #$28 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + LDY #$07 + LDA ESTKL,X + STA (FRMP),Y +; 1205: else + INX + JMP C0172 +C0171: +; 1206: memset($A0A0, scrnptr + numchars, 40 - numchars) + DEX + LDA #$A0 + STA ESTKL,X + STA ESTKH,X + DEX + LDY #$0A + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + DEX + LDA #$28 + STA ESTKL,X + STY ESTKH,X + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SUB + JSR C0011 +; 1207: fin +C0172: +; 1208: memcpy(strptr + ofst + 1, scrnptr, numchars) + DEX + LDY #$08 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JSR ADD + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + DEX + LDY #$0A + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR C0013 +; 1209: next + JMP C0168 +C0167: +; 1210: end + INX + JMP LEAVE +; 1211: def cursoff +C0173: ; cursoff() +; 1212: if flags & showcurs + JSR INTERP + DB $68,D0192 ; LAB D0192 + DB $2A,$04 ; CB 4 + DB $14 ; BAND + DB $4C,C0175 ; SKPFLS C0175 +; 1213: ^cursptr = underchr + DB $6A,D0204 ; LAW D0204 + DB $68,D0198 ; LAB D0198 + DB $70 ; SB +; 1214: flags = flags & #showcurs + DB $68,D0192 ; LAB D0192 + DB $2C,$FB,$FF ; CW -5 + DB $14 ; BAND + DB $78,D0192 ; SAB D0192 +; 1215: fin +C0175: +C0176: +; 1216: end + DB $5C ; RET +; 1217: def curson +C0177: ; curson() +; 1218: if !(flags & showcurs) + JSR INTERP + DB $68,D0192 ; LAB D0192 + DB $2A,$04 ; CB 4 + DB $14 ; BAND + DB $20 ; NOT + DB $4C,C0179 ; SKPFLS C0179 +; 1219: cursptr = txtscrn[cursy] + cursx + DB $26,D0000 ; LA D0000 + DB $68,D0195 ; LAB D0195 + DB $1E ; IDXW + DB $62 ; LW + DB $68,D0194 ; LAB D0194 + DB $02 ; ADD + DB $7A,D0204 ; SAW D0204 +; 1220: underchr = ^cursptr + DB $6A,D0204 ; LAW D0204 + DB $60 ; LB + DB $78,D0198 ; SAB D0198 +; 1221: ^cursptr = curschr + DB $6A,D0204 ; LAW D0204 + DB $68,D0199 ; LAB D0199 + DB $70 ; SB +; 1222: flags = flags ? showcurs + DB $68,D0192 ; LAB D0192 + DB $2A,$04 ; CB 4 + DB $16 ; IOR + DB $78,D0192 ; SAB D0192 +; 1223: fin +C0179: +C0180: +; 1224: end + DB $5C ; RET +; 1225: def cursflash() +C0181: ; cursflash() +; 1226: if flags & showcurs + JSR INTERP + DB $68,D0192 ; LAB D0192 + DB $2A,$04 ; CB 4 + DB $14 ; BAND + DB $4C,C0183 ; SKPFLS C0183 +; 1227: if flash == 0 + DB $68,D0193 ; LAB D0193 + DB $00 ; ZERO + DB $40 ; ISEQ + DB $4C,C0185 ; SKPFLS C0185 +; 1228: ^cursptr = curschr + DB $6A,D0204 ; LAW D0204 + DB $68,D0199 ; LAB D0199 + DB $70 ; SB +; 1229: elsif flash == 128 + DB $50,C0186 ; SKIP C0186 +C0185: + DB $68,D0193 ; LAB D0193 + DB $2A,$80 ; CB 128 + DB $40 ; ISEQ + DB $4C,C0187 ; SKPFLS C0187 +; 1230: ^cursptr = underchr + DB $6A,D0204 ; LAW D0204 + DB $68,D0198 ; LAB D0198 + DB $70 ; SB +; 1231: fin +C0187: +C0186: +; 1232: flash = flash + 1 + DB $68,D0193 ; LAB D0193 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $78,D0193 ; SAB D0193 +; 1233: fin +C0183: +C0184: +; 1234: end + DB $5C ; RET +; 1235: def redraw +C0188: ; redraw() +; 1236: cursoff() + JSR INTERP + DB $54,C0173 ; CALL C0173 +; 1237: drawscrn_20(scrntop, scrnleft) + DB $6A,D0202 ; LAW D0202 + DB $68,D0196 ; LAB D0196 + DB $54,C0165 ; CALL C0165 +; 1238: curson() + DB $54,C0177 ; CALL C0177 +; 1239: end + DB $5C ; RET +; 1240: def curshome +C0190: ; curshome() +; 1241: cursoff() + JSR INTERP + DB $54,C0173 ; CALL C0173 +; 1242: cursrow = 0 + DB $00 ; ZERO + DB $7A,D0200 ; SAW D0200 +; 1243: curscol = 0 + DB $00 ; ZERO + DB $78,D0197 ; SAB D0197 +; 1244: cursx = 0 + DB $00 ; ZERO + DB $78,D0194 ; SAB D0194 +; 1245: cursy = 0 + DB $00 ; ZERO + DB $78,D0195 ; SAB D0195 +; 1246: scrnleft = 0 + DB $00 ; ZERO + DB $78,D0196 ; SAB D0196 +; 1247: scrntop = 0 + DB $00 ; ZERO + DB $7A,D0202 ; SAW D0202 +; 1248: drawscrn_20(scrntop, scrnleft) + DB $6A,D0202 ; LAW D0202 + DB $68,D0196 ; LAB D0196 + DB $54,C0165 ; CALL C0165 +; 1249: curson() + DB $54,C0177 ; CALL C0177 +; 1250: end + DB $5C ; RET +; 1251: def cursend +C0192: ; cursend() +; 1252: cursoff() + JSR INTERP + DB $54,C0173 ; CALL C0173 +; 1253: if numlines > 23 + DB $6A,D0206 ; LAW D0206 + DB $2A,$17 ; CB 23 + DB $44 ; ISGT + DB $4C,C0194 ; SKPFLS C0194 +; 1254: cursrow = numlines - 1 + DB $6A,D0206 ; LAW D0206 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $7A,D0200 ; SAW D0200 +; 1255: cursy = 23 + DB $2A,$17 ; CB 23 + DB $78,D0195 ; SAB D0195 +; 1256: scrntop = cursrow - 23 + DB $6A,D0200 ; LAW D0200 + DB $2A,$17 ; CB 23 + DB $04 ; SUB + DB $7A,D0202 ; SAW D0202 +; 1257: else + DB $50,C0195 ; SKIP C0195 +C0194: +; 1258: cursrow = numlines - 1 + DB $6A,D0206 ; LAW D0206 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $7A,D0200 ; SAW D0200 +; 1259: cursy = numlines - 1 + DB $6A,D0206 ; LAW D0206 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $78,D0195 ; SAB D0195 +; 1260: scrntop = 0 + DB $00 ; ZERO + DB $7A,D0202 ; SAW D0202 +; 1261: fin +C0195: +; 1262: curscol = 0 + DB $00 ; ZERO + DB $78,D0197 ; SAB D0197 +; 1263: cursx = 0 + DB $00 ; ZERO + DB $78,D0194 ; SAB D0194 +; 1264: scrnleft = 0 + DB $00 ; ZERO + DB $78,D0196 ; SAB D0196 +; 1265: drawscrn_20(scrntop, scrnleft) + DB $6A,D0202 ; LAW D0202 + DB $68,D0196 ; LAB D0196 + DB $54,C0165 ; CALL C0165 +; 1266: curson() + DB $54,C0177 ; CALL C0177 +; 1267: end + DB $5C ; RET +; 1268: def cursup +C0196: ; cursup() +; 1269: if cursrow > 0 + JSR INTERP + DB $6A,D0200 ; LAW D0200 + DB $00 ; ZERO + DB $44 ; ISGT + DB $4C,C0198 ; SKPFLS C0198 +; 1270: cursoff() + DB $54,C0173 ; CALL C0173 +; 1271: cursrow = cursrow - 1 + DB $6A,D0200 ; LAW D0200 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $7A,D0200 ; SAW D0200 +; 1272: if cursy > 0 + DB $68,D0195 ; LAB D0195 + DB $00 ; ZERO + DB $44 ; ISGT + DB $4C,C0200 ; SKPFLS C0200 +; 1273: cursy = cursy - 1 + DB $68,D0195 ; LAB D0195 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $78,D0195 ; SAB D0195 +; 1274: else + DB $50,C0201 ; SKIP C0201 +C0200: +; 1275: scrntop = cursrow + DB $6A,D0200 ; LAW D0200 + DB $7A,D0202 ; SAW D0202 +; 1276: drawscrn_20(scrntop, scrnleft) + DB $6A,D0202 ; LAW D0202 + DB $68,D0196 ; LAB D0196 + DB $54,C0165 ; CALL C0165 +; 1277: fin +C0201: +; 1278: curson() + DB $54,C0177 ; CALL C0177 +; 1279: fin +C0198: +C0199: +; 1280: end + DB $5C ; RET +; 1281: def pgup +C0202: ; pgup() +; 1282: byte i + ; i = 2 +; 1283: +; 1284: for i = pgjmp downto 0 + JSR INTERP + DB $58,$03,$00 ; ENTER 3,0 + DB $2A,$10 ; CB 16 +C0205: + DB $6C,$02 ; DLB 2 + DB $00 ; ZERO + DB $38,C0204 ; SKPLT C0204 + DB $0E ; DECR +; 1285: cursup() + DB $54,C0196 ; CALL C0196 +; 1286: next + DB $50,C0205 ; SKIP C0205 +C0204: + DB $30 ; DROP +; 1287: end + DB $5A ; LEAVE +; 1288: def cursdown +C0206: ; cursdown() +; 1289: if cursrow < numlines - 1 + JSR INTERP + DB $6A,D0200 ; LAW D0200 + DB $6A,D0206 ; LAW D0206 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $46 ; ISLT + DB $4C,C0208 ; SKPFLS C0208 +; 1290: cursoff() + DB $54,C0173 ; CALL C0173 +; 1291: cursrow = cursrow + 1 + DB $6A,D0200 ; LAW D0200 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $7A,D0200 ; SAW D0200 +; 1292: if cursy < 23 + DB $68,D0195 ; LAB D0195 + DB $2A,$17 ; CB 23 + DB $46 ; ISLT + DB $4C,C0210 ; SKPFLS C0210 +; 1293: cursy = cursy + 1 + DB $68,D0195 ; LAB D0195 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $78,D0195 ; SAB D0195 +; 1294: else + DB $50,C0211 ; SKIP C0211 +C0210: +; 1295: scrntop = cursrow - 23 + DB $6A,D0200 ; LAW D0200 + DB $2A,$17 ; CB 23 + DB $04 ; SUB + DB $7A,D0202 ; SAW D0202 +; 1296: drawscrn_20(scrntop, scrnleft) + DB $6A,D0202 ; LAW D0202 + DB $68,D0196 ; LAB D0196 + DB $54,C0165 ; CALL C0165 +; 1297: fin +C0211: +; 1298: curson() + DB $54,C0177 ; CALL C0177 +; 1299: fin +C0208: +C0209: +; 1300: end + DB $5C ; RET +; 1301: def pgdown +C0212: ; pgdown() +; 1302: byte i + ; i = 2 +; 1303: +; 1304: for i = pgjmp downto 0 + JSR INTERP + DB $58,$03,$00 ; ENTER 3,0 + DB $2A,$10 ; CB 16 +C0215: + DB $6C,$02 ; DLB 2 + DB $00 ; ZERO + DB $38,C0214 ; SKPLT C0214 + DB $0E ; DECR +; 1305: cursdown() + DB $54,C0206 ; CALL C0206 +; 1306: next + DB $50,C0215 ; SKIP C0215 +C0214: + DB $30 ; DROP +; 1307: end + DB $5A ; LEAVE +; 1308: def cursleft +C0216: ; cursleft() +; 1309: if curscol > 0 + JSR INTERP + DB $68,D0197 ; LAB D0197 + DB $00 ; ZERO + DB $44 ; ISGT + DB $4C,C0218 ; SKPFLS C0218 +; 1310: cursoff() + DB $54,C0173 ; CALL C0173 +; 1311: curscol = curscol - 1 + DB $68,D0197 ; LAB D0197 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $78,D0197 ; SAB D0197 +; 1312: if cursx > 0 + DB $68,D0194 ; LAB D0194 + DB $00 ; ZERO + DB $44 ; ISGT + DB $4C,C0220 ; SKPFLS C0220 +; 1313: cursx = cursx - 1 + DB $68,D0194 ; LAB D0194 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $78,D0194 ; SAB D0194 +; 1314: else + DB $50,C0221 ; SKIP C0221 +C0220: +; 1315: scrnleft = curscol + DB $68,D0197 ; LAB D0197 + DB $78,D0196 ; SAB D0196 +; 1316: drawscrn_20(scrntop, scrnleft) + DB $6A,D0202 ; LAW D0202 + DB $68,D0196 ; LAB D0196 + DB $54,C0165 ; CALL C0165 +; 1317: fin +C0221: +; 1318: curson() + DB $54,C0177 ; CALL C0177 +; 1319: fin +C0218: +C0219: +; 1320: end + DB $5C ; RET +; 1321: def pgleft +C0222: ; pgleft() +; 1322: byte i + ; i = 2 +; 1323: +; 1324: for i = 7 downto 0 + JSR INTERP + DB $58,$03,$00 ; ENTER 3,0 + DB $2A,$07 ; CB 7 +C0225: + DB $6C,$02 ; DLB 2 + DB $00 ; ZERO + DB $38,C0224 ; SKPLT C0224 + DB $0E ; DECR +; 1325: cursleft() + DB $54,C0216 ; CALL C0216 +; 1326: next + DB $50,C0225 ; SKIP C0225 +C0224: + DB $30 ; DROP +; 1327: end + DB $5A ; LEAVE +; 1328: def cursright +C0226: ; cursright() +; 1329: if curscol < 80 + JSR INTERP + DB $68,D0197 ; LAB D0197 + DB $2A,$50 ; CB 80 + DB $46 ; ISLT + DB $4C,C0228 ; SKPFLS C0228 +; 1330: cursoff() + DB $54,C0173 ; CALL C0173 +; 1331: curscol = curscol + 1 + DB $68,D0197 ; LAB D0197 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $78,D0197 ; SAB D0197 +; 1332: if cursx < 39 + DB $68,D0194 ; LAB D0194 + DB $2A,$27 ; CB 39 + DB $46 ; ISLT + DB $4C,C0230 ; SKPFLS C0230 +; 1333: cursx = cursx + 1 + DB $68,D0194 ; LAB D0194 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $78,D0194 ; SAB D0194 +; 1334: else + DB $50,C0231 ; SKIP C0231 +C0230: +; 1335: scrnleft = curscol - 39 + DB $68,D0197 ; LAB D0197 + DB $2A,$27 ; CB 39 + DB $04 ; SUB + DB $78,D0196 ; SAB D0196 +; 1336: drawscrn_20(scrntop, scrnleft) + DB $6A,D0202 ; LAW D0202 + DB $68,D0196 ; LAB D0196 + DB $54,C0165 ; CALL C0165 +; 1337: fin +C0231: +; 1338: curson() + DB $54,C0177 ; CALL C0177 +; 1339: fin +C0228: +C0229: +; 1340: end + DB $5C ; RET +; 1341: def pgright +C0232: ; pgright() +; 1342: byte i + ; i = 2 +; 1343: +; 1344: for i = 7 downto 0 + JSR INTERP + DB $58,$03,$00 ; ENTER 3,0 + DB $2A,$07 ; CB 7 +C0235: + DB $6C,$02 ; DLB 2 + DB $00 ; ZERO + DB $38,C0234 ; SKPLT C0234 + DB $0E ; DECR +; 1345: cursright() + DB $54,C0226 ; CALL C0226 +; 1346: next + DB $50,C0235 ; SKIP C0235 +C0234: + DB $30 ; DROP +; 1347: end + DB $5A ; LEAVE +; 1348: ; +; 1349: ; Keyboard routines +; 1350: ; +; 1351: def keyin2e_01 +C0236: ; keyin2e_01() +; 1352: repeat + JSR INTERP +C0239: +; 1353: cursflash() + DB $54,C0181 ; CALL C0181 +; 1354: until ^keyboard >= 128 + DB $2C,$00,$C0 ; CW 49152 + DB $60 ; LB + DB $2A,$80 ; CB 128 + DB $48 ; ISGE + DB $4C,C0239 ; SKPFLS C0239 +C0238: +; 1355: return ^keystrobe + DB $2C,$10,$C0 ; CW 49168 + DB $60 ; LB + DB $5C ; RET +; 1356: end +; 1357: def keyin2_01 +C0240: ; keyin2_01() +; 1358: byte key + ; key = 2 +; 1359: +; 1360: repeat + JSR INTERP + DB $58,$03,$00 ; ENTER 3,0 +C0243: +; 1361: cursflash() + DB $54,C0181 ; CALL C0181 +; 1362: key = ^keyboard + DB $2C,$00,$C0 ; CW 49152 + DB $60 ; LB + DB $74,$02 ; SLB 2 +; 1363: if key == keyctrll + DB $64,$02 ; LLB 2 + DB $2A,$8C ; CB 140 + DB $40 ; ISEQ + DB $4C,C0244 ; SKPFLS C0244 +; 1364: drop ^keystrobe + DB $2C,$10,$C0 ; CW 49168 + DB $60 ; LB + DB $30 ; DROP +; 1365: flags = flags ^ shiftlock + DB $68,D0192 ; LAB D0192 + DB $2A,$80 ; CB 128 + DB $18 ; XOR + DB $78,D0192 ; SAB D0192 +; 1366: key = 0 + DB $00 ; ZERO + DB $74,$02 ; SLB 2 +; 1367: fin +C0244: +C0245: +; 1368: until key >= 128 + DB $64,$02 ; LLB 2 + DB $2A,$80 ; CB 128 + DB $48 ; ISGE + DB $4C,C0243 ; SKPFLS C0243 +C0242: +; 1369: drop ^keystrobe + DB $2C,$10,$C0 ; CW 49168 + DB $60 ; LB + DB $30 ; DROP +; 1370: if key == keyctrln + DB $64,$02 ; LLB 2 + DB $2A,$8E ; CB 142 + DB $40 ; ISEQ + DB $4C,C0246 ; SKPFLS C0246 +; 1371: key = $DB ; [ + DB $2A,$DB ; CB 219 + DB $74,$02 ; SLB 2 +; 1372: elsif key == keyctrlp + DB $50,C0247 ; SKIP C0247 +C0246: + DB $64,$02 ; LLB 2 + DB $2A,$90 ; CB 144 + DB $40 ; ISEQ + DB $4C,C0248 ; SKPFLS C0248 +; 1373: key = $DF ; _ + DB $2A,$DF ; CB 223 + DB $74,$02 ; SLB 2 +; 1374: elsif key == keyctrlb + DB $50,C0247 ; SKIP C0247 +C0248: + DB $64,$02 ; LLB 2 + DB $2A,$82 ; CB 130 + DB $40 ; ISEQ + DB $4C,C0249 ; SKPFLS C0249 +; 1375: key = $DC ; \ + DB $2A,$DC ; CB 220 + DB $74,$02 ; SLB 2 +; 1376: elsif key == keyarrowleft + DB $50,C0247 ; SKIP C0247 +C0249: + DB $64,$02 ; LLB 2 + DB $2A,$88 ; CB 136 + DB $40 ; ISEQ + DB $4C,C0250 ; SKPFLS C0250 +; 1377: if ^pushbttn3 < 128 + DB $2C,$63,$C0 ; CW 49251 + DB $60 ; LB + DB $2A,$80 ; CB 128 + DB $46 ; ISLT + DB $4C,C0251 ; SKPFLS C0251 +; 1378: key = $FF + DB $2A,$FF ; CB 255 + DB $74,$02 ; SLB 2 +; 1379: fin +C0251: +C0252: +; 1380: elsif key >= $C0 and flags < shiftlock + DB $50,C0247 ; SKIP C0247 +C0250: + DB $64,$02 ; LLB 2 + DB $2A,$C0 ; CB 192 + DB $48 ; ISGE + DB $68,D0192 ; LAB D0192 + DB $2A,$80 ; CB 128 + DB $46 ; ISLT + DB $24 ; LAND + DB $4C,C0253 ; SKPFLS C0253 +; 1381: if ^pushbttn3 < 128 + DB $2C,$63,$C0 ; CW 49251 + DB $60 ; LB + DB $2A,$80 ; CB 128 + DB $46 ; ISLT + DB $4C,C0254 ; SKPFLS C0254 +; 1382: if key == $C0 + DB $64,$02 ; LLB 2 + DB $2A,$C0 ; CB 192 + DB $40 ; ISEQ + DB $4C,C0256 ; SKPFLS C0256 +; 1383: key = $D0 ; P + DB $2A,$D0 ; CB 208 + DB $74,$02 ; SLB 2 +; 1384: elsif key == $DD + DB $50,C0257 ; SKIP C0257 +C0256: + DB $64,$02 ; LLB 2 + DB $2A,$DD ; CB 221 + DB $40 ; ISEQ + DB $4C,C0258 ; SKPFLS C0258 +; 1385: key = $CD ; M + DB $2A,$CD ; CB 205 + DB $74,$02 ; SLB 2 +; 1386: elsif key == $DE + DB $50,C0257 ; SKIP C0257 +C0258: + DB $64,$02 ; LLB 2 + DB $2A,$DE ; CB 222 + DB $40 ; ISEQ + DB $4C,C0259 ; SKPFLS C0259 +; 1387: key = $CE ; N + DB $2A,$CE ; CB 206 + DB $74,$02 ; SLB 2 +; 1388: fin +C0259: +C0257: +; 1389: else + DB $50,C0255 ; SKIP C0255 +C0254: +; 1390: key = key ? $E0 + DB $64,$02 ; LLB 2 + DB $2A,$E0 ; CB 224 + DB $16 ; IOR + DB $74,$02 ; SLB 2 +; 1391: fin +C0255: +; 1392: fin +C0253: +C0247: +; 1393: return key + DB $64,$02 ; LLB 2 + DB $5A ; LEAVE +; 1394: end +; 1395: ; +; 1396: ; Printer routines +; 1397: ; +; 1398: def printtxt_10(slot) +C0260: ; printtxt_10() + ; slot = 2 +; 1399: byte txtbuf[80] + ; txtbuf = 4 +; 1400: word i, scrncsw + ; i = 84 + ; scrncsw = 86 +; 1401: +; 1402: scrncsw = *(csw) + JSR INTERP + DB $58,$58,$01 ; ENTER 88,1 + DB $2A,$36 ; CB 54 + DB $62 ; LW + DB $76,$56 ; SLW 86 +; 1403: *(csw) = $C000 ? (slot << 8) + DB $2A,$36 ; CB 54 + DB $2C,$00,$C0 ; CW 49152 + DB $66,$02 ; LLW 2 + DB $2A,$08 ; CB 8 + DB $1A ; SHL + DB $16 ; IOR + DB $72 ; SW +; 1404: for i = 0 to numlines - 1 + DB $00 ; ZERO +C0263: + DB $6E,$54 ; DLW 84 + DB $6A,D0206 ; LAW D0206 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $3A,C0262 ; SKPGT C0262 + DB $0C ; INCR +; 1405: cpyln_20(strlinbuf:[i], @txtbuf) + DB $2C,$00,$10 ; CW 4096 + DB $66,$54 ; LLW 84 + DB $1E ; IDXW + DB $62 ; LW + DB $28,$04 ; LLA 4 + DB $54,C0133 ; CALL C0133 +; 1406: prstr(@txtbuf) + DB $28,$04 ; LLA 4 + DB $54,C0019 ; CALL C0019 +; 1407: crout() + DB $54,C0043 ; CALL C0043 +; 1408: next + DB $50,C0263 ; SKIP C0263 +C0262: + DB $30 ; DROP +; 1409: *(csw) = scrncsw + DB $2A,$36 ; CB 54 + DB $66,$56 ; LLW 86 + DB $72 ; SW +; 1410: end + DB $5A ; LEAVE +; 1411: def openline_11(row) +C0264: ; openline_11() + ; row = 2 +; 1412: if numlines < maxlines + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $6A,D0206 ; LAW D0206 + DB $2C,$72,$02 ; CW 626 + DB $46 ; ISLT + DB $4C,C0266 ; SKPFLS C0266 +; 1413: memcpy(@strlinbuf:[row], @strlinbuf:[row + 1], (numlines - row) * 2) + DB $2C,$00,$10 ; CW 4096 + DB $66,$02 ; LLW 2 + DB $1E ; IDXW + DB $2C,$00,$10 ; CW 4096 + DB $66,$02 ; LLW 2 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $1E ; IDXW + DB $6A,D0206 ; LAW D0206 + DB $66,$02 ; LLW 2 + DB $04 ; SUB + DB $2A,$02 ; CB 2 + DB $06 ; MUL + DB $54,C0013 ; CALL C0013 +; 1414: strlinbuf:[row] = @nullstr + DB $2C,$00,$10 ; CW 4096 + DB $66,$02 ; LLW 2 + DB $1E ; IDXW + DB $26,D0048 ; LA D0048 + DB $72 ; SW +; 1415: numlines = numlines + 1 + DB $6A,D0206 ; LAW D0206 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $7A,D0206 ; SAW D0206 +; 1416: flags = flags ? changed + DB $68,D0192 ; LAB D0192 + DB $2A,$01 ; CB 1 + DB $16 ; IOR + DB $78,D0192 ; SAB D0192 +; 1417: return 1 + DB $2A,$01 ; CB 1 + DB $5A ; LEAVE +; 1418: fin +C0266: +C0267: +; 1419: bell() + DB $54,C0045 ; CALL C0045 +; 1420: return 0 + DB $00 ; ZERO + DB $5A ; LEAVE +; 1421: end +; 1422: def cutline +C0268: ; cutline() +; 1423: freestr_10(cutbuf) + JSR INTERP + DB $6A,D0208 ; LAW D0208 + DB $54,C0073 ; CALL C0073 +; 1424: cutbuf = strlinbuf:[cursrow] + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0200 ; LAW D0200 + DB $1E ; IDXW + DB $62 ; LW + DB $7A,D0208 ; SAW D0208 +; 1425: memcpy(@strlinbuf:[cursrow + 1], @strlinbuf:[cursrow], (numlines - cursrow) * 2) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0200 ; LAW D0200 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $1E ; IDXW + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0200 ; LAW D0200 + DB $1E ; IDXW + DB $6A,D0206 ; LAW D0206 + DB $6A,D0200 ; LAW D0200 + DB $04 ; SUB + DB $2A,$02 ; CB 2 + DB $06 ; MUL + DB $54,C0013 ; CALL C0013 +; 1426: if numlines > 1 + DB $6A,D0206 ; LAW D0206 + DB $2A,$01 ; CB 1 + DB $44 ; ISGT + DB $4C,C0270 ; SKPFLS C0270 +; 1427: numlines = numlines - 1 + DB $6A,D0206 ; LAW D0206 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $7A,D0206 ; SAW D0206 +; 1428: fin +C0270: +C0271: +; 1429: flags = flags ? changed + DB $68,D0192 ; LAB D0192 + DB $2A,$01 ; CB 1 + DB $16 ; IOR + DB $78,D0192 ; SAB D0192 +; 1430: if cursrow == numlines + DB $6A,D0200 ; LAW D0200 + DB $6A,D0206 ; LAW D0206 + DB $40 ; ISEQ + DB $4C,C0272 ; SKPFLS C0272 +; 1431: cursup() + DB $54,C0196 ; CALL C0196 +; 1432: fin +C0272: +C0273: +; 1433: redraw() + DB $54,C0188 ; CALL C0188 +; 1434: end + DB $5C ; RET +; 1435: def pasteline +C0274: ; pasteline() +; 1436: if cutbuf and numlines < maxlines + JSR INTERP + DB $6A,D0208 ; LAW D0208 + DB $6A,D0206 ; LAW D0206 + DB $2C,$72,$02 ; CW 626 + DB $46 ; ISLT + DB $24 ; LAND + DB $4C,C0276 ; SKPFLS C0276 +; 1437: memcpy(@strlinbuf:[cursrow], @strlinbuf:[cursrow + 1], (numlines - cursrow) * 2) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0200 ; LAW D0200 + DB $1E ; IDXW + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0200 ; LAW D0200 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $1E ; IDXW + DB $6A,D0206 ; LAW D0206 + DB $6A,D0200 ; LAW D0200 + DB $04 ; SUB + DB $2A,$02 ; CB 2 + DB $06 ; MUL + DB $54,C0013 ; CALL C0013 +; 1438: strlinbuf:[cursrow] = newstr_11(cutbuf) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0200 ; LAW D0200 + DB $1E ; IDXW + DB $6A,D0208 ; LAW D0208 + DB $54,C0077 ; CALL C0077 + DB $72 ; SW +; 1439: numlines = numlines + 1 + DB $6A,D0206 ; LAW D0206 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $7A,D0206 ; SAW D0206 +; 1440: flags = flags ? changed + DB $68,D0192 ; LAB D0192 + DB $2A,$01 ; CB 1 + DB $16 ; IOR + DB $78,D0192 ; SAB D0192 +; 1441: redraw() + DB $54,C0188 ; CALL C0188 +; 1442: else + DB $50,C0277 ; SKIP C0277 +C0276: +; 1443: bell() + DB $54,C0045 ; CALL C0045 +; 1444: fin +C0277: +; 1445: end + DB $5C ; RET +; 1446: def joinline +C0278: ; joinline() +; 1447: byte joinstr[80], joinlen + ; joinstr = 2 + ; joinlen = 82 +; 1448: +; 1449: if cursrow < numlines - 1 + JSR INTERP + DB $58,$53,$00 ; ENTER 83,0 + DB $6A,D0200 ; LAW D0200 + DB $6A,D0206 ; LAW D0206 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $46 ; ISLT + DB $4C,C0280 ; SKPFLS C0280 +; 1450: strcpy_20(strlinbuf:[cursrow], @joinstr) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0200 ; LAW D0200 + DB $1E ; IDXW + DB $62 ; LW + DB $28,$02 ; LLA 2 + DB $54,C0047 ; CALL C0047 +; 1451: joinlen = joinstr + ^(strlinbuf:[cursrow + 1]) + DB $64,$02 ; LLB 2 + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0200 ; LAW D0200 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $1E ; IDXW + DB $62 ; LW + DB $60 ; LB + DB $02 ; ADD + DB $74,$52 ; SLB 82 +; 1452: if joinlen < 80 + DB $64,$52 ; LLB 82 + DB $2A,$50 ; CB 80 + DB $46 ; ISLT + DB $4C,C0282 ; SKPFLS C0282 +; 1453: memcpy(strlinbuf:[cursrow + 1] + 1, @joinstr + joinstr + 1, ^(strlinbuf:[cursrow + 1])) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0200 ; LAW D0200 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $1E ; IDXW + DB $62 ; LW + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $28,$02 ; LLA 2 + DB $64,$02 ; LLB 2 + DB $02 ; ADD + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0200 ; LAW D0200 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $1E ; IDXW + DB $62 ; LW + DB $60 ; LB + DB $54,C0013 ; CALL C0013 +; 1454: joinstr = joinlen + DB $64,$52 ; LLB 82 + DB $74,$02 ; SLB 2 +; 1455: freestr_10(strlinbuf:[cursrow]) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0200 ; LAW D0200 + DB $1E ; IDXW + DB $62 ; LW + DB $54,C0073 ; CALL C0073 +; 1456: strlinbuf:[cursrow] = newstr_11(@joinstr) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0200 ; LAW D0200 + DB $1E ; IDXW + DB $28,$02 ; LLA 2 + DB $54,C0077 ; CALL C0077 + DB $72 ; SW +; 1457: freestr_10(strlinbuf:[cursrow + 1]) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0200 ; LAW D0200 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $1E ; IDXW + DB $62 ; LW + DB $54,C0073 ; CALL C0073 +; 1458: numlines = numlines - 1 + DB $6A,D0206 ; LAW D0206 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $7A,D0206 ; SAW D0206 +; 1459: memcpy(@strlinbuf:[cursrow + 2], @strlinbuf:[cursrow + 1], (numlines - cursrow) * 2) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0200 ; LAW D0200 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $1E ; IDXW + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0200 ; LAW D0200 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $1E ; IDXW + DB $6A,D0206 ; LAW D0206 + DB $6A,D0200 ; LAW D0200 + DB $04 ; SUB + DB $2A,$02 ; CB 2 + DB $06 ; MUL + DB $54,C0013 ; CALL C0013 +; 1460: flags = flags ? changed + DB $68,D0192 ; LAB D0192 + DB $2A,$01 ; CB 1 + DB $16 ; IOR + DB $78,D0192 ; SAB D0192 +; 1461: redraw() + DB $54,C0188 ; CALL C0188 +; 1462: else + DB $50,C0283 ; SKIP C0283 +C0282: +; 1463: bell() + DB $54,C0045 ; CALL C0045 +; 1464: fin +C0283: +; 1465: fin +C0280: +C0281: +; 1466: end + DB $5A ; LEAVE +; 1467: def splitline +C0284: ; splitline() +; 1468: byte splitstr[80], splitlen + ; splitstr = 2 + ; splitlen = 82 +; 1469: +; 1470: if openline_11(cursrow + 1) + JSR INTERP + DB $58,$53,$00 ; ENTER 83,0 + DB $6A,D0200 ; LAW D0200 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $54,C0264 ; CALL C0264 + DB $4C,C0286 ; SKPFLS C0286 +; 1471: if curscol + DB $68,D0197 ; LAB D0197 + DB $4C,C0288 ; SKPFLS C0288 +; 1472: splitlen = ^(strlinbuf:[cursrow]) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0200 ; LAW D0200 + DB $1E ; IDXW + DB $62 ; LW + DB $60 ; LB + DB $74,$52 ; SLB 82 +; 1473: if curscol < splitlen - 1 + DB $68,D0197 ; LAB D0197 + DB $64,$52 ; LLB 82 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $46 ; ISLT + DB $4C,C0290 ; SKPFLS C0290 +; 1474: memcpy(strlinbuf:[cursrow] + curscol + 1, @splitstr + 1, splitlen - curscol) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0200 ; LAW D0200 + DB $1E ; IDXW + DB $62 ; LW + DB $68,D0197 ; LAB D0197 + DB $02 ; ADD + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $28,$02 ; LLA 2 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $64,$52 ; LLB 82 + DB $68,D0197 ; LAB D0197 + DB $04 ; SUB + DB $54,C0013 ; CALL C0013 +; 1475: splitstr = splitlen - curscol + DB $64,$52 ; LLB 82 + DB $68,D0197 ; LAB D0197 + DB $04 ; SUB + DB $74,$02 ; SLB 2 +; 1476: strlinbuf:[cursrow + 1] = newstr_11(@splitstr) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0200 ; LAW D0200 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $1E ; IDXW + DB $28,$02 ; LLA 2 + DB $54,C0077 ; CALL C0077 + DB $72 ; SW +; 1477: memcpy(strlinbuf:[cursrow] + 1, @splitstr + 1, curscol) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0200 ; LAW D0200 + DB $1E ; IDXW + DB $62 ; LW + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $28,$02 ; LLA 2 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D0197 ; LAB D0197 + DB $54,C0013 ; CALL C0013 +; 1478: splitstr = curscol + DB $68,D0197 ; LAB D0197 + DB $74,$02 ; SLB 2 +; 1479: freestr_10(strlinbuf:[cursrow]) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0200 ; LAW D0200 + DB $1E ; IDXW + DB $62 ; LW + DB $54,C0073 ; CALL C0073 +; 1480: strlinbuf:[cursrow] = newstr_11(@splitstr) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0200 ; LAW D0200 + DB $1E ; IDXW + DB $28,$02 ; LLA 2 + DB $54,C0077 ; CALL C0077 + DB $72 ; SW +; 1481: fin +C0290: +C0291: +; 1482: else + DB $50,C0289 ; SKIP C0289 +C0288: +; 1483: strlinbuf:[cursrow + 1] = strlinbuf:[cursrow] + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0200 ; LAW D0200 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $1E ; IDXW + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0200 ; LAW D0200 + DB $1E ; IDXW + DB $62 ; LW + DB $72 ; SW +; 1484: strlinbuf:[cursrow] = @nullstr + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0200 ; LAW D0200 + DB $1E ; IDXW + DB $26,D0048 ; LA D0048 + DB $72 ; SW +; 1485: fin +C0289: +; 1486: curscol = 0 + DB $00 ; ZERO + DB $78,D0197 ; SAB D0197 +; 1487: cursx = 0 + DB $00 ; ZERO + DB $78,D0194 ; SAB D0194 +; 1488: scrnleft = 0 + DB $00 ; ZERO + DB $78,D0196 ; SAB D0196 +; 1489: redraw() + DB $54,C0188 ; CALL C0188 +; 1490: cursdown() + DB $54,C0206 ; CALL C0206 +; 1491: fin +C0286: +C0287: +; 1492: end + DB $5A ; LEAVE +; 1493: def editkey_11(key) +C0292: ; editkey_11() + ; key = 2 +; 1494: if key >= keyspace + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $66,$02 ; LLW 2 + DB $2A,$A0 ; CB 160 + DB $48 ; ISGE + DB $4C,C0294 ; SKPFLS C0294 +; 1495: return 1 + DB $2A,$01 ; CB 1 + DB $5A ; LEAVE +; 1496: elsif key == keydelete + DB $50,C0295 ; SKIP C0295 +C0294: + DB $66,$02 ; LLW 2 + DB $2A,$FF ; CB 255 + DB $40 ; ISEQ + DB $4C,C0296 ; SKPFLS C0296 +; 1497: return 1 + DB $2A,$01 ; CB 1 + DB $5A ; LEAVE +; 1498: elsif key == keyctrld + DB $50,C0295 ; SKIP C0295 +C0296: + DB $66,$02 ; LLW 2 + DB $2A,$84 ; CB 132 + DB $40 ; ISEQ + DB $4C,C0297 ; SKPFLS C0297 +; 1499: return 1 + DB $2A,$01 ; CB 1 + DB $5A ; LEAVE +; 1500: elsif key == keyctrlr + DB $50,C0295 ; SKIP C0295 +C0297: + DB $66,$02 ; LLW 2 + DB $2A,$92 ; CB 146 + DB $40 ; ISEQ + DB $4C,C0298 ; SKPFLS C0298 +; 1501: return 1 + DB $2A,$01 ; CB 1 + DB $5A ; LEAVE +; 1502: fin +C0298: +C0295: +; 1503: return 0 + DB $00 ; ZERO + DB $5A ; LEAVE +; 1504: end +; 1505: def editline_11(key) +C0299: ; editline_11() + ; key = 2 +; 1506: byte editstr[80] + ; editstr = 4 +; 1507: word undoline + ; undoline = 84 +; 1508: +; 1509: if (editkey_11(key)) + JSR INTERP + DB $58,$56,$01 ; ENTER 86,1 + DB $66,$02 ; LLW 2 + DB $54,C0292 ; CALL C0292 + DB $4C,C0301 ; SKPFLS C0301 +; 1510: flags = flags ? changed + DB $68,D0192 ; LAB D0192 + DB $2A,$01 ; CB 1 + DB $16 ; IOR + DB $78,D0192 ; SAB D0192 +; 1511: memset($A0A0, @editstr, 80) + DB $2C,$A0,$A0 ; CW 41120 + DB $28,$04 ; LLA 4 + DB $2A,$50 ; CB 80 + DB $54,C0011 ; CALL C0011 +; 1512: strcpy_20(strlinbuf:[cursrow], @editstr) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0200 ; LAW D0200 + DB $1E ; IDXW + DB $62 ; LW + DB $28,$04 ; LLA 4 + DB $54,C0047 ; CALL C0047 +; 1513: undoline = strlinbuf:[cursrow] + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0200 ; LAW D0200 + DB $1E ; IDXW + DB $62 ; LW + DB $76,$54 ; SLW 84 +; 1514: strlinbuf:[cursrow] = @editstr + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0200 ; LAW D0200 + DB $1E ; IDXW + DB $28,$04 ; LLA 4 + DB $72 ; SW +; 1515: repeat +C0304: +; 1516: if key >= keyspace + DB $66,$02 ; LLW 2 + DB $2A,$A0 ; CB 160 + DB $48 ; ISGE + DB $4C,C0305 ; SKPFLS C0305 +; 1517: if key == keydelete + DB $66,$02 ; LLW 2 + DB $2A,$FF ; CB 255 + DB $40 ; ISEQ + DB $4C,C0307 ; SKPFLS C0307 +; 1518: if curscol > 0 + DB $68,D0197 ; LAB D0197 + DB $00 ; ZERO + DB $44 ; ISGT + DB $4C,C0309 ; SKPFLS C0309 +; 1519: if curscol <= editstr + DB $68,D0197 ; LAB D0197 + DB $64,$04 ; LLB 4 + DB $4A ; ISLE + DB $4C,C0311 ; SKPFLS C0311 +; 1520: memcpy(@editstr[curscol + 1], @editstr[curscol], editstr - curscol) + DB $28,$04 ; LLA 4 + DB $68,D0197 ; LAB D0197 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $02 ; IDXB + DB $28,$04 ; LLA 4 + DB $68,D0197 ; LAB D0197 + DB $02 ; IDXB + DB $64,$04 ; LLB 4 + DB $68,D0197 ; LAB D0197 + DB $04 ; SUB + DB $54,C0013 ; CALL C0013 +; 1521: editstr = editstr - 1 + DB $64,$04 ; LLB 4 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $74,$04 ; SLB 4 +; 1522: fin +C0311: +C0312: +; 1523: curscol = curscol - 1 + DB $68,D0197 ; LAB D0197 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $78,D0197 ; SAB D0197 +; 1524: cursoff() + DB $54,C0173 ; CALL C0173 +; 1525: if cursx > 0 + DB $68,D0194 ; LAB D0194 + DB $00 ; ZERO + DB $44 ; ISGT + DB $4C,C0313 ; SKPFLS C0313 +; 1526: cursx = cursx - 1 + DB $68,D0194 ; LAB D0194 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $78,D0194 ; SAB D0194 +; 1527: drawrow_30(cursy, scrnleft, @editstr) + DB $68,D0195 ; LAB D0195 + DB $68,D0196 ; LAB D0196 + DB $28,$04 ; LLA 4 + DB $54,C0159 ; CALL C0159 +; 1528: else + DB $50,C0314 ; SKIP C0314 +C0313: +; 1529: scrnleft = scrnleft - 1 + DB $68,D0196 ; LAB D0196 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $78,D0196 ; SAB D0196 +; 1530: drawscrn_20(scrntop, scrnleft) + DB $6A,D0202 ; LAW D0202 + DB $68,D0196 ; LAB D0196 + DB $54,C0165 ; CALL C0165 +; 1531: fin +C0314: +; 1532: curson() + DB $54,C0177 ; CALL C0177 +; 1533: fin +C0309: +C0310: +; 1534: elsif curscol < maxlnlen + DB $50,C0308 ; SKIP C0308 +C0307: + DB $68,D0197 ; LAB D0197 + DB $2A,$4F ; CB 79 + DB $46 ; ISLT + DB $4C,C0315 ; SKPFLS C0315 +; 1535: curscol = curscol + 1 + DB $68,D0197 ; LAB D0197 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $78,D0197 ; SAB D0197 +; 1536: cursx = cursx + 1 + DB $68,D0194 ; LAB D0194 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $78,D0194 ; SAB D0194 +; 1537: if flags & insmode + DB $68,D0192 ; LAB D0192 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C0316 ; SKPFLS C0316 +; 1538: if editstr < maxlnlen or editstr.maxlnlen == $A0 + DB $64,$04 ; LLB 4 + DB $2A,$4F ; CB 79 + DB $46 ; ISLT + DB $28,$53 ; LLA 83 + DB $60 ; LB + DB $2A,$A0 ; CB 160 + DB $40 ; ISEQ + DB $22 ; LOR + DB $4C,C0318 ; SKPFLS C0318 +; 1539: editstr = editstr + 1 + DB $64,$04 ; LLB 4 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $74,$04 ; SLB 4 +; 1540: if curscol >= editstr + DB $68,D0197 ; LAB D0197 + DB $64,$04 ; LLB 4 + DB $48 ; ISGE + DB $4C,C0320 ; SKPFLS C0320 +; 1541: editstr = curscol + DB $68,D0197 ; LAB D0197 + DB $74,$04 ; SLB 4 +; 1542: else + DB $50,C0321 ; SKIP C0321 +C0320: +; 1543: memcpy(@editstr[curscol], @editstr[curscol + 1], editstr - curscol) + DB $28,$04 ; LLA 4 + DB $68,D0197 ; LAB D0197 + DB $02 ; IDXB + DB $28,$04 ; LLA 4 + DB $68,D0197 ; LAB D0197 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $02 ; IDXB + DB $64,$04 ; LLB 4 + DB $68,D0197 ; LAB D0197 + DB $04 ; SUB + DB $54,C0013 ; CALL C0013 +; 1544: fin +C0321: +; 1545: else + DB $50,C0319 ; SKIP C0319 +C0318: +; 1546: curscol = curscol - 1 + DB $68,D0197 ; LAB D0197 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $78,D0197 ; SAB D0197 +; 1547: cursx = cursx - 1 + DB $68,D0194 ; LAB D0194 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $78,D0194 ; SAB D0194 +; 1548: key = editstr[curscol] + DB $28,$04 ; LLA 4 + DB $68,D0197 ; LAB D0197 + DB $02 ; IDXB + DB $60 ; LB + DB $76,$02 ; SLW 2 +; 1549: bell() + DB $54,C0045 ; CALL C0045 +; 1550: fin +C0319: +; 1551: else + DB $50,C0317 ; SKIP C0317 +C0316: +; 1552: if curscol > editstr + DB $68,D0197 ; LAB D0197 + DB $64,$04 ; LLB 4 + DB $44 ; ISGT + DB $4C,C0322 ; SKPFLS C0322 +; 1553: editstr = curscol + DB $68,D0197 ; LAB D0197 + DB $74,$04 ; SLB 4 +; 1554: fin +C0322: +C0323: +; 1555: fin +C0317: +; 1556: editstr[curscol] = caseconv_11(key) + DB $28,$04 ; LLA 4 + DB $68,D0197 ; LAB D0197 + DB $02 ; IDXB + DB $66,$02 ; LLW 2 + DB $54,C0087 ; CALL C0087 + DB $70 ; SB +; 1557: cursoff() + DB $54,C0173 ; CALL C0173 +; 1558: if cursx <= 39 + DB $68,D0194 ; LAB D0194 + DB $2A,$27 ; CB 39 + DB $4A ; ISLE + DB $4C,C0324 ; SKPFLS C0324 +; 1559: drawrow_30(cursy, scrnleft, @editstr) + DB $68,D0195 ; LAB D0195 + DB $68,D0196 ; LAB D0196 + DB $28,$04 ; LLA 4 + DB $54,C0159 ; CALL C0159 +; 1560: else + DB $50,C0325 ; SKIP C0325 +C0324: +; 1561: scrnleft = scrnleft + 1 + DB $68,D0196 ; LAB D0196 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $78,D0196 ; SAB D0196 +; 1562: cursx = 39 + DB $2A,$27 ; CB 39 + DB $78,D0194 ; SAB D0194 +; 1563: drawscrn_20(scrntop, scrnleft) + DB $6A,D0202 ; LAW D0202 + DB $68,D0196 ; LAB D0196 + DB $54,C0165 ; CALL C0165 +; 1564: fin +C0325: +; 1565: curson() + DB $54,C0177 ; CALL C0177 +; 1566: else + DB $50,C0308 ; SKIP C0308 +C0315: +; 1567: bell() + DB $54,C0045 ; CALL C0045 +; 1568: fin +C0308: +; 1569: elsif key == keyctrld + DB $50,C0306 ; SKIP C0306 +C0305: + DB $66,$02 ; LLW 2 + DB $2A,$84 ; CB 132 + DB $40 ; ISEQ + DB $4C,C0326 ; SKPFLS C0326 +; 1570: if curscol < editstr + DB $68,D0197 ; LAB D0197 + DB $64,$04 ; LLB 4 + DB $46 ; ISLT + DB $4C,C0327 ; SKPFLS C0327 +; 1571: memcpy(@editstr[curscol + 2], @editstr[curscol + 1], editstr - curscol) + DB $28,$04 ; LLA 4 + DB $68,D0197 ; LAB D0197 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $02 ; IDXB + DB $28,$04 ; LLA 4 + DB $68,D0197 ; LAB D0197 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $02 ; IDXB + DB $64,$04 ; LLB 4 + DB $68,D0197 ; LAB D0197 + DB $04 ; SUB + DB $54,C0013 ; CALL C0013 +; 1572: editstr = editstr - 1 + DB $64,$04 ; LLB 4 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $74,$04 ; SLB 4 +; 1573: cursoff() + DB $54,C0173 ; CALL C0173 +; 1574: drawrow_30(cursy, scrnleft, @editstr) + DB $68,D0195 ; LAB D0195 + DB $68,D0196 ; LAB D0196 + DB $28,$04 ; LLA 4 + DB $54,C0159 ; CALL C0159 +; 1575: curson() + DB $54,C0177 ; CALL C0177 +; 1576: fin +C0327: +C0328: +; 1577: elsif key == keyctrlr + DB $50,C0306 ; SKIP C0306 +C0326: + DB $66,$02 ; LLW 2 + DB $2A,$92 ; CB 146 + DB $40 ; ISEQ + DB $4C,C0329 ; SKPFLS C0329 +; 1578: strcpy_20(undoline, @editstr) + DB $66,$54 ; LLW 84 + DB $28,$04 ; LLA 4 + DB $54,C0047 ; CALL C0047 +; 1579: cursoff() + DB $54,C0173 ; CALL C0173 +; 1580: drawrow_30(cursy, scrnleft, @editstr) + DB $68,D0195 ; LAB D0195 + DB $68,D0196 ; LAB D0196 + DB $28,$04 ; LLA 4 + DB $54,C0159 ; CALL C0159 +; 1581: curson() + DB $54,C0177 ; CALL C0177 +; 1582: fin +C0329: +C0306: +; 1583: key = keyin_01() + DB $26,D0210 ; LA D0210 + DB $62 ; LW + DB $34 ; PUSH + DB $36 ; PULL + DB $56 ; ICAL + DB $76,$02 ; SLW 2 +; 1584: until !editkey_11(key) + DB $66,$02 ; LLW 2 + DB $54,C0292 ; CALL C0292 + DB $20 ; NOT + DB $4C,C0304 ; SKPFLS C0304 +C0303: +; 1585: if editstr + DB $64,$04 ; LLB 4 + DB $4C,C0330 ; SKPFLS C0330 +; 1586: strlinbuf:[cursrow] = newstr_11(@editstr) + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0200 ; LAW D0200 + DB $1E ; IDXW + DB $28,$04 ; LLA 4 + DB $54,C0077 ; CALL C0077 + DB $72 ; SW +; 1587: else + DB $50,C0331 ; SKIP C0331 +C0330: +; 1588: strlinbuf:[cursrow] = @nullstr + DB $2C,$00,$10 ; CW 4096 + DB $6A,D0200 ; LAW D0200 + DB $1E ; IDXW + DB $26,D0048 ; LA D0048 + DB $72 ; SW +; 1589: fin +C0331: +; 1590: freestr_10(undoline) + DB $66,$54 ; LLW 84 + DB $54,C0073 ; CALL C0073 +; 1591: fin +C0301: +C0302: +; 1592: return key + DB $66,$02 ; LLW 2 + DB $5A ; LEAVE +; 1593: end +; 1594: def editmode +C0332: ; editmode() +; 1595: repeat + JSR INTERP +C0335: +; 1596: when editline_11(keyin_01()) + DB $26,D0210 ; LA D0210 + DB $62 ; LW + DB $34 ; PUSH + DB $36 ; PULL + DB $56 ; ICAL + DB $54,C0299 ; CALL C0299 +; 1597: is keyarrowup + DB $2A,$8B ; CB 139 + DB $3E,C0337 ; SKPNE C0337 +; 1598: cursup() + DB $54,C0196 ; CALL C0196 +; 1599: is keyarrowdown + DB $50,C0336 ; SKIP C0336 +C0337: + DB $2A,$8A ; CB 138 + DB $3E,C0338 ; SKPNE C0338 +; 1600: cursdown() + DB $54,C0206 ; CALL C0206 +; 1601: is keyarrowleft + DB $50,C0336 ; SKIP C0336 +C0338: + DB $2A,$88 ; CB 136 + DB $3E,C0339 ; SKPNE C0339 +; 1602: cursleft() + DB $54,C0216 ; CALL C0216 +; 1603: is keyarrowright + DB $50,C0336 ; SKIP C0336 +C0339: + DB $2A,$95 ; CB 149 + DB $3E,C0340 ; SKPNE C0340 +; 1604: cursright() + DB $54,C0226 ; CALL C0226 +; 1605: is keyctrlw + DB $50,C0336 ; SKIP C0336 +C0340: + DB $2A,$97 ; CB 151 + DB $3E,C0341 ; SKPNE C0341 +; 1606: pgup() + DB $54,C0202 ; CALL C0202 +; 1607: is keyctrlz + DB $50,C0336 ; SKIP C0336 +C0341: + DB $2A,$9A ; CB 154 + DB $3E,C0342 ; SKPNE C0342 +; 1608: pgdown() + DB $54,C0212 ; CALL C0212 +; 1609: is keyctrla + DB $50,C0336 ; SKIP C0336 +C0342: + DB $2A,$81 ; CB 129 + DB $3E,C0343 ; SKPNE C0343 +; 1610: pgleft() + DB $54,C0222 ; CALL C0222 +; 1611: is keyctrls + DB $50,C0336 ; SKIP C0336 +C0343: + DB $2A,$93 ; CB 147 + DB $3E,C0344 ; SKPNE C0344 +; 1612: pgright() + DB $54,C0232 ; CALL C0232 +; 1613: is keyctrlq + DB $50,C0336 ; SKIP C0336 +C0344: + DB $2A,$91 ; CB 145 + DB $3E,C0345 ; SKPNE C0345 +; 1614: curshome() + DB $54,C0190 ; CALL C0190 +; 1615: is keyctrle + DB $50,C0336 ; SKIP C0336 +C0345: + DB $2A,$85 ; CB 133 + DB $3E,C0346 ; SKPNE C0346 +; 1616: cursend() + DB $54,C0192 ; CALL C0192 +; 1617: is keyctrlx + DB $50,C0336 ; SKIP C0336 +C0346: + DB $2A,$98 ; CB 152 + DB $3E,C0347 ; SKPNE C0347 +; 1618: cutline() + DB $54,C0268 ; CALL C0268 +; 1619: is keyctrlv + DB $50,C0336 ; SKIP C0336 +C0347: + DB $2A,$96 ; CB 150 + DB $3E,C0348 ; SKPNE C0348 +; 1620: pasteline() + DB $54,C0274 ; CALL C0274 +; 1621: is keyctrlo + DB $50,C0336 ; SKIP C0336 +C0348: + DB $2A,$8F ; CB 143 + DB $3E,C0349 ; SKPNE C0349 +; 1622: drop openline_11(cursrow) + DB $6A,D0200 ; LAW D0200 + DB $54,C0264 ; CALL C0264 + DB $30 ; DROP +; 1623: redraw() + DB $54,C0188 ; CALL C0188 +; 1624: is keyenter + DB $50,C0336 ; SKIP C0336 +C0349: + DB $2A,$8D ; CB 141 + DB $3E,C0350 ; SKPNE C0350 +; 1625: if flags & insmode + DB $68,D0192 ; LAB D0192 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C0351 ; SKPFLS C0351 +; 1626: splitline() + DB $54,C0284 ; CALL C0284 +; 1627: else + DB $50,C0352 ; SKIP C0352 +C0351: +; 1628: drop openline_11(cursrow + 1) + DB $6A,D0200 ; LAW D0200 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $54,C0264 ; CALL C0264 + DB $30 ; DROP +; 1629: cursdown() + DB $54,C0206 ; CALL C0206 +; 1630: redraw() + DB $54,C0188 ; CALL C0188 +; 1631: fin +C0352: +; 1632: is keyctrlt + DB $50,C0336 ; SKIP C0336 +C0350: + DB $2A,$94 ; CB 148 + DB $3E,C0353 ; SKPNE C0353 +; 1633: joinline() + DB $54,C0278 ; CALL C0278 +; 1634: is keyctrli + DB $50,C0336 ; SKIP C0336 +C0353: + DB $2A,$89 ; CB 137 + DB $3E,C0354 ; SKPNE C0354 +; 1635: if flags & insmode + DB $68,D0192 ; LAB D0192 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C0355 ; SKPFLS C0355 +; 1636: flags = flags & #insmode + DB $68,D0192 ; LAB D0192 + DB $2C,$FD,$FF ; CW -3 + DB $14 ; BAND + DB $78,D0192 ; SAB D0192 +; 1637: curschr = ' ' + DB $2A,$20 ; CB 32 + DB $78,D0199 ; SAB D0199 +; 1638: else + DB $50,C0356 ; SKIP C0356 +C0355: +; 1639: flags = flags ? insmode + DB $68,D0192 ; LAB D0192 + DB $2A,$02 ; CB 2 + DB $16 ; IOR + DB $78,D0192 ; SAB D0192 +; 1640: curschr = '+' + DB $2A,$2B ; CB 43 + DB $78,D0199 ; SAB D0199 +; 1641: fin +C0356: +; 1642: is keyctrlc + DB $50,C0336 ; SKIP C0336 +C0354: + DB $2A,$83 ; CB 131 + DB $3E,C0357 ; SKPNE C0357 +; 1643: if flags & uppercase + DB $68,D0192 ; LAB D0192 + DB $2A,$08 ; CB 8 + DB $14 ; BAND + DB $4C,C0358 ; SKPFLS C0358 +; 1644: txtlower() + DB $54,C0109 ; CALL C0109 +; 1645: else + DB $50,C0359 ; SKIP C0359 +C0358: +; 1646: txtupper() + DB $54,C0105 ; CALL C0105 +; 1647: fin +C0359: +; 1648: redraw() + DB $54,C0188 ; CALL C0188 +; 1649: is keyescape + DB $50,C0336 ; SKIP C0336 +C0357: + DB $2A,$9B ; CB 155 + DB $3E,C0360 ; SKPNE C0360 +; 1650: cursoff() + DB $54,C0173 ; CALL C0173 +; 1651: cmdmode() + DB $54,C0000 ; CALL C0000 +; 1652: redraw() + DB $54,C0188 ; CALL C0188 +; 1653: wend + DB $50,C0336 ; SKIP C0336 +C0360: +C0336: + DB $30 ; DROP +; 1654: until 0 + DB $00 ; ZERO + DB $4C,C0335 ; SKPFLS C0335 +C0334: +; 1655: end + DB $5C ; RET +; 1656: ; +; 1657: ; Command mode +; 1658: ; +; 1659: def prfiles_11(optpath) +C0362: ; prfiles_11() + ; optpath = 2 +; 1660: byte path[64] + ; path = 4 +; 1661: byte refnum + ; refnum = 68 +; 1662: byte firstblk + ; firstblk = 69 +; 1663: byte entrylen, entriesblk + ; entrylen = 70 + ; entriesblk = 71 +; 1664: byte i, type, len + ; i = 72 + ; type = 73 + ; len = 74 +; 1665: word entry, filecnt + ; entry = 75 + ; filecnt = 77 +; 1666: +; 1667: if ^optpath + JSR INTERP + DB $58,$4F,$01 ; ENTER 79,1 + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $4C,C0364 ; SKPFLS C0364 +; 1668: strcpy_20(optpath, @path) + DB $66,$02 ; LLW 2 + DB $28,$04 ; LLA 4 + DB $54,C0047 ; CALL C0047 +; 1669: else + DB $50,C0365 ; SKIP C0365 +C0364: +; 1670: drop getpfx_11(@path) + DB $28,$04 ; LLA 4 + DB $54,C0025 ; CALL C0025 + DB $30 ; DROP +; 1671: prstr(@path) + DB $28,$04 ; LLA 4 + DB $54,C0019 ; CALL C0019 +; 1672: crout() + DB $54,C0043 ; CALL C0043 +; 1673: fin +C0365: +; 1674: refnum = open_21(@path, iobuffer); + DB $28,$04 ; LLA 4 + DB $2C,$00,$08 ; CW 2048 + DB $54,C0029 ; CALL C0029 + DB $74,$44 ; SLB 68 +; 1675: if perr + DB $68,D0088 ; LAB D0088 + DB $4C,C0366 ; SKPFLS C0366 +; 1676: return perr + DB $68,D0088 ; LAB D0088 + DB $5A ; LEAVE +; 1677: fin +C0366: +C0367: +; 1678: firstblk = 1 + DB $2A,$01 ; CB 1 + DB $74,$45 ; SLB 69 +; 1679: repeat +C0369: +; 1680: if read_31(refnum, databuff, 512) == 512 + DB $64,$44 ; LLB 68 + DB $2C,$00,$0C ; CW 3072 + DB $2C,$00,$02 ; CW 512 + DB $54,C0033 ; CALL C0033 + DB $2C,$00,$02 ; CW 512 + DB $40 ; ISEQ + DB $4C,C0370 ; SKPFLS C0370 +; 1681: entry = databuff + 4 + DB $2C,$00,$0C ; CW 3072 + DB $2A,$04 ; CB 4 + DB $02 ; ADD + DB $76,$4B ; SLW 75 +; 1682: if firstblk + DB $64,$45 ; LLB 69 + DB $4C,C0372 ; SKPFLS C0372 +; 1683: entrylen = databuff.$23 + DB $2C,$23,$0C ; CW 3107 + DB $60 ; LB + DB $74,$46 ; SLB 70 +; 1684: entriesblk = databuff.$24 + DB $2C,$24,$0C ; CW 3108 + DB $60 ; LB + DB $74,$47 ; SLB 71 +; 1685: filecnt = databuff:$25 + DB $2C,$25,$0C ; CW 3109 + DB $62 ; LW + DB $76,$4D ; SLW 77 +; 1686: entry = entry + entrylen + DB $66,$4B ; LLW 75 + DB $64,$46 ; LLB 70 + DB $02 ; ADD + DB $76,$4B ; SLW 75 +; 1687: fin +C0372: +C0373: +; 1688: for i = firstblk to entriesblk + DB $64,$45 ; LLB 69 +C0375: + DB $6C,$48 ; DLB 72 + DB $64,$47 ; LLB 71 + DB $3A,C0374 ; SKPGT C0374 + DB $0C ; INCR +; 1689: type = ^entry + DB $66,$4B ; LLW 75 + DB $60 ; LB + DB $74,$49 ; SLB 73 +; 1690: if type <> 0 + DB $64,$49 ; LLB 73 + DB $00 ; ZERO + DB $42 ; ISNE + DB $4C,C0376 ; SKPFLS C0376 +; 1691: len = type & $0F + DB $64,$49 ; LLB 73 + DB $2A,$0F ; CB 15 + DB $14 ; BAND + DB $74,$4A ; SLB 74 +; 1692: ^entry = len + DB $66,$4B ; LLW 75 + DB $64,$4A ; LLB 74 + DB $70 ; SB +; 1693: prstr(entry) + DB $66,$4B ; LLW 75 + DB $54,C0019 ; CALL C0019 +; 1694: if type & $F0 == $D0 ; Is it a directory? + DB $64,$49 ; LLB 73 + DB $2A,$F0 ; CB 240 + DB $14 ; BAND + DB $2A,$D0 ; CB 208 + DB $40 ; ISEQ + DB $4C,C0378 ; SKPFLS C0378 +; 1695: cout('/') + DB $2A,$2F ; CB 47 + DB $54,C0015 ; CALL C0015 +; 1696: len = len + 1 + DB $64,$4A ; LLB 74 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $74,$4A ; SLB 74 +; 1697: fin +C0378: +C0379: +; 1698: for len = 20 - len downto 1 + DB $2A,$14 ; CB 20 + DB $64,$4A ; LLB 74 + DB $04 ; SUB +C0381: + DB $6C,$4A ; DLB 74 + DB $2A,$01 ; CB 1 + DB $38,C0380 ; SKPLT C0380 + DB $0E ; DECR +; 1699: cout(' ') + DB $2A,$20 ; CB 32 + DB $54,C0015 ; CALL C0015 +; 1700: next + DB $50,C0381 ; SKIP C0381 +C0380: + DB $30 ; DROP +; 1701: filecnt = filecnt - 1 + DB $66,$4D ; LLW 77 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $76,$4D ; SLW 77 +; 1702: fin +C0376: +C0377: +; 1703: entry = entry + entrylen + DB $66,$4B ; LLW 75 + DB $64,$46 ; LLB 70 + DB $02 ; ADD + DB $76,$4B ; SLW 75 +; 1704: next + DB $50,C0375 ; SKIP C0375 +C0374: + DB $30 ; DROP +; 1705: firstblk = 0 + DB $00 ; ZERO + DB $74,$45 ; SLB 69 +; 1706: else + DB $50,C0371 ; SKIP C0371 +C0370: +; 1707: filecnt = 0 + DB $00 ; ZERO + DB $76,$4D ; SLW 77 +; 1708: fin +C0371: +; 1709: until filecnt == 0 + DB $66,$4D ; LLW 77 + DB $00 ; ZERO + DB $40 ; ISEQ + DB $4C,C0369 ; SKPFLS C0369 +C0368: +; 1710: drop close_11(refnum) + DB $64,$44 ; LLB 68 + DB $54,C0031 ; CALL C0031 + DB $30 ; DROP +; 1711: crout() + DB $54,C0043 ; CALL C0043 +; 1712: return 0 + DB $00 ; ZERO + DB $5A ; LEAVE +; 1713: end +; 1714: def striplead_20(strptr, chr) +C0382: ; striplead_20() + ; strptr = 2 + ; chr = 4 +; 1715: while ^strptr and ^(strptr + 1) == chr + JSR INTERP + DB $58,$06,$02 ; ENTER 6,2 +C0384: + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $66,$02 ; LLW 2 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $60 ; LB + DB $66,$04 ; LLW 4 + DB $40 ; ISEQ + DB $24 ; LAND + DB $4C,C0385 ; SKPFLS C0385 +; 1716: memcpy(strptr + 2, strptr + 1, ^strptr) + DB $66,$02 ; LLW 2 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $66,$02 ; LLW 2 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $54,C0013 ; CALL C0013 +; 1717: ^strptr = ^strptr - 1 + DB $66,$02 ; LLW 2 + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $70 ; SB +; 1718: loop + DB $50,C0384 ; SKIP C0384 +C0385: +; 1719: end + DB $5A ; LEAVE +; 1720: def parsecmd_11(strptr) +C0386: ; parsecmd_11() + ; strptr = 2 +; 1721: byte cmd + ; cmd = 4 +; 1722: +; 1723: cmd = 0 + JSR INTERP + DB $58,$05,$01 ; ENTER 5,1 + DB $00 ; ZERO + DB $74,$04 ; SLB 4 +; 1724: striplead_20(strptr, ' ') + DB $66,$02 ; LLW 2 + DB $2A,$20 ; CB 32 + DB $54,C0382 ; CALL C0382 +; 1725: if ^strptr + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $4C,C0388 ; SKPFLS C0388 +; 1726: cmd = ^(strptr + 1) + DB $66,$02 ; LLW 2 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $60 ; LB + DB $74,$04 ; SLB 4 +; 1727: memcpy(strptr + 2, strptr + 1, ^strptr) + DB $66,$02 ; LLW 2 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $66,$02 ; LLW 2 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $54,C0013 ; CALL C0013 +; 1728: ^strptr = ^strptr - 1 + DB $66,$02 ; LLW 2 + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $70 ; SB +; 1729: fin +C0388: +C0389: +; 1730: if ^strptr + DB $66,$02 ; LLW 2 + DB $60 ; LB + DB $4C,C0390 ; SKPFLS C0390 +; 1731: striplead_20(strptr, ' ') + DB $66,$02 ; LLW 2 + DB $2A,$20 ; CB 32 + DB $54,C0382 ; CALL C0382 +; 1732: fin +C0390: +C0391: +; 1733: return cmd + DB $64,$04 ; LLB 4 + DB $5A ; LEAVE +; 1734: end +; 1735: def chkchng_01 +C0392: ; chkchng_01() +; 1736: if flags & changed + JSR INTERP + DB $68,D0192 ; LAB D0192 + DB $2A,$01 ; CB 1 + DB $14 ; BAND + DB $4C,C0394 ; SKPFLS C0394 +; 1737: prstr(@losechng) + DB $26,D0104 ; LA D0104 + DB $54,C0019 ; CALL C0019 +; 1738: if toupper_11(keyin_01()) == 'N' + DB $26,D0210 ; LA D0210 + DB $62 ; LW + DB $34 ; PUSH + DB $36 ; PULL + DB $56 ; ICAL + DB $54,C0127 ; CALL C0127 + DB $2A,$4E ; CB 78 + DB $40 ; ISEQ + DB $4C,C0396 ; SKPFLS C0396 +; 1739: crout() + DB $54,C0043 ; CALL C0043 +; 1740: return 0 + DB $00 ; ZERO + DB $5C ; RET +; 1741: fin +C0396: +C0397: +; 1742: crout() + DB $54,C0043 ; CALL C0043 +; 1743: fin +C0394: +C0395: +; 1744: return 1 + DB $2A,$01 ; CB 1 + DB $5C ; RET +; 1745: end +; 1746: def exec +C0398: ; exec() +; 1747: when execentry() + JSR INTERP + DB $54,C0005 ; CALL C0005 +; 1748: is 1 + DB $2A,$01 ; CB 1 + DB $3E,C0401 ; SKPNE C0401 +; 1749: crout() + DB $54,C0043 ; CALL C0043 +; 1750: prstr(@brkmsg) + DB $26,D0956 ; LA D0956 + DB $54,C0019 ; CALL C0019 +; 1751: crout() + DB $54,C0043 ; CALL C0043 +; 1752: is 2 + DB $50,C0400 ; SKIP C0400 +C0401: + DB $2A,$02 ; CB 2 + DB $3E,C0402 ; SKPNE C0402 +; 1753: crout() + DB $54,C0043 ; CALL C0043 +; 1754: prstr(@stkovflwmsg) + DB $26,D0969 ; LA D0969 + DB $54,C0019 ; CALL C0019 +; 1755: crout() + DB $54,C0043 ; CALL C0043 +; 1756: wend + DB $50,C0400 ; SKIP C0400 +C0402: +C0400: + DB $30 ; DROP +; 1757: ; +; 1758: ; Close all files +; 1759: ; +; 1760: ^$BFD8 = 0 + DB $2C,$D8,$BF ; CW 49112 + DB $00 ; ZERO + DB $70 ; SB +; 1761: drop close_11(0) + DB $00 ; ZERO + DB $54,C0031 ; CALL C0031 + DB $30 ; DROP +; 1762: end + DB $5C ; RET +; 1763: def quit +C0404: ; quit() +; 1764: if chkchng_01() + JSR INTERP + DB $54,C0392 ; CALL C0392 + DB $4C,C0406 ; SKPFLS C0406 +; 1765: exit + DB $54,C0023 ; CALL C0023 +; 1766: fin +C0406: +C0407: +; 1767: end + DB $5C ; RET +; 1768: def cmdmode +C0000: ; cmdmode() +; 1769: byte slot + ; slot = 2 +; 1770: word cmdptr + ; cmdptr = 3 +; 1771: +; 1772: clrscrn(); + JSR INTERP + DB $58,$05,$00 ; ENTER 5,0 + DB $54,C0157 ; CALL C0157 +; 1773: prstr(@version) + DB $26,D0049 ; LA D0049 + DB $54,C0019 ; CALL C0019 +; 1774: crout() + DB $54,C0043 ; CALL C0043 +; 1775: while 1 +C0409: + DB $2A,$01 ; CB 1 + DB $4C,C0410 ; SKPFLS C0410 +; 1776: prstr(@txtfile) + DB $26,D0141 ; LA D0141 + DB $54,C0019 ; CALL C0019 +; 1777: cmdptr = rdstr($BA) + DB $2A,$BA ; CB 186 + DB $54,C0021 ; CALL C0021 + DB $76,$03 ; SLW 3 +; 1778: when toupper_11(parsecmd_11(cmdptr)) + DB $66,$03 ; LLW 3 + DB $54,C0386 ; CALL C0386 + DB $54,C0127 ; CALL C0127 +; 1779: is 'A' + DB $2A,$41 ; CB 65 + DB $3E,C0412 ; SKPNE C0412 +; 1780: readtxt_10(cmdptr) + DB $66,$03 ; LLW 3 + DB $54,C0135 ; CALL C0135 +; 1781: flags = flags ? changed + DB $68,D0192 ; LAB D0192 + DB $2A,$01 ; CB 1 + DB $16 ; IOR + DB $78,D0192 ; SAB D0192 +; 1782: is 'R' + DB $50,C0411 ; SKIP C0411 +C0412: + DB $2A,$52 ; CB 82 + DB $3E,C0413 ; SKPNE C0413 +; 1783: if chkchng_01() + DB $54,C0392 ; CALL C0392 + DB $4C,C0414 ; SKPFLS C0414 +; 1784: inittxtbuf() + DB $54,C0085 ; CALL C0085 +; 1785: strcpy_20(cmdptr, @txtfile) + DB $66,$03 ; LLW 3 + DB $26,D0141 ; LA D0141 + DB $54,C0047 ; CALL C0047 +; 1786: readtxt_10(@txtfile) + DB $26,D0141 ; LA D0141 + DB $54,C0135 ; CALL C0135 +; 1787: entrypoint = 0 + DB $00 ; ZERO + DB $7A,D0492 ; SAW D0492 +; 1788: flags = flags & #changed + DB $68,D0192 ; LAB D0192 + DB $2C,$FE,$FF ; CW -2 + DB $14 ; BAND + DB $78,D0192 ; SAB D0192 +; 1789: fin +C0414: +C0415: +; 1790: is 'W' + DB $50,C0411 ; SKIP C0411 +C0413: + DB $2A,$57 ; CB 87 + DB $3E,C0416 ; SKPNE C0416 +; 1791: if ^cmdptr + DB $66,$03 ; LLW 3 + DB $60 ; LB + DB $4C,C0417 ; SKPFLS C0417 +; 1792: strcpy_20(cmdptr, @txtfile) + DB $66,$03 ; LLW 3 + DB $26,D0141 ; LA D0141 + DB $54,C0047 ; CALL C0047 +; 1793: fin +C0417: +C0418: +; 1794: writetxt_10(@txtfile) + DB $26,D0141 ; LA D0141 + DB $54,C0149 ; CALL C0149 +; 1795: if flags & changed + DB $68,D0192 ; LAB D0192 + DB $2A,$01 ; CB 1 + DB $14 ; BAND + DB $4C,C0419 ; SKPFLS C0419 +; 1796: entrypoint = 0 + DB $00 ; ZERO + DB $7A,D0492 ; SAW D0492 +; 1797: fin +C0419: +C0420: +; 1798: flags = flags & #changed + DB $68,D0192 ; LAB D0192 + DB $2C,$FE,$FF ; CW -2 + DB $14 ; BAND + DB $78,D0192 ; SAB D0192 +; 1799: is 'Q' + DB $50,C0411 ; SKIP C0411 +C0416: + DB $2A,$51 ; CB 81 + DB $3E,C0421 ; SKPNE C0421 +; 1800: quit() + DB $54,C0404 ; CALL C0404 +; 1801: is 'C' + DB $50,C0411 ; SKIP C0411 +C0421: + DB $2A,$43 ; CB 67 + DB $3E,C0422 ; SKPNE C0422 +; 1802: drop prfiles_11(cmdptr) + DB $66,$03 ; LLW 3 + DB $54,C0362 ; CALL C0362 + DB $30 ; DROP +; 1803: is 'P' + DB $50,C0411 ; SKIP C0411 +C0422: + DB $2A,$50 ; CB 80 + DB $3E,C0423 ; SKPNE C0423 +; 1804: drop setpfx_11(cmdptr) + DB $66,$03 ; LLW 3 + DB $54,C0027 ; CALL C0027 + DB $30 ; DROP +; 1805: is 'H' + DB $50,C0411 ; SKIP C0411 +C0423: + DB $2A,$48 ; CB 72 + DB $3E,C0424 ; SKPNE C0424 +; 1806: if ^cmdptr + DB $66,$03 ; LLW 3 + DB $60 ; LB + DB $4C,C0425 ; SKPFLS C0425 +; 1807: slot = cmdptr.1 - '0' + DB $28,$04 ; LLA 4 + DB $60 ; LB + DB $2A,$30 ; CB 48 + DB $04 ; SUB + DB $74,$02 ; SLB 2 +; 1808: else + DB $50,C0426 ; SKIP C0426 +C0425: +; 1809: slot = 1 + DB $2A,$01 ; CB 1 + DB $74,$02 ; SLB 2 +; 1810: fin +C0426: +; 1811: printtxt_10(slot) + DB $64,$02 ; LLB 2 + DB $54,C0260 ; CALL C0260 +; 1812: is 'E' + DB $50,C0411 ; SKIP C0411 +C0424: + DB $2A,$45 ; CB 69 + DB $3E,C0427 ; SKPNE C0427 +; 1813: return + DB $30 ; DROP + DB $5A ; LEAVE +; 1814: is 0 + DB $50,C0411 ; SKIP C0411 +C0427: + DB $00 ; ZERO + DB $3E,C0428 ; SKPNE C0428 +; 1815: return + DB $30 ; DROP + DB $5A ; LEAVE +; 1816: is 'N' + DB $50,C0411 ; SKIP C0411 +C0428: + DB $2A,$4E ; CB 78 + DB $3E,C0429 ; SKPNE C0429 +; 1817: if chkchng_01() + DB $54,C0392 ; CALL C0392 + DB $4C,C0430 ; SKPFLS C0430 +; 1818: inittxtbuf() + DB $54,C0085 ; CALL C0085 +; 1819: numlines = 1 + DB $2A,$01 ; CB 1 + DB $7A,D0206 ; SAW D0206 +; 1820: strcpy_20(@untitled, @txtfile) + DB $26,D0132 ; LA D0132 + DB $26,D0141 ; LA D0141 + DB $54,C0047 ; CALL C0047 +; 1821: fin +C0430: +C0431: +; 1822: is 'X' + DB $50,C0411 ; SKIP C0411 +C0429: + DB $2A,$58 ; CB 88 + DB $3E,C0432 ; SKPNE C0432 +; 1823: if flags & changed or !entrypoint + DB $68,D0192 ; LAB D0192 + DB $2A,$01 ; CB 1 + DB $14 ; BAND + DB $6A,D0492 ; LAW D0492 + DB $20 ; NOT + DB $22 ; LOR + DB $4C,C0433 ; SKPFLS C0433 +; 1824: drop parse_module_01() + DB $54,C0002 ; CALL C0002 + DB $30 ; DROP +; 1825: if parserr + DB $68,D0498 ; LAB D0498 + DB $4C,C0435 ; SKPFLS C0435 +; 1826: bell() + DB $54,C0045 ; CALL C0045 +; 1827: cursrow = parserrln + DB $6A,D0503 ; LAW D0503 + DB $7A,D0200 ; SAW D0200 +; 1828: scrntop = cursrow & $FFF8 + DB $6A,D0200 ; LAW D0200 + DB $2C,$F8,$FF ; CW 65528 + DB $14 ; BAND + DB $7A,D0202 ; SAW D0202 +; 1829: cursy = cursrow - scrntop + DB $6A,D0200 ; LAW D0200 + DB $6A,D0202 ; LAW D0202 + DB $04 ; SUB + DB $78,D0195 ; SAB D0195 +; 1830: curscol = parserrpos + DB $68,D0497 ; LAB D0497 + DB $78,D0197 ; SAB D0197 +; 1831: scrnleft = curscol & $FFE0 + DB $68,D0197 ; LAB D0197 + DB $2C,$E0,$FF ; CW 65504 + DB $14 ; BAND + DB $78,D0196 ; SAB D0196 +; 1832: cursx = curscol - scrnleft + DB $68,D0197 ; LAB D0197 + DB $68,D0196 ; LAB D0196 + DB $04 ; SUB + DB $78,D0194 ; SAB D0194 +; 1833: else + DB $50,C0436 ; SKIP C0436 +C0435: +; 1834: crout() + DB $54,C0043 ; CALL C0043 +; 1835: exec(entrypoint) + DB $6A,D0492 ; LAW D0492 + DB $54,C0398 ; CALL C0398 +; 1836: fin +C0436: +; 1837: else + DB $50,C0434 ; SKIP C0434 +C0433: +; 1838: exec(entrypoint) + DB $6A,D0492 ; LAW D0492 + DB $54,C0398 ; CALL C0398 +; 1839: fin +C0434: +; 1840: crout() + DB $54,C0043 ; CALL C0043 +; 1841: is 'V' + DB $50,C0411 ; SKIP C0411 +C0432: + DB $2A,$56 ; CB 86 + DB $3E,C0437 ; SKPNE C0437 +; 1842: prstr(@version) + DB $26,D0049 ; LA D0049 + DB $54,C0019 ; CALL C0019 +; 1843: wend + DB $50,C0411 ; SKIP C0411 +C0437: +C0411: + DB $30 ; DROP +; 1844: if perr + DB $68,D0088 ; LAB D0088 + DB $4C,C0439 ; SKPFLS C0439 +; 1845: prstr(@errorstr) + DB $26,D0076 ; LA D0076 + DB $54,C0019 ; CALL C0019 +; 1846: drop romcall(perr, 0, 0, 0, $FDDA) + DB $68,D0088 ; LAB D0088 + DB $00 ; ZERO + DB $00 ; ZERO + DB $00 ; ZERO + DB $2C,$DA,$FD ; CW 64986 + DB $54,C0007 ; CALL C0007 + DB $30 ; DROP +; 1847: else + DB $50,C0440 ; SKIP C0440 +C0439: +; 1848: prstr(@okstr) + DB $26,D0085 ; LA D0085 + DB $54,C0019 ; CALL C0019 +; 1849: fin +C0440: +; 1850: crout() + DB $54,C0043 ; CALL C0043 +; 1851: loop + DB $50,C0409 ; SKIP C0409 +C0410: +; 1852: end + DB $5A ; LEAVE +; 1853: +; 1854: ;===================================== +; 1855: ; +; 1856: ; PLASMA Compiler +; 1857: ; +; 1858: ;===================================== +; 1859: +; 1860: ; +; 1861: ; Error handler +; 1862: ; +; 1863: def parse_err_11(err) +C0441: ; parse_err_11() + ; err = 2 +; 1864: if !parserr + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $68,D0498 ; LAB D0498 + DB $20 ; NOT + DB $4C,C0443 ; SKPFLS C0443 +; 1865: parserr = TRUE + DB $2C,$FF,$FF ; CW -1 + DB $78,D0498 ; SAB D0498 +; 1866: parserrln = lineno - 1 + DB $6A,D0507 ; LAW D0507 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $7A,D0503 ; SAW D0503 +; 1867: parserrpos = tknptr - inbuff + DB $6A,D0501 ; LAW D0501 + DB $2C,$00,$02 ; CW 512 + DB $04 ; SUB + DB $78,D0497 ; SAB D0497 +; 1868: print_10(lineno) + DB $6A,D0507 ; LAW D0507 + DB $54,C0117 ; CALL C0117 +; 1869: cout(':') + DB $2A,$3A ; CB 58 + DB $54,C0015 ; CALL C0015 +; 1870: prstr(err) + DB $66,$02 ; LLW 2 + DB $54,C0019 ; CALL C0019 +; 1871: crout() + DB $54,C0043 ; CALL C0043 +; 1872: fin +C0443: +C0444: +; 1873: return ERR_TKN + DB $00 ; ZERO + DB $5A ; LEAVE +; 1874: end +; 1875: ; +; 1876: ; Emit bytecode +; 1877: ; +; 1878: def ctag_new_01 +C0445: ; ctag_new_01() +; 1879: if codetag >= ctag_max + JSR INTERP + DB $6A,D0488 ; LAW D0488 + DB $2C,$80,$02 ; CW 640 + DB $48 ; ISGE + DB $4C,C0447 ; SKPFLS C0447 +; 1880: return parse_err_11(@ctag_full) + DB $26,D0800 ; LA D0800 + DB $54,C0441 ; CALL C0441 + DB $5C ; RET +; 1881: fin +C0447: +C0448: +; 1882: codetag = codetag + 1 + DB $6A,D0488 ; LAW D0488 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $7A,D0488 ; SAW D0488 +; 1883: ctag_value:[codetag] = 0 + DB $2C,$00,$08 ; CW 2048 + DB $6A,D0488 ; LAW D0488 + DB $1E ; IDXW + DB $00 ; ZERO + DB $72 ; SW +; 1884: ctag_flags.[codetag] = 0 + DB $2C,$80,$0D ; CW 3456 + DB $6A,D0488 ; LAW D0488 + DB $02 ; IDXB + DB $00 ; ZERO + DB $70 ; SB +; 1885: return codetag ? is_ctag + DB $6A,D0488 ; LAW D0488 + DB $2C,$00,$80 ; CW 32768 + DB $16 ; IOR + DB $5C ; RET +; 1886: end +; 1887: defopt ctag_resolve_21(tag, addr) +C0449: ; ctag_resolve_21() + ; tag = 2 + ; addr = 4 +; 1888: word updtptr, nextptr + ; updtptr = 6 + ; nextptr = 8 +; 1889: +; 1890: tag = tag & mask_ctag + LDY #10 + LDA #2 + JSR ENTER + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$FF + STA ESTKL,X + LDA #$7F + STA ESTKH,X + JSR BAND + LDY #$02 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 1891: if ctag_flags.[tag] & resolved + LDA #$80 + STA ESTKL,X + LDA #$0D + STA ESTKH,X + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JSR ADD + LDY #$00 + JSR LB + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR BAND + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0451 +: +; 1892: return parse_err_11(@dup_id) + DEX + LDA #D0538 + STA ESTKH,X + JSR C0441 + JMP LEAVE +; 1893: fin +C0451: +C0452: +; 1894: updtptr = ctag_value:[tag] + DEX + LDY #$00 + STY ESTKL,X + LDA #$08 + STA ESTKH,X + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JSR IDXW + LDY #$00 + JSR LW + LDY #$06 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 1895: while updtptr + INX +C0453: + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0454 +: +; 1896: ; +; 1897: ; Update list of addresses needing resolution +; 1898: ; +; 1899: nextptr = *updtptr + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR LW + LDY #$08 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 1900: *updtptr = addr + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR SW +; 1901: updtptr = nextptr + DEX + LDY #$08 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$06 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 1902: loop + INX + JMP C0453 +C0454: +; 1903: ctag_value:[tag] = addr + DEX + LDY #$00 + STY ESTKL,X + LDA #$08 + STA ESTKH,X + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JSR IDXW + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR SW +; 1904: ctag_flags.[tag] = ctag_flags.[tag] ? resolved + DEX + LDA #$80 + STA ESTKL,X + LDA #$0D + STA ESTKH,X + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JSR ADD + DEX + LDA #$80 + STA ESTKL,X + LDA #$0D + STA ESTKH,X + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JSR ADD + LDY #$00 + JSR LB + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR IOR + JSR SB +; 1905: return 0 + DEX + STY ESTKL,X + STY ESTKH,X + JMP LEAVE +; 1906: end +; 1907: defopt emit_byte_10(bval) +C0455: ; emit_byte_10() + ; bval = 2 +; 1908: ^codeptr = bval + LDY #4 + LDA #1 + JSR ENTER + DEX + LDA D0490 + STA ESTKL,X + LDA D0490+1 + STA ESTKH,X + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR SB +; 1909: codeptr = codeptr + 1 + DEX + LDA D0490 + STA ESTKL,X + LDA D0490+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0490 + LDA ESTKH,X + STA D0490+1 +; 1910: end + INX + JMP LEAVE +; 1911: defopt emit_word_10(wval) +C0457: ; emit_word_10() + ; wval = 2 +; 1912: *codeptr = wval + LDY #4 + LDA #1 + JSR ENTER + DEX + LDA D0490 + STA ESTKL,X + LDA D0490+1 + STA ESTKH,X + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR SW +; 1913: codeptr = codeptr + 2 + DEX + LDA D0490 + STA ESTKL,X + LDA D0490+1 + STA ESTKH,X + DEX + LDA #$02 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0490 + LDA ESTKH,X + STA D0490+1 +; 1914: end + INX + JMP LEAVE +; 1915: def emit_fill_10(size) +C0459: ; emit_fill_10() + ; size = 2 +; 1916: memset(0, codeptr, size) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $00 ; ZERO + DB $6A,D0490 ; LAW D0490 + DB $66,$02 ; LLW 2 + DB $54,C0011 ; CALL C0011 +; 1917: codeptr = codeptr + size + DB $6A,D0490 ; LAW D0490 + DB $66,$02 ; LLW 2 + DB $02 ; ADD + DB $7A,D0490 ; SAW D0490 +; 1918: end + DB $5A ; LEAVE +; 1919: def emit_codetag_10(tag) +C0461: ; emit_codetag_10() + ; tag = 2 +; 1920: drop ctag_resolve_21(tag, codeptr) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $66,$02 ; LLW 2 + DB $6A,D0490 ; LAW D0490 + DB $54,C0449 ; CALL C0449 + DB $30 ; DROP +; 1921: end + DB $5A ; LEAVE +; 1922: defopt emit_op_10(op) +C0463: ; emit_op_10() + ; op = 2 +; 1923: lastop = op + LDY #4 + LDA #1 + JSR ENTER + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDA ESTKL,X + STA D0494 +; 1924: ^codeptr = op + LDA D0490 + STA ESTKL,X + LDA D0490+1 + STA ESTKH,X + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR SB +; 1925: codeptr = codeptr + 1 + DEX + LDA D0490 + STA ESTKL,X + LDA D0490+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0490 + LDA ESTKH,X + STA D0490+1 +; 1926: end + INX + JMP LEAVE +; 1927: def emit_tag_10(tag) +C0465: ; emit_tag_10() + ; tag = 2 +; 1928: word updtptr + ; updtptr = 4 +; 1929: +; 1930: if tag & is_ctag + JSR INTERP + DB $58,$06,$01 ; ENTER 6,1 + DB $66,$02 ; LLW 2 + DB $2C,$00,$80 ; CW 32768 + DB $14 ; BAND + DB $4C,C0467 ; SKPFLS C0467 +; 1931: tag = tag & mask_ctag + DB $66,$02 ; LLW 2 + DB $2C,$FF,$7F ; CW 32767 + DB $14 ; BAND + DB $76,$02 ; SLW 2 +; 1932: updtptr = ctag_value:[tag] + DB $2C,$00,$08 ; CW 2048 + DB $66,$02 ; LLW 2 + DB $1E ; IDXW + DB $62 ; LW + DB $76,$04 ; SLW 4 +; 1933: if !(ctag_flags.[tag] & resolved) + DB $2C,$80,$0D ; CW 3456 + DB $66,$02 ; LLW 2 + DB $02 ; IDXB + DB $60 ; LB + DB $2A,$01 ; CB 1 + DB $14 ; BAND + DB $20 ; NOT + DB $4C,C0469 ; SKPFLS C0469 +; 1934: ; +; 1935: ; Add to list of tags needing resolution +; 1936: ; +; 1937: ctag_value:[tag] = codeptr + DB $2C,$00,$08 ; CW 2048 + DB $66,$02 ; LLW 2 + DB $1E ; IDXW + DB $6A,D0490 ; LAW D0490 + DB $72 ; SW +; 1938: fin +C0469: +C0470: +; 1939: emit_word_10(updtptr) + DB $66,$04 ; LLW 4 + DB $54,C0457 ; CALL C0457 +; 1940: else + DB $50,C0468 ; SKIP C0468 +C0467: +; 1941: emit_word_10(tag + codebuff) + DB $66,$02 ; LLW 2 + DB $2C,$00,$A8 ; CW 43008 + DB $02 ; ADD + DB $54,C0457 ; CALL C0457 +; 1942: fin +C0468: +; 1943: end + DB $5A ; LEAVE +; 1944: def emit_iddata_30(value, size, namestr) +C0471: ; emit_iddata_30() + ; value = 2 + ; size = 4 + ; namestr = 6 +; 1945: emit_fill_10(size) + JSR INTERP + DB $58,$08,$03 ; ENTER 8,3 + DB $66,$04 ; LLW 4 + DB $54,C0459 ; CALL C0459 +; 1946: end + DB $5A ; LEAVE +; 1947: def emit_data_41(vartype, consttype, constval, constsize) +C0473: ; emit_data_41() + ; vartype = 2 + ; consttype = 4 + ; constval = 6 + ; constsize = 8 +; 1948: byte i + ; i = 10 +; 1949: word size, chrptr + ; size = 11 + ; chrptr = 13 +; 1950: +; 1951: if consttype == 0 + JSR INTERP + DB $58,$0F,$04 ; ENTER 15,4 + DB $66,$04 ; LLW 4 + DB $00 ; ZERO + DB $40 ; ISEQ + DB $4C,C0475 ; SKPFLS C0475 +; 1952: size = constsize + DB $66,$08 ; LLW 8 + DB $76,$0B ; SLW 11 +; 1953: emit_fill_10(constsize) + DB $66,$08 ; LLW 8 + DB $54,C0459 ; CALL C0459 +; 1954: elsif consttype == STR_TYPE + DB $50,C0476 ; SKIP C0476 +C0475: + DB $66,$04 ; LLW 4 + DB $2A,$80 ; CB 128 + DB $40 ; ISEQ + DB $4C,C0477 ; SKPFLS C0477 +; 1955: size = constsize + DB $66,$08 ; LLW 8 + DB $76,$0B ; SLW 11 +; 1956: chrptr = constval + DB $66,$06 ; LLW 6 + DB $76,$0D ; SLW 13 +; 1957: constsize = constsize - 1 + DB $66,$08 ; LLW 8 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $76,$08 ; SLW 8 +; 1958: emit_byte_10(constsize) + DB $66,$08 ; LLW 8 + DB $54,C0455 ; CALL C0455 +; 1959: while constsize > 0 +C0478: + DB $66,$08 ; LLW 8 + DB $00 ; ZERO + DB $44 ; ISGT + DB $4C,C0479 ; SKPFLS C0479 +; 1960: emit_byte_10(^chrptr) + DB $66,$0D ; LLW 13 + DB $60 ; LB + DB $54,C0455 ; CALL C0455 +; 1961: chrptr = chrptr + 1 + DB $66,$0D ; LLW 13 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $76,$0D ; SLW 13 +; 1962: constsize = constsize - 1 + DB $66,$08 ; LLW 8 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $76,$08 ; SLW 8 +; 1963: loop + DB $50,C0478 ; SKIP C0478 +C0479: +; 1964: else + DB $50,C0476 ; SKIP C0476 +C0477: +; 1965: if vartype == WORD_TYPE + DB $66,$02 ; LLW 2 + DB $2A,$04 ; CB 4 + DB $40 ; ISEQ + DB $4C,C0480 ; SKPFLS C0480 +; 1966: size = 2 + DB $2A,$02 ; CB 2 + DB $76,$0B ; SLW 11 +; 1967: emit_word_10(constval) + DB $66,$06 ; LLW 6 + DB $54,C0457 ; CALL C0457 +; 1968: else + DB $50,C0481 ; SKIP C0481 +C0480: +; 1969: size = 1 + DB $2A,$01 ; CB 1 + DB $76,$0B ; SLW 11 +; 1970: emit_byte_10(constval) + DB $66,$06 ; LLW 6 + DB $54,C0455 ; CALL C0455 +; 1971: fin +C0481: +; 1972: fin +C0476: +; 1973: return size + DB $66,$0B ; LLW 11 + DB $5A ; LEAVE +; 1974: end +; 1975: def emit_const_10(cval) +C0482: ; emit_const_10() + ; cval = 2 +; 1976: if cval == 0 + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $66,$02 ; LLW 2 + DB $00 ; ZERO + DB $40 ; ISEQ + DB $4C,C0484 ; SKPFLS C0484 +; 1977: emit_op_10($00) + DB $00 ; ZERO + DB $54,C0463 ; CALL C0463 +; 1978: elsif cval > 0 and cval < 256 + DB $50,C0485 ; SKIP C0485 +C0484: + DB $66,$02 ; LLW 2 + DB $00 ; ZERO + DB $44 ; ISGT + DB $66,$02 ; LLW 2 + DB $2C,$00,$01 ; CW 256 + DB $46 ; ISLT + DB $24 ; LAND + DB $4C,C0486 ; SKPFLS C0486 +; 1979: emit_op_10($2A) + DB $2A,$2A ; CB 42 + DB $54,C0463 ; CALL C0463 +; 1980: emit_byte_10(cval) + DB $66,$02 ; LLW 2 + DB $54,C0455 ; CALL C0455 +; 1981: else + DB $50,C0485 ; SKIP C0485 +C0486: +; 1982: emit_op_10($2C) + DB $2A,$2C ; CB 44 + DB $54,C0463 ; CALL C0463 +; 1983: emit_word_10(cval) + DB $66,$02 ; LLW 2 + DB $54,C0457 ; CALL C0457 +; 1984: fin +C0485: +; 1985: end + DB $5A ; LEAVE +; 1986: def emit_lb +C0487: ; emit_lb() +; 1987: emit_op_10($60) + JSR INTERP + DB $2A,$60 ; CB 96 + DB $54,C0463 ; CALL C0463 +; 1988: end + DB $5C ; RET +; 1989: def emit_lw +C0489: ; emit_lw() +; 1990: emit_op_10($62) + JSR INTERP + DB $2A,$62 ; CB 98 + DB $54,C0463 ; CALL C0463 +; 1991: end + DB $5C ; RET +; 1992: def emit_llb_10(index) +C0491: ; emit_llb_10() + ; index = 2 +; 1993: emit_op_10($64) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$64 ; CB 100 + DB $54,C0463 ; CALL C0463 +; 1994: emit_byte_10(index) + DB $66,$02 ; LLW 2 + DB $54,C0455 ; CALL C0455 +; 1995: end + DB $5A ; LEAVE +; 1996: def emit_llw_10(index) +C0493: ; emit_llw_10() + ; index = 2 +; 1997: emit_op_10($66) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$66 ; CB 102 + DB $54,C0463 ; CALL C0463 +; 1998: emit_byte_10(index) + DB $66,$02 ; LLW 2 + DB $54,C0455 ; CALL C0455 +; 1999: end + DB $5A ; LEAVE +; 2000: def emit_lab_10(tag) +C0495: ; emit_lab_10() + ; tag = 2 +; 2001: emit_op_10($68) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$68 ; CB 104 + DB $54,C0463 ; CALL C0463 +; 2002: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0465 ; CALL C0465 +; 2003: end + DB $5A ; LEAVE +; 2004: def emit_law_10(tag) +C0497: ; emit_law_10() + ; tag = 2 +; 2005: emit_op_10($6A) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$6A ; CB 106 + DB $54,C0463 ; CALL C0463 +; 2006: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0465 ; CALL C0465 +; 2007: end + DB $5A ; LEAVE +; 2008: def emit_sb +C0499: ; emit_sb() +; 2009: emit_op_10($70) + JSR INTERP + DB $2A,$70 ; CB 112 + DB $54,C0463 ; CALL C0463 +; 2010: end + DB $5C ; RET +; 2011: def emit_sw +C0501: ; emit_sw() +; 2012: emit_op_10($72) + JSR INTERP + DB $2A,$72 ; CB 114 + DB $54,C0463 ; CALL C0463 +; 2013: end + DB $5C ; RET +; 2014: def emit_slb_10(index) +C0503: ; emit_slb_10() + ; index = 2 +; 2015: emit_op_10($74) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$74 ; CB 116 + DB $54,C0463 ; CALL C0463 +; 2016: emit_byte_10(index) + DB $66,$02 ; LLW 2 + DB $54,C0455 ; CALL C0455 +; 2017: end + DB $5A ; LEAVE +; 2018: def emit_slw_10(index) +C0505: ; emit_slw_10() + ; index = 2 +; 2019: emit_op_10($76) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$76 ; CB 118 + DB $54,C0463 ; CALL C0463 +; 2020: emit_byte_10(index) + DB $66,$02 ; LLW 2 + DB $54,C0455 ; CALL C0455 +; 2021: end + DB $5A ; LEAVE +; 2022: def emit_dlb_10(index) +C0507: ; emit_dlb_10() + ; index = 2 +; 2023: emit_op_10($6C) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$6C ; CB 108 + DB $54,C0463 ; CALL C0463 +; 2024: emit_byte_10(index) + DB $66,$02 ; LLW 2 + DB $54,C0455 ; CALL C0455 +; 2025: end + DB $5A ; LEAVE +; 2026: def emit_dlw_10(index) +C0509: ; emit_dlw_10() + ; index = 2 +; 2027: emit_op_10($6E) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$6E ; CB 110 + DB $54,C0463 ; CALL C0463 +; 2028: emit_byte_10(index) + DB $66,$02 ; LLW 2 + DB $54,C0455 ; CALL C0455 +; 2029: end + DB $5A ; LEAVE +; 2030: def emit_sab_10(tag) +C0511: ; emit_sab_10() + ; tag = 2 +; 2031: emit_op_10($78) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$78 ; CB 120 + DB $54,C0463 ; CALL C0463 +; 2032: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0465 ; CALL C0465 +; 2033: end + DB $5A ; LEAVE +; 2034: def emit_saw_10(tag) +C0513: ; emit_saw_10() + ; tag = 2 +; 2035: emit_op_10($7A) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$7A ; CB 122 + DB $54,C0463 ; CALL C0463 +; 2036: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0465 ; CALL C0465 +; 2037: end + DB $5A ; LEAVE +; 2038: def emit_dab_10(tag) +C0515: ; emit_dab_10() + ; tag = 2 +; 2039: emit_op_10($7C) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$7C ; CB 124 + DB $54,C0463 ; CALL C0463 +; 2040: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0465 ; CALL C0465 +; 2041: end + DB $5A ; LEAVE +; 2042: def emit_daw_10(tag) +C0517: ; emit_daw_10() + ; tag = 2 +; 2043: emit_op_10($7E) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$7E ; CB 126 + DB $54,C0463 ; CALL C0463 +; 2044: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0465 ; CALL C0465 +; 2045: end + DB $5A ; LEAVE +; 2046: def emit_call_10(tag) +C0519: ; emit_call_10() + ; tag = 2 +; 2047: emit_op_10($54) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$54 ; CB 84 + DB $54,C0463 ; CALL C0463 +; 2048: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0465 ; CALL C0465 +; 2049: end + DB $5A ; LEAVE +; 2050: def emit_ical +C0521: ; emit_ical() +; 2051: emit_op_10($56) + JSR INTERP + DB $2A,$56 ; CB 86 + DB $54,C0463 ; CALL C0463 +; 2052: end + DB $5C ; RET +; 2053: def emit_push +C0523: ; emit_push() +; 2054: emit_op_10($34) + JSR INTERP + DB $2A,$34 ; CB 52 + DB $54,C0463 ; CALL C0463 +; 2055: end + DB $5C ; RET +; 2056: def emit_pull +C0525: ; emit_pull() +; 2057: ; +; 2058: ; Skip if last op was push +; 2059: ; +; 2060: if lastop == $34 + JSR INTERP + DB $68,D0494 ; LAB D0494 + DB $2A,$34 ; CB 52 + DB $40 ; ISEQ + DB $4C,C0527 ; SKPFLS C0527 +; 2061: codeptr = codeptr - 1 + DB $6A,D0490 ; LAW D0490 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $7A,D0490 ; SAW D0490 +; 2062: lastop = $FF + DB $2A,$FF ; CB 255 + DB $78,D0494 ; SAB D0494 +; 2063: else + DB $50,C0528 ; SKIP C0528 +C0527: +; 2064: emit_op_10($36) + DB $2A,$36 ; CB 54 + DB $54,C0463 ; CALL C0463 +; 2065: fin +C0528: +; 2066: end + DB $5C ; RET +; 2067: def emit_localaddr_10(index) +C0529: ; emit_localaddr_10() + ; index = 2 +; 2068: emit_op_10($28) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$28 ; CB 40 + DB $54,C0463 ; CALL C0463 +; 2069: emit_byte_10(index) + DB $66,$02 ; LLW 2 + DB $54,C0455 ; CALL C0455 +; 2070: end + DB $5A ; LEAVE +; 2071: def emit_globaladdr_10(tag) +C0531: ; emit_globaladdr_10() + ; tag = 2 +; 2072: emit_op_10($26) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$26 ; CB 38 + DB $54,C0463 ; CALL C0463 +; 2073: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0465 ; CALL C0465 +; 2074: end + DB $5A ; LEAVE +; 2075: def emit_indexbyte +C0533: ; emit_indexbyte() +; 2076: emit_op_10($02) + JSR INTERP + DB $2A,$02 ; CB 2 + DB $54,C0463 ; CALL C0463 +; 2077: end + DB $5C ; RET +; 2078: def emit_indexword +C0535: ; emit_indexword() +; 2079: emit_op_10($1E) + JSR INTERP + DB $2A,$1E ; CB 30 + DB $54,C0463 ; CALL C0463 +; 2080: end + DB $5C ; RET +; 2081: defopt emit_unaryop_11(op) +C0537: ; emit_unaryop_11() + ; op = 2 +; 2082: when op + LDY #4 + LDA #1 + JSR ENTER + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X +; 2083: is NEG_TKN + DEX + LDA #$AD + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0540 +: +; 2084: emit_op_10($10) + DEX + LDA #$10 + STA ESTKL,X + STY ESTKH,X + JSR C0463 +; 2085: is COMP_TKN + JMP C0539 +C0540: + DEX + LDA #$A3 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0541 +: +; 2086: emit_op_10($12) + DEX + LDA #$12 + STA ESTKL,X + STY ESTKH,X + JSR C0463 +; 2087: is LOGIC_NOT_TKN + JMP C0539 +C0541: + DEX + LDA #$A1 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0542 +: +; 2088: emit_op_10($20) + DEX + LDA #$20 + STA ESTKL,X + STY ESTKH,X + JSR C0463 +; 2089: is INC_TKN + JMP C0539 +C0542: + DEX + LDA #$C1 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0543 +: +; 2090: emit_op_10($0C) + DEX + LDA #$0C + STA ESTKL,X + STY ESTKH,X + JSR C0463 +; 2091: is DEC_TKN + JMP C0539 +C0543: + DEX + LDA #$C4 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0544 +: +; 2092: emit_op_10($0E) + DEX + LDA #$0E + STA ESTKL,X + STY ESTKH,X + JSR C0463 +; 2093: is BPTR_TKN + JMP C0539 +C0544: + DEX + LDA #$DE + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0545 +: +; 2094: emit_op_10($60) + DEX + LDA #$60 + STA ESTKL,X + STY ESTKH,X + JSR C0463 +; 2095: is WPTR_TKN + JMP C0539 +C0545: + DEX + LDA #$AA + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0546 +: +; 2096: emit_op_10($62) + DEX + LDA #$62 + STA ESTKL,X + STY ESTKH,X + JSR C0463 +; 2097: otherwise + JMP C0539 +C0546: +; 2098: return FALSE + LDY #$00 + STY ESTKL,X + STY ESTKH,X + JMP LEAVE +; 2099: wend +C0539: +; 2100: return TRUE + LDA #$FF + STA ESTKL,X + STA ESTKH,X + JMP LEAVE +; 2101: end +; 2102: defopt emit_binaryop_11(op) +C0548: ; emit_binaryop_11() + ; op = 2 +; 2103: when op + LDY #4 + LDA #1 + JSR ENTER + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X +; 2104: is MUL_TKN + DEX + LDA #$AA + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0551 +: +; 2105: ; +; 2106: ; Replace MUL 2 with SHL 1 +; 2107: ; +; 2108: if lastop == $2A and ^(codeptr - 1) == 2 ; CB 2 + DEX + LDA D0494 + STA ESTKL,X + STY ESTKH,X + DEX + LDA #$2A + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + DEX + LDA D0490 + STA ESTKL,X + LDA D0490+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SUB + JSR LB + DEX + LDA #$02 + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + JSR LAND + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0552 +: +; 2109: codeptr = codeptr - 1 + DEX + LDA D0490 + STA ESTKL,X + LDA D0490+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SUB + LDA ESTKL,X + STA D0490 + LDA ESTKH,X + STA D0490+1 +; 2110: emit_byte_10(1) ; CB 1 + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR C0455 +; 2111: emit_op_10($1A) ; SHL + DEX + LDA #$1A + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR C0463 +; 2112: else + JMP C0553 +C0552: +; 2113: emit_op_10($06) + DEX + LDA #$06 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR C0463 +; 2114: fin +C0553: +; 2115: is DIV_TKN + JMP C0550 +C0551: + DEX + LDA #$AF + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0554 +: +; 2116: ; +; 2117: ; Replace DIV 2 with SHR 1 +; 2118: ; +; 2119: if lastop == $2A and ^(codeptr - 1) == 2 ; CB 2 + DEX + LDA D0494 + STA ESTKL,X + STY ESTKH,X + DEX + LDA #$2A + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + DEX + LDA D0490 + STA ESTKL,X + LDA D0490+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SUB + JSR LB + DEX + LDA #$02 + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + JSR LAND + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0555 +: +; 2120: codeptr = codeptr - 1 + DEX + LDA D0490 + STA ESTKL,X + LDA D0490+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SUB + LDA ESTKL,X + STA D0490 + LDA ESTKH,X + STA D0490+1 +; 2121: emit_byte_10(1) ; CB 1 + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR C0455 +; 2122: emit_op_10($1C) ; SHR + DEX + LDA #$1C + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR C0463 +; 2123: else + JMP C0556 +C0555: +; 2124: emit_op_10($08) + DEX + LDA #$08 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR C0463 +; 2125: fin +C0556: +; 2126: is MOD_TKN + JMP C0550 +C0554: + DEX + LDA #$A5 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0557 +: +; 2127: emit_op_10($0A) + DEX + LDA #$0A + STA ESTKL,X + STY ESTKH,X + JSR C0463 +; 2128: is ADD_TKN + JMP C0550 +C0557: + DEX + LDA #$AB + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0558 +: +; 2129: ; +; 2130: ; Replace ADD 1 with INCR +; 2131: ; +; 2132: if lastop == $2A and ^(codeptr - 1) == 1 ; CB 1 + DEX + LDA D0494 + STA ESTKL,X + STY ESTKH,X + DEX + LDA #$2A + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + DEX + LDA D0490 + STA ESTKL,X + LDA D0490+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SUB + JSR LB + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + JSR LAND + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0559 +: +; 2133: codeptr = codeptr - 2 + DEX + LDA D0490 + STA ESTKL,X + LDA D0490+1 + STA ESTKH,X + DEX + LDA #$02 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SUB + LDA ESTKL,X + STA D0490 + LDA ESTKH,X + STA D0490+1 +; 2134: emit_op_10($0C) ; INC_OP + LDA #$0C + STA ESTKL,X + STY ESTKH,X + JSR C0463 +; 2135: else + JMP C0560 +C0559: +; 2136: emit_op_10($02) + DEX + LDA #$02 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR C0463 +; 2137: fin +C0560: +; 2138: is SUB_TKN + JMP C0550 +C0558: + DEX + LDA #$AD + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0561 +: +; 2139: ; +; 2140: ; Replace SUB 1 with DECR +; 2141: ; +; 2142: if lastop == $2A and ^(codeptr - 1) == 1 ; CB 1 + DEX + LDA D0494 + STA ESTKL,X + STY ESTKH,X + DEX + LDA #$2A + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + DEX + LDA D0490 + STA ESTKL,X + LDA D0490+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SUB + JSR LB + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + JSR LAND + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0562 +: +; 2143: codeptr = codeptr - 2 + DEX + LDA D0490 + STA ESTKL,X + LDA D0490+1 + STA ESTKH,X + DEX + LDA #$02 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SUB + LDA ESTKL,X + STA D0490 + LDA ESTKH,X + STA D0490+1 +; 2144: emit_op_10($0E) ; DEC_OP + LDA #$0E + STA ESTKL,X + STY ESTKH,X + JSR C0463 +; 2145: else + JMP C0563 +C0562: +; 2146: emit_op_10($04) + DEX + LDA #$04 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR C0463 +; 2147: fin +C0563: +; 2148: is SHL_TKN + JMP C0550 +C0561: + DEX + LDA #$CC + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0564 +: +; 2149: emit_op_10($1A) + DEX + LDA #$1A + STA ESTKL,X + STY ESTKH,X + JSR C0463 +; 2150: is SHR_TKN + JMP C0550 +C0564: + DEX + LDA #$D2 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0565 +: +; 2151: emit_op_10($1C) + DEX + LDA #$1C + STA ESTKL,X + STY ESTKH,X + JSR C0463 +; 2152: is AND_TKN + JMP C0550 +C0565: + DEX + LDA #$A6 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0566 +: +; 2153: emit_op_10($14) + DEX + LDA #$14 + STA ESTKL,X + STY ESTKH,X + JSR C0463 +; 2154: is OR_TKN + JMP C0550 +C0566: + DEX + LDA #$BF + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0567 +: +; 2155: emit_op_10($16) + DEX + LDA #$16 + STA ESTKL,X + STY ESTKH,X + JSR C0463 +; 2156: is EOR_TKN + JMP C0550 +C0567: + DEX + LDA #$DE + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0568 +: +; 2157: emit_op_10($18) + DEX + LDA #$18 + STA ESTKL,X + STY ESTKH,X + JSR C0463 +; 2158: is EQ_TKN + JMP C0550 +C0568: + DEX + LDA #$C5 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0569 +: +; 2159: emit_op_10($40) + DEX + LDA #$40 + STA ESTKL,X + STY ESTKH,X + JSR C0463 +; 2160: is NE_TKN + JMP C0550 +C0569: + DEX + LDA #$D5 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0570 +: +; 2161: emit_op_10($42) + DEX + LDA #$42 + STA ESTKL,X + STY ESTKH,X + JSR C0463 +; 2162: is GE_TKN + JMP C0550 +C0570: + DEX + LDA #$C8 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0571 +: +; 2163: emit_op_10($48) + DEX + LDA #$48 + STA ESTKL,X + STY ESTKH,X + JSR C0463 +; 2164: is LT_TKN + JMP C0550 +C0571: + DEX + LDA #$BC + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0572 +: +; 2165: emit_op_10($46) + DEX + LDA #$46 + STA ESTKL,X + STY ESTKH,X + JSR C0463 +; 2166: is GT_TKN + JMP C0550 +C0572: + DEX + LDA #$BE + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0573 +: +; 2167: emit_op_10($44) + DEX + LDA #$44 + STA ESTKL,X + STY ESTKH,X + JSR C0463 +; 2168: is LE_TKN + JMP C0550 +C0573: + DEX + LDA #$C2 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0574 +: +; 2169: emit_op_10($4A) + DEX + LDA #$4A + STA ESTKL,X + STY ESTKH,X + JSR C0463 +; 2170: is LOGIC_OR_TKN + JMP C0550 +C0574: + DEX + LDA #$CF + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0575 +: +; 2171: emit_op_10($22) + DEX + LDA #$22 + STA ESTKL,X + STY ESTKH,X + JSR C0463 +; 2172: is LOGIC_AND_TKN + JMP C0550 +C0575: + DEX + LDA #$CE + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0576 +: +; 2173: emit_op_10($24) + DEX + LDA #$24 + STA ESTKL,X + STY ESTKH,X + JSR C0463 +; 2174: is COMMA_TKN + JMP C0550 +C0576: + DEX + LDA #$AC + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE :+ + LDA ESTKH-1,X + CMP ESTKH,X + BEQ :++ +: JMP C0577 +: +; 2175: ; Do nothing except move to next stanza in expression +; 2176: otherwise + JMP C0550 +C0577: +; 2177: return FALSE + LDY #$00 + STY ESTKL,X + STY ESTKH,X + JMP LEAVE +; 2178: wend +C0550: +; 2179: return TRUE + LDA #$FF + STA ESTKL,X + STA ESTKH,X + JMP LEAVE +; 2180: end +; 2181: def emit_brtru_10(tag) +C0579: ; emit_brtru_10() + ; tag = 2 +; 2182: emit_op_10($4E) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$4E ; CB 78 + DB $54,C0463 ; CALL C0463 +; 2183: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0465 ; CALL C0465 +; 2184: end + DB $5A ; LEAVE +; 2185: def emit_brfls_10(tag) +C0581: ; emit_brfls_10() + ; tag = 2 +; 2186: emit_op_10($4C) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$4C ; CB 76 + DB $54,C0463 ; CALL C0463 +; 2187: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0465 ; CALL C0465 +; 2188: end + DB $5A ; LEAVE +; 2189: def emit_brgt_10(tag) +C0583: ; emit_brgt_10() + ; tag = 2 +; 2190: emit_op_10($3A) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$3A ; CB 58 + DB $54,C0463 ; CALL C0463 +; 2191: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0465 ; CALL C0465 +; 2192: end + DB $5A ; LEAVE +; 2193: def emit_brlt_10(tag) +C0585: ; emit_brlt_10() + ; tag = 2 +; 2194: emit_op_10($38) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$38 ; CB 56 + DB $54,C0463 ; CALL C0463 +; 2195: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0465 ; CALL C0465 +; 2196: end + DB $5A ; LEAVE +; 2197: def emit_brne_10(tag) +C0587: ; emit_brne_10() + ; tag = 2 +; 2198: emit_op_10($3E) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$3E ; CB 62 + DB $54,C0463 ; CALL C0463 +; 2199: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0465 ; CALL C0465 +; 2200: end + DB $5A ; LEAVE +; 2201: def emit_jump_10(tag) +C0589: ; emit_jump_10() + ; tag = 2 +; 2202: emit_op_10($50) + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $2A,$50 ; CB 80 + DB $54,C0463 ; CALL C0463 +; 2203: emit_tag_10(tag) + DB $66,$02 ; LLW 2 + DB $54,C0465 ; CALL C0465 +; 2204: end + DB $5A ; LEAVE +; 2205: def emit_drop +C0591: ; emit_drop() +; 2206: emit_op_10($30) + JSR INTERP + DB $2A,$30 ; CB 48 + DB $54,C0463 ; CALL C0463 +; 2207: end + DB $5C ; RET +; 2208: def emit_swap +C0593: ; emit_swap() +; 2209: emit_op_10($2E) + JSR INTERP + DB $2A,$2E ; CB 46 + DB $54,C0463 ; CALL C0463 +; 2210: end + DB $5C ; RET +; 2211: def emit_leave_10(framesize) +C0595: ; emit_leave_10() + ; framesize = 2 +; 2212: if framesize > 2 + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $66,$02 ; LLW 2 + DB $2A,$02 ; CB 2 + DB $44 ; ISGT + DB $4C,C0597 ; SKPFLS C0597 +; 2213: emit_op_10($5A) + DB $2A,$5A ; CB 90 + DB $54,C0463 ; CALL C0463 +; 2214: else + DB $50,C0598 ; SKIP C0598 +C0597: +; 2215: emit_op_10($5C) + DB $2A,$5C ; CB 92 + DB $54,C0463 ; CALL C0463 +; 2216: fin +C0598: +; 2217: end + DB $5A ; LEAVE +; 2218: def emit_enter_20(framesize, cparams) +C0599: ; emit_enter_20() + ; framesize = 2 + ; cparams = 4 +; 2219: emit_byte_10(emit_enter_20.[0]) + JSR INTERP + DB $58,$06,$02 ; ENTER 6,2 + DB $26,C0599 ; LA C0599 + DB $00 ; ZERO + DB $02 ; IDXB + DB $60 ; LB + DB $54,C0455 ; CALL C0455 +; 2220: emit_byte_10(emit_enter_20.[1]) + DB $26,C0599 ; LA C0599 + DB $2A,$01 ; CB 1 + DB $02 ; IDXB + DB $60 ; LB + DB $54,C0455 ; CALL C0455 +; 2221: emit_byte_10(emit_enter_20.[2]) + DB $26,C0599 ; LA C0599 + DB $2A,$02 ; CB 2 + DB $02 ; IDXB + DB $60 ; LB + DB $54,C0455 ; CALL C0455 +; 2222: if framesize > 2 + DB $66,$02 ; LLW 2 + DB $2A,$02 ; CB 2 + DB $44 ; ISGT + DB $4C,C0601 ; SKPFLS C0601 +; 2223: emit_op_10($58) + DB $2A,$58 ; CB 88 + DB $54,C0463 ; CALL C0463 +; 2224: emit_byte_10(framesize) + DB $66,$02 ; LLW 2 + DB $54,C0455 ; CALL C0455 +; 2225: emit_byte_10(cparams) + DB $66,$04 ; LLW 4 + DB $54,C0455 ; CALL C0455 +; 2226: fin +C0601: +C0602: +; 2227: end + DB $5A ; LEAVE +; 2228: def emit_start +C0603: ; emit_start() +; 2229: ; +; 2230: ; Save address +; 2231: ; +; 2232: entrypoint = codeptr + JSR INTERP + DB $6A,D0490 ; LAW D0490 + DB $7A,D0492 ; SAW D0492 +; 2233: emit_byte_10(emit_start.[0]) + DB $26,C0603 ; LA C0603 + DB $00 ; ZERO + DB $02 ; IDXB + DB $60 ; LB + DB $54,C0455 ; CALL C0455 +; 2234: emit_byte_10(emit_start.[1]) + DB $26,C0603 ; LA C0603 + DB $2A,$01 ; CB 1 + DB $02 ; IDXB + DB $60 ; LB + DB $54,C0455 ; CALL C0455 +; 2235: emit_byte_10(emit_start.[2]) + DB $26,C0603 ; LA C0603 + DB $2A,$02 ; CB 2 + DB $02 ; IDXB + DB $60 ; LB + DB $54,C0455 ; CALL C0455 +; 2236: end + DB $5C ; RET +; 2237: def emit_exit +C0605: ; emit_exit() +; 2238: emit_op_10($00) + JSR INTERP + DB $00 ; ZERO + DB $54,C0463 ; CALL C0463 +; 2239: emit_op_10($5C) + DB $2A,$5C ; CB 92 + DB $54,C0463 ; CALL C0463 +; 2240: end + DB $5C ; RET +; 2241: ; +; 2242: ; Lexical anaylzer +; 2243: ; +; 2244: ;def isalpha_11(c) +; 2245: ; if c >= 'A' and c <= 'Z' +; 2246: ; return TRUE +; 2247: ; elsif c >= 'a' and c <= 'z' +; 2248: ; return TRUE +; 2249: ; elsif c == '_' +; 2250: ; return TRUE +; 2251: ; fin +; 2252: ; return FALSE +; 2253: ;end +; 2254: asm isalpha_11 +C0607: ; isalpha_11() +; 2255: LDY #$00 + LDY #$00 +; 2256: LDA ESTKL,X + LDA ESTKL,X +; 2257: CMP #'A' + CMP #'A' +; 2258: BCC ISALRET + BCC ISALRET +; 2259: CMP #'Z'+1 + CMP #'Z'+1 +; 2260: BCS :+ + BCS :+ +; 2261: DEY + DEY +; 2262: BNE ISALRET + BNE ISALRET +; 2263: : CMP #'a' +: CMP #'a' +; 2264: BCC ISALRET + BCC ISALRET +; 2265: CMP #'z'+1 + CMP #'z'+1 +; 2266: BCS :+ + BCS :+ +; 2267: DEY + DEY +; 2268: BNE ISALRET + BNE ISALRET +; 2269: : CMP #'_' +: CMP #'_' +; 2270: BNE ISALRET + BNE ISALRET +; 2271: DEY + DEY +; 2272: ISALRET: +ISALRET: +; 2273: STY ESTKL,X + STY ESTKL,X +; 2274: STY ESTKH,X + STY ESTKH,X +; 2275: RTS + RTS +; 2276: end + RTS +; 2277: ;def isnum_11(c) +; 2278: ; if c >= '0' and c <= '9' +; 2279: ; return TRUE +; 2280: ; fin +; 2281: ; return FALSE +; 2282: ;end +; 2283: asm isnum_11 +C0609: ; isnum_11() +; 2284: LDY #$00 + LDY #$00 +; 2285: LDA ESTKL,X + LDA ESTKL,X +; 2286: CMP #'0' + CMP #'0' +; 2287: BCC :+ + BCC :+ +; 2288: CMP #'9'+1 + CMP #'9'+1 +; 2289: BCS :+ + BCS :+ +; 2290: DEY + DEY +; 2291: : STY ESTKL,X +: STY ESTKL,X +; 2292: STY ESTKH,X + STY ESTKH,X +; 2293: RTS + RTS +; 2294: end + RTS +; 2295: ;def isalphanum_11(c) +; 2296: ; if c >= 'A' and c <= 'Z' +; 2297: ; return TRUE +; 2298: ; elsif c >= '0' and c <= '9' +; 2299: ; return TRUE +; 2300: ; elsif c >= 'a' and c <= 'z' +; 2301: ; return TRUE +; 2302: ; elsif c == '_' +; 2303: ; return TRUE +; 2304: ; fin +; 2305: ; return FALSE +; 2306: ;end +; 2307: asm isalphanum_11 +C0611: ; isalphanum_11() +; 2308: LDY #$00 + LDY #$00 +; 2309: LDA ESTKL,X + LDA ESTKL,X +; 2310: CMP #'0' + CMP #'0' +; 2311: BCC ISANRET + BCC ISANRET +; 2312: CMP #'9'+1 + CMP #'9'+1 +; 2313: BCS :+ + BCS :+ +; 2314: DEY + DEY +; 2315: BNE ISANRET + BNE ISANRET +; 2316: : CMP #'A' +: CMP #'A' +; 2317: BCC ISANRET + BCC ISANRET +; 2318: CMP #'Z'+1 + CMP #'Z'+1 +; 2319: BCS :+ + BCS :+ +; 2320: DEY + DEY +; 2321: BNE ISANRET + BNE ISANRET +; 2322: : CMP #'a' +: CMP #'a' +; 2323: BCC :+ + BCC :+ +; 2324: CMP #'z'+1 + CMP #'z'+1 +; 2325: BCS ISANRET + BCS ISANRET +; 2326: DEY + DEY +; 2327: BNE ISANRET + BNE ISANRET +; 2328: : CMP #'_' +: CMP #'_' +; 2329: BNE ISANRET + BNE ISANRET +; 2330: DEY + DEY +; 2331: ISANRET: +ISANRET: +; 2332: STY ESTKL,X + STY ESTKL,X +; 2333: STY ESTKH,X + STY ESTKH,X +; 2334: RTS + RTS +; 2335: end + RTS +; 2336: defopt keymatch_21(chrptr, len) +C0613: ; keymatch_21() + ; chrptr = 2 + ; len = 4 +; 2337: byte i, keypos + ; i = 6 + ; keypos = 7 +; 2338: +; 2339: keypos = 0 + LDY #8 + LDA #2 + JSR ENTER + DEX + STY ESTKL,X + STY ESTKH,X + LDY #$07 + LDA ESTKL,X + STA (FRMP),Y +; 2340: while keywrds[keypos] < len + INX +C0615: + DEX + LDA #D0212 + STA ESTKH,X + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR ISLT + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0616 +: +; 2341: keypos = keypos + keywrds[keypos] + 2 + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA #D0212 + STA ESTKH,X + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + JSR ADD + DEX + LDA #$02 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDY #$07 + LDA ESTKL,X + STA (FRMP),Y +; 2342: loop + INX + JMP C0615 +C0616: +; 2343: while keywrds[keypos] == len +C0617: + DEX + LDA #D0212 + STA ESTKH,X + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0618 +: +; 2344: for i = 1 to len + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X +C0620: + LDY #$06 + LDA ESTKL,X + STA (FRMP),Y + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + LDA ESTKH-1,X + SBC ESTKH,X + BPL :+ + JMP C0619 +: + INC ESTKL,X + BNE :+ + INC ESTKH,X +: +; 2345: if toupper_11((chrptr).[i - 1]) <> keywrds[keypos + i] + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR SUB + JSR ADD + JSR LB + JSR C0127 + DEX + LDA #D0212 + STA ESTKH,X + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR ADD + JSR LB + JSR ISNE + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0621 +: +; 2346: break + JMP C0619 +; 2347: fin +C0621: +C0622: +; 2348: next + JMP C0620 +C0619: +; 2349: if i > len + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR ISGT + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0623 +: +; 2350: return keywrds[keypos + keywrds[keypos] + 1] + DEX + LDA #D0212 + STA ESTKH,X + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA #D0212 + STA ESTKH,X + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + JSR ADD + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR ADD + JSR ADD + JSR LB + JMP LEAVE +; 2351: fin +C0623: +C0624: +; 2352: keypos = keypos + keywrds[keypos] + 2 + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA #D0212 + STA ESTKH,X + DEX + LDY #$07 + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + JSR ADD + DEX + LDA #$02 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDY #$07 + LDA ESTKL,X + STA (FRMP),Y +; 2353: loop + INX + JMP C0617 +C0618: +; 2354: return ID_TKN + DEX + LDA #$D6 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JMP LEAVE +; 2355: end +; 2356: defopt skipspace_01 +C0625: ; skipspace_01() +; 2357: ; +; 2358: ; Skip whitespace +; 2359: ; +; 2360: while ^scanptr and ^scanptr <= ' ' +C0627: + DEX + LDA D0499 + STA ESTKL,X + LDA D0499+1 + STA ESTKH,X + LDY #$00 + JSR LB + DEX + LDA D0499 + STA ESTKL,X + LDA D0499+1 + STA ESTKH,X + JSR LB + DEX + LDA #$20 + STA ESTKL,X + STY ESTKH,X + JSR ISLE + JSR LAND + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0628 +: +; 2361: scanptr = scanptr + 1 + DEX + LDA D0499 + STA ESTKL,X + LDA D0499+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0499 + LDA ESTKH,X + STA D0499+1 +; 2362: loop + INX + JMP C0627 +C0628: +; 2363: tknptr = scanptr + DEX + LDA D0499 + STA ESTKL,X + LDA D0499+1 + STA ESTKH,X + LDA ESTKL,X + STA D0501 + LDA ESTKH,X + STA D0501+1 +; 2364: return !^scanptr or ^scanptr == ';' + LDA D0499 + STA ESTKL,X + LDA D0499+1 + STA ESTKH,X + LDY #$00 + JSR LB + JSR NOT + DEX + LDA D0499 + STA ESTKL,X + LDA D0499+1 + STA ESTKH,X + JSR LB + DEX + LDA #$3B + STA ESTKL,X + STY ESTKH,X + JSR ISEQ + JSR LOR + RTS +; 2365: end +; 2366: def scan_01 +C0629: ; scan_01() +; 2367: ; +; 2368: ; Scan for token based on first character +; 2369: ; +; 2370: if skipspace_01() + JSR INTERP + DB $54,C0625 ; CALL C0625 + DB $4C,C0631 ; SKPFLS C0631 +; 2371: if token <> EOF_TKN + DB $68,D0495 ; LAB D0495 + DB $2A,$01 ; CB 1 + DB $42 ; ISNE + DB $4C,C0633 ; SKPFLS C0633 +; 2372: token = EOL_TKN + DB $2A,$02 ; CB 2 + DB $78,D0495 ; SAB D0495 +; 2373: fin +C0633: +C0634: +; 2374: elsif isalpha_11(^scanptr) + DB $50,C0632 ; SKIP C0632 +C0631: + DB $6A,D0499 ; LAW D0499 + DB $60 ; LB + DB $54,C0607 ; CALL C0607 + DB $4C,C0635 ; SKPFLS C0635 +; 2375: ; +; 2376: ; ID, either variable name or reserved word +; 2377: ; +; 2378: repeat +C0637: +; 2379: scanptr = scanptr + 1 + DB $6A,D0499 ; LAW D0499 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $7A,D0499 ; SAW D0499 +; 2380: until !isalphanum_11(^scanptr) + DB $6A,D0499 ; LAW D0499 + DB $60 ; LB + DB $54,C0611 ; CALL C0611 + DB $20 ; NOT + DB $4C,C0637 ; SKPFLS C0637 +C0636: +; 2381: tknlen = scanptr - tknptr; + DB $6A,D0499 ; LAW D0499 + DB $6A,D0501 ; LAW D0501 + DB $04 ; SUB + DB $78,D0496 ; SAB D0496 +; 2382: token = keymatch_21(tknptr, tknlen) + DB $6A,D0501 ; LAW D0501 + DB $68,D0496 ; LAB D0496 + DB $54,C0613 ; CALL C0613 + DB $78,D0495 ; SAB D0495 +; 2383: elsif isnum_11(^scanptr) + DB $50,C0632 ; SKIP C0632 +C0635: + DB $6A,D0499 ; LAW D0499 + DB $60 ; LB + DB $54,C0609 ; CALL C0609 + DB $4C,C0638 ; SKPFLS C0638 +; 2384: ; +; 2385: ; Number constant +; 2386: ; +; 2387: token = INT_TKN + DB $2A,$C9 ; CB 201 + DB $78,D0495 ; SAB D0495 +; 2388: constval = 0 + DB $00 ; ZERO + DB $7A,D0505 ; SAW D0505 +; 2389: repeat +C0640: +; 2390: constval = constval * 10 + ^scanptr - '0' + DB $6A,D0505 ; LAW D0505 + DB $2A,$0A ; CB 10 + DB $06 ; MUL + DB $6A,D0499 ; LAW D0499 + DB $60 ; LB + DB $02 ; ADD + DB $2A,$30 ; CB 48 + DB $04 ; SUB + DB $7A,D0505 ; SAW D0505 +; 2391: scanptr = scanptr + 1 + DB $6A,D0499 ; LAW D0499 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $7A,D0499 ; SAW D0499 +; 2392: until !isnum_11(^scanptr) + DB $6A,D0499 ; LAW D0499 + DB $60 ; LB + DB $54,C0609 ; CALL C0609 + DB $20 ; NOT + DB $4C,C0640 ; SKPFLS C0640 +C0639: +; 2393: elsif ^scanptr == '$' + DB $50,C0632 ; SKIP C0632 +C0638: + DB $6A,D0499 ; LAW D0499 + DB $60 ; LB + DB $2A,$24 ; CB 36 + DB $40 ; ISEQ + DB $4C,C0641 ; SKPFLS C0641 +; 2394: ; +; 2395: ; Hexadecimal constant +; 2396: ; +; 2397: token = INT_TKN; + DB $2A,$C9 ; CB 201 + DB $78,D0495 ; SAB D0495 +; 2398: constval = 0 + DB $00 ; ZERO + DB $7A,D0505 ; SAW D0505 +; 2399: repeat +C0643: +; 2400: scanptr = scanptr + 1 + DB $6A,D0499 ; LAW D0499 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $7A,D0499 ; SAW D0499 +; 2401: if ^scanptr >= '0' and ^scanptr <= '9' + DB $6A,D0499 ; LAW D0499 + DB $60 ; LB + DB $2A,$30 ; CB 48 + DB $48 ; ISGE + DB $6A,D0499 ; LAW D0499 + DB $60 ; LB + DB $2A,$39 ; CB 57 + DB $4A ; ISLE + DB $24 ; LAND + DB $4C,C0644 ; SKPFLS C0644 +; 2402: constval = (constval << 4) + ^scanptr - '0' + DB $6A,D0505 ; LAW D0505 + DB $2A,$04 ; CB 4 + DB $1A ; SHL + DB $6A,D0499 ; LAW D0499 + DB $60 ; LB + DB $02 ; ADD + DB $2A,$30 ; CB 48 + DB $04 ; SUB + DB $7A,D0505 ; SAW D0505 +; 2403: elsif ^scanptr >= 'A' and ^scanptr <= 'F' + DB $50,C0645 ; SKIP C0645 +C0644: + DB $6A,D0499 ; LAW D0499 + DB $60 ; LB + DB $2A,$41 ; CB 65 + DB $48 ; ISGE + DB $6A,D0499 ; LAW D0499 + DB $60 ; LB + DB $2A,$46 ; CB 70 + DB $4A ; ISLE + DB $24 ; LAND + DB $4C,C0646 ; SKPFLS C0646 +; 2404: constval = (constval << 4) + ^scanptr - '7'; 'A'-10 + DB $6A,D0505 ; LAW D0505 + DB $2A,$04 ; CB 4 + DB $1A ; SHL + DB $6A,D0499 ; LAW D0499 + DB $60 ; LB + DB $02 ; ADD + DB $2A,$37 ; CB 55 + DB $04 ; SUB + DB $7A,D0505 ; SAW D0505 +; 2405: elsif ^scanptr >= 'a' and ^scanptr <= 'f' + DB $50,C0645 ; SKIP C0645 +C0646: + DB $6A,D0499 ; LAW D0499 + DB $60 ; LB + DB $2A,$61 ; CB 97 + DB $48 ; ISGE + DB $6A,D0499 ; LAW D0499 + DB $60 ; LB + DB $2A,$66 ; CB 102 + DB $4A ; ISLE + DB $24 ; LAND + DB $4C,C0647 ; SKPFLS C0647 +; 2406: constval = (constval << 4) + ^scanptr - 'W'; 'a'-10 + DB $6A,D0505 ; LAW D0505 + DB $2A,$04 ; CB 4 + DB $1A ; SHL + DB $6A,D0499 ; LAW D0499 + DB $60 ; LB + DB $02 ; ADD + DB $2A,$57 ; CB 87 + DB $04 ; SUB + DB $7A,D0505 ; SAW D0505 +; 2407: else + DB $50,C0645 ; SKIP C0645 +C0647: +; 2408: break; + DB $50,C0642 ; SKIP C0642 +; 2409: fin +C0645: +; 2410: until !^scanptr + DB $6A,D0499 ; LAW D0499 + DB $60 ; LB + DB $20 ; NOT + DB $4C,C0643 ; SKPFLS C0643 +C0642: +; 2411: elsif ^scanptr == $27 ; ' + DB $50,C0632 ; SKIP C0632 +C0641: + DB $6A,D0499 ; LAW D0499 + DB $60 ; LB + DB $2A,$27 ; CB 39 + DB $40 ; ISEQ + DB $4C,C0648 ; SKPFLS C0648 +; 2412: ; +; 2413: ; Character constant +; 2414: ; +; 2415: token = CHR_TKN + DB $2A,$C3 ; CB 195 + DB $78,D0495 ; SAB D0495 +; 2416: if ^(scanptr + 1) <> $5C ; \ + DB $6A,D0499 ; LAW D0499 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $60 ; LB + DB $2A,$5C ; CB 92 + DB $42 ; ISNE + DB $4C,C0649 ; SKPFLS C0649 +; 2417: constval = ^(scanptr + 1) + DB $6A,D0499 ; LAW D0499 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $60 ; LB + DB $7A,D0505 ; SAW D0505 +; 2418: if ^(scanptr + 2) <> $27 ; ' + DB $6A,D0499 ; LAW D0499 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $60 ; LB + DB $2A,$27 ; CB 39 + DB $42 ; ISNE + DB $4C,C0651 ; SKPFLS C0651 +; 2419: return parse_err_11(@bad_cnst) + DB $26,D0581 ; LA D0581 + DB $54,C0441 ; CALL C0441 + DB $5C ; RET +; 2420: fin +C0651: +C0652: +; 2421: scanptr = scanptr + 3 + DB $6A,D0499 ; LAW D0499 + DB $2A,$03 ; CB 3 + DB $02 ; ADD + DB $7A,D0499 ; SAW D0499 +; 2422: else + DB $50,C0650 ; SKIP C0650 +C0649: +; 2423: when ^(scanptr + 2) + DB $6A,D0499 ; LAW D0499 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $60 ; LB +; 2424: is 'n' + DB $2A,$6E ; CB 110 + DB $3E,C0654 ; SKPNE C0654 +; 2425: constval = $0D + DB $2A,$0D ; CB 13 + DB $7A,D0505 ; SAW D0505 +; 2426: is 'r' + DB $50,C0653 ; SKIP C0653 +C0654: + DB $2A,$72 ; CB 114 + DB $3E,C0655 ; SKPNE C0655 +; 2427: constval = $0A + DB $2A,$0A ; CB 10 + DB $7A,D0505 ; SAW D0505 +; 2428: is 't' + DB $50,C0653 ; SKIP C0653 +C0655: + DB $2A,$74 ; CB 116 + DB $3E,C0656 ; SKPNE C0656 +; 2429: constval = $09 + DB $2A,$09 ; CB 9 + DB $7A,D0505 ; SAW D0505 +; 2430: otherwise + DB $50,C0653 ; SKIP C0653 +C0656: +; 2431: constval = ^(scanptr + 2) + DB $6A,D0499 ; LAW D0499 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $60 ; LB + DB $7A,D0505 ; SAW D0505 +; 2432: wend +C0653: + DB $30 ; DROP +; 2433: if ^(scanptr + 3) <> $27 ; ' + DB $6A,D0499 ; LAW D0499 + DB $2A,$03 ; CB 3 + DB $02 ; ADD + DB $60 ; LB + DB $2A,$27 ; CB 39 + DB $42 ; ISNE + DB $4C,C0658 ; SKPFLS C0658 +; 2434: return parse_err_11(@bad_cnst) + DB $26,D0581 ; LA D0581 + DB $54,C0441 ; CALL C0441 + DB $5C ; RET +; 2435: fin +C0658: +C0659: +; 2436: scanptr = scanptr + 4 + DB $6A,D0499 ; LAW D0499 + DB $2A,$04 ; CB 4 + DB $02 ; ADD + DB $7A,D0499 ; SAW D0499 +; 2437: fin +C0650: +; 2438: elsif ^scanptr == '"' + DB $50,C0632 ; SKIP C0632 +C0648: + DB $6A,D0499 ; LAW D0499 + DB $60 ; LB + DB $2A,$22 ; CB 34 + DB $40 ; ISEQ + DB $4C,C0660 ; SKPFLS C0660 +; 2439: ; +; 2440: ; String constant +; 2441: ; +; 2442: token = STR_TKN + DB $2A,$D3 ; CB 211 + DB $78,D0495 ; SAB D0495 +; 2443: scanptr = scanptr + 1 + DB $6A,D0499 ; LAW D0499 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $7A,D0499 ; SAW D0499 +; 2444: constval = scanptr + DB $6A,D0499 ; LAW D0499 + DB $7A,D0505 ; SAW D0505 +; 2445: while ^scanptr and ^scanptr <> '"' +C0661: + DB $6A,D0499 ; LAW D0499 + DB $60 ; LB + DB $6A,D0499 ; LAW D0499 + DB $60 ; LB + DB $2A,$22 ; CB 34 + DB $42 ; ISNE + DB $24 ; LAND + DB $4C,C0662 ; SKPFLS C0662 +; 2446: scanptr = scanptr + 1 + DB $6A,D0499 ; LAW D0499 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $7A,D0499 ; SAW D0499 +; 2447: loop + DB $50,C0661 ; SKIP C0661 +C0662: +; 2448: if !^scanptr + DB $6A,D0499 ; LAW D0499 + DB $60 ; LB + DB $20 ; NOT + DB $4C,C0663 ; SKPFLS C0663 +; 2449: return parse_err_11(@bad_cnst) + DB $26,D0581 ; LA D0581 + DB $54,C0441 ; CALL C0441 + DB $5C ; RET +; 2450: fin +C0663: +C0664: +; 2451: scanptr = scanptr + 1 + DB $6A,D0499 ; LAW D0499 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $7A,D0499 ; SAW D0499 +; 2452: else + DB $50,C0632 ; SKIP C0632 +C0660: +; 2453: ; +; 2454: ; Potential two and three character tokens +; 2455: ; +; 2456: when ^scanptr + DB $6A,D0499 ; LAW D0499 + DB $60 ; LB +; 2457: is '>' + DB $2A,$3E ; CB 62 + DB $3E,C0666 ; SKPNE C0666 +; 2458: if ^(scanptr + 1) == '>' + DB $6A,D0499 ; LAW D0499 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $60 ; LB + DB $2A,$3E ; CB 62 + DB $40 ; ISEQ + DB $4C,C0667 ; SKPFLS C0667 +; 2459: token = SHR_TKN + DB $2A,$D2 ; CB 210 + DB $78,D0495 ; SAB D0495 +; 2460: scanptr = scanptr + 2 + DB $6A,D0499 ; LAW D0499 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $7A,D0499 ; SAW D0499 +; 2461: elsif ^(scanptr + 1) == '=' + DB $50,C0668 ; SKIP C0668 +C0667: + DB $6A,D0499 ; LAW D0499 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $60 ; LB + DB $2A,$3D ; CB 61 + DB $40 ; ISEQ + DB $4C,C0669 ; SKPFLS C0669 +; 2462: token = GE_TKN + DB $2A,$C8 ; CB 200 + DB $78,D0495 ; SAB D0495 +; 2463: scanptr = scanptr + 2 + DB $6A,D0499 ; LAW D0499 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $7A,D0499 ; SAW D0499 +; 2464: else + DB $50,C0668 ; SKIP C0668 +C0669: +; 2465: token = GT_TKN + DB $2A,$BE ; CB 190 + DB $78,D0495 ; SAB D0495 +; 2466: scanptr = scanptr + 1 + DB $6A,D0499 ; LAW D0499 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $7A,D0499 ; SAW D0499 +; 2467: fin +C0668: +; 2468: is '<' + DB $50,C0665 ; SKIP C0665 +C0666: + DB $2A,$3C ; CB 60 + DB $3E,C0670 ; SKPNE C0670 +; 2469: if ^(scanptr + 1) == '<' + DB $6A,D0499 ; LAW D0499 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $60 ; LB + DB $2A,$3C ; CB 60 + DB $40 ; ISEQ + DB $4C,C0671 ; SKPFLS C0671 +; 2470: token = SHL_TKN + DB $2A,$CC ; CB 204 + DB $78,D0495 ; SAB D0495 +; 2471: scanptr = scanptr + 2 + DB $6A,D0499 ; LAW D0499 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $7A,D0499 ; SAW D0499 +; 2472: elsif ^(scanptr + 1) == '=' + DB $50,C0672 ; SKIP C0672 +C0671: + DB $6A,D0499 ; LAW D0499 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $60 ; LB + DB $2A,$3D ; CB 61 + DB $40 ; ISEQ + DB $4C,C0673 ; SKPFLS C0673 +; 2473: token = LE_TKN + DB $2A,$C2 ; CB 194 + DB $78,D0495 ; SAB D0495 +; 2474: scanptr = scanptr + 2 + DB $6A,D0499 ; LAW D0499 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $7A,D0499 ; SAW D0499 +; 2475: elsif ^(scanptr + 1) == '>' + DB $50,C0672 ; SKIP C0672 +C0673: + DB $6A,D0499 ; LAW D0499 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $60 ; LB + DB $2A,$3E ; CB 62 + DB $40 ; ISEQ + DB $4C,C0674 ; SKPFLS C0674 +; 2476: token = NE_TKN + DB $2A,$D5 ; CB 213 + DB $78,D0495 ; SAB D0495 +; 2477: scanptr = scanptr + 2 + DB $6A,D0499 ; LAW D0499 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $7A,D0499 ; SAW D0499 +; 2478: else + DB $50,C0672 ; SKIP C0672 +C0674: +; 2479: token = LT_TKN + DB $2A,$BC ; CB 188 + DB $78,D0495 ; SAB D0495 +; 2480: scanptr = scanptr + 1 + DB $6A,D0499 ; LAW D0499 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $7A,D0499 ; SAW D0499 +; 2481: fin +C0672: +; 2482: is '=' + DB $50,C0665 ; SKIP C0665 +C0670: + DB $2A,$3D ; CB 61 + DB $3E,C0675 ; SKPNE C0675 +; 2483: if ^(scanptr + 1) == '=' + DB $6A,D0499 ; LAW D0499 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $60 ; LB + DB $2A,$3D ; CB 61 + DB $40 ; ISEQ + DB $4C,C0676 ; SKPFLS C0676 +; 2484: token = EQ_TKN + DB $2A,$C5 ; CB 197 + DB $78,D0495 ; SAB D0495 +; 2485: scanptr = scanptr + 2; + DB $6A,D0499 ; LAW D0499 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $7A,D0499 ; SAW D0499 +; 2486: elsif ^(scanptr + 1) == ',' + DB $50,C0677 ; SKIP C0677 +C0676: + DB $6A,D0499 ; LAW D0499 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $60 ; LB + DB $2A,$2C ; CB 44 + DB $40 ; ISEQ + DB $4C,C0678 ; SKPFLS C0678 +; 2487: token = SETLIST_TKN + DB $2A,$B9 ; CB 185 + DB $78,D0495 ; SAB D0495 +; 2488: scanptr = scanptr + 2; + DB $6A,D0499 ; LAW D0499 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $7A,D0499 ; SAW D0499 +; 2489: else + DB $50,C0677 ; SKIP C0677 +C0678: +; 2490: token = SET_TKN; + DB $2A,$BD ; CB 189 + DB $78,D0495 ; SAB D0495 +; 2491: scanptr = scanptr + 1 + DB $6A,D0499 ; LAW D0499 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $7A,D0499 ; SAW D0499 +; 2492: fin +C0677: +; 2493: otherwise + DB $50,C0665 ; SKIP C0665 +C0675: +; 2494: ; +; 2495: ; Simple single character tokens +; 2496: ; +; 2497: token = ^scanptr ? $80 + DB $6A,D0499 ; LAW D0499 + DB $60 ; LB + DB $2A,$80 ; CB 128 + DB $16 ; IOR + DB $78,D0495 ; SAB D0495 +; 2498: scanptr = scanptr + 1 + DB $6A,D0499 ; LAW D0499 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $7A,D0499 ; SAW D0499 +; 2499: wend +C0665: + DB $30 ; DROP +; 2500: fin +C0632: +; 2501: tknlen = scanptr - tknptr + DB $6A,D0499 ; LAW D0499 + DB $6A,D0501 ; LAW D0501 + DB $04 ; SUB + DB $78,D0496 ; SAB D0496 +; 2502: return token + DB $68,D0495 ; LAB D0495 + DB $5C ; RET +; 2503: end +; 2504: def rewind_10(ptr) +C0680: ; rewind_10() + ; ptr = 2 +; 2505: scanptr = ptr + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $66,$02 ; LLW 2 + DB $7A,D0499 ; SAW D0499 +; 2506: end + DB $5A ; LEAVE +; 2507: ; +; 2508: ; Get next line of input +; 2509: ; +; 2510: defopt nextln_01 +C0682: ; nextln_01() +; 2511: ; if ^keyboard == $A0 +; 2512: ; ^keystrobe +; 2513: ; while ^keyboard < 128 +; 2514: ; loop +; 2515: ; ^keystrobe +; 2516: ; elsif ^keyboard == $82 +; 2517: ; lineno = numlines +; 2518: ; ^keystrobe +; 2519: ; fin +; 2520: scanptr = inbuff + DEX + LDY #$00 + STY ESTKL,X + LDA #$02 + STA ESTKH,X + LDA ESTKL,X + STA D0499 + LDA ESTKH,X + STA D0499+1 +; 2521: if lineno < numlines + LDA D0507 + STA ESTKL,X + LDA D0507+1 + STA ESTKH,X + DEX + LDA D0206 + STA ESTKL,X + LDA D0206+1 + STA ESTKH,X + JSR ISLT + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0684 +: +; 2522: cpyln_20(strlinbuf:[lineno], instr) + DEX + LDY #$00 + STY ESTKL,X + LDA #$10 + STA ESTKH,X + DEX + LDA D0507 + STA ESTKL,X + LDA D0507+1 + STA ESTKH,X + JSR IDXW + JSR LW + DEX + LDA #$FF + STA ESTKL,X + LDA #$01 + STA ESTKH,X + JSR C0133 +; 2523: lineno = lineno + 1 + DEX + LDA D0507 + STA ESTKL,X + LDA D0507+1 + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0507 + LDA ESTKH,X + STA D0507+1 +; 2524: if !(lineno & $0F) + LDA D0507 + STA ESTKL,X + LDA D0507+1 + STA ESTKH,X + DEX + LDA #$0F + STA ESTKL,X + STY ESTKH,X + JSR BAND + JSR NOT + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0686 +: +; 2525: cout('.') + DEX + LDA #$2E + STA ESTKL,X + STY ESTKH,X + JSR C0015 +; 2526: fin +C0686: +C0687: +; 2527: ; cout('>') +; 2528: ; prstr(instr) +; 2529: ; crout() +; 2530: drop scan_01() + JSR C0629 +; 2531: else + INX + JMP C0685 +C0684: +; 2532: ^instr = 0 + DEX + LDA #$FF + STA ESTKL,X + LDA #$01 + STA ESTKH,X + DEX + LDY #$00 + STY ESTKL,X + STY ESTKH,X + JSR SB +; 2533: ^inbuff = $00 + DEX + STY ESTKL,X + LDA #$02 + STA ESTKH,X + DEX + STY ESTKL,X + STY ESTKH,X + JSR SB +; 2534: token = DONE_TKN + DEX + LDA #$98 + STA ESTKL,X + STY ESTKH,X + LDA ESTKL,X + STA D0495 +; 2535: fin + INX +C0685: +; 2536: return ^instr + DEX + LDA #$FF + STA ESTKL,X + LDA #$01 + STA ESTKH,X + LDY #$00 + JSR LB + RTS +; 2537: end +; 2538: ; +; 2539: ; Alebraic op to stack op +; 2540: ; +; 2541: def push_op_21(op, prec) +C0688: ; push_op_21() + ; op = 2 + ; prec = 4 +; 2542: opsp = opsp + 1 + JSR INTERP + DB $58,$06,$02 ; ENTER 6,2 + DB $6A,D0475 ; LAW D0475 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $7A,D0475 ; SAW D0475 +; 2543: if opsp == 16 + DB $6A,D0475 ; LAW D0475 + DB $2A,$10 ; CB 16 + DB $40 ; ISEQ + DB $4C,C0690 ; SKPFLS C0690 +; 2544: return parse_err_11(@estk_overflw) + DB $26,D0681 ; LA D0681 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 2545: fin +C0690: +C0691: +; 2546: opstack[opsp] = op + DB $26,D0443 ; LA D0443 + DB $6A,D0475 ; LAW D0475 + DB $02 ; IDXB + DB $66,$02 ; LLW 2 + DB $70 ; SB +; 2547: precstack[opsp] = prec + DB $26,D0459 ; LA D0459 + DB $6A,D0475 ; LAW D0475 + DB $02 ; IDXB + DB $66,$04 ; LLW 4 + DB $70 ; SB +; 2548: return 0 + DB $00 ; ZERO + DB $5A ; LEAVE +; 2549: end +; 2550: def pop_op_01 +C0692: ; pop_op_01() +; 2551: if opsp < 0 + JSR INTERP + DB $6A,D0475 ; LAW D0475 + DB $00 ; ZERO + DB $46 ; ISLT + DB $4C,C0694 ; SKPFLS C0694 +; 2552: return parse_err_11(@estk_underflw) + DB $26,D0701 ; LA D0701 + DB $54,C0441 ; CALL C0441 + DB $5C ; RET +; 2553: fin +C0694: +C0695: +; 2554: opsp = opsp - 1 + DB $6A,D0475 ; LAW D0475 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $7A,D0475 ; SAW D0475 +; 2555: return opstack[opsp + 1] + DB $26,D0443 ; LA D0443 + DB $6A,D0475 ; LAW D0475 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $02 ; IDXB + DB $60 ; LB + DB $5C ; RET +; 2556: end +; 2557: def tos_op_01 +C0696: ; tos_op_01() +; 2558: if opsp < 0 + JSR INTERP + DB $6A,D0475 ; LAW D0475 + DB $00 ; ZERO + DB $46 ; ISLT + DB $4C,C0698 ; SKPFLS C0698 +; 2559: return 0 + DB $00 ; ZERO + DB $5C ; RET +; 2560: fin +C0698: +C0699: +; 2561: return opstack[opsp] + DB $26,D0443 ; LA D0443 + DB $6A,D0475 ; LAW D0475 + DB $02 ; IDXB + DB $60 ; LB + DB $5C ; RET +; 2562: end +; 2563: def tos_op_prec_11(tos) +C0700: ; tos_op_prec_11() + ; tos = 2 +; 2564: if opsp <= tos + JSR INTERP + DB $58,$04,$01 ; ENTER 4,1 + DB $6A,D0475 ; LAW D0475 + DB $66,$02 ; LLW 2 + DB $4A ; ISLE + DB $4C,C0702 ; SKPFLS C0702 +; 2565: return 100 + DB $2A,$64 ; CB 100 + DB $5A ; LEAVE +; 2566: fin +C0702: +C0703: +; 2567: return precstack[opsp] + DB $26,D0459 ; LA D0459 + DB $6A,D0475 ; LAW D0475 + DB $02 ; IDXB + DB $60 ; LB + DB $5A ; LEAVE +; 2568: end +; 2569: ; +; 2570: ; Symbol table +; 2571: ; +; 2572: defopt idmatch_41(nameptr, len, idptr, idcnt) +C0704: ; idmatch_41() + ; nameptr = 2 + ; len = 4 + ; idptr = 6 + ; idcnt = 8 +; 2573: byte i + ; i = 10 +; 2574: +; 2575: while idcnt + LDY #11 + LDA #4 + JSR ENTER +C0706: + DEX + LDY #$08 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0707 +: +; 2576: if len == (idptr).idname + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$03 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + JSR ISEQ + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0708 +: +; 2577: for i = 1 to len + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X +C0711: + LDY #$0A + LDA ESTKL,X + STA (FRMP),Y + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + LDA ESTKH-1,X + SBC ESTKH,X + BPL :+ + JMP C0710 +: + INC ESTKL,X + BNE :+ + INC ESTKH,X +: +; 2578: if (nameptr).[i - 1] <> (idptr).idname.[i] + DEX + LDY #$02 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$0A + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X + JSR SUB + JSR ADD + JSR LB + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$03 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + DEX + LDY #$0A + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + JSR ISNE + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0712 +: +; 2579: break + JMP C0710 +; 2580: fin +C0712: +C0713: +; 2581: next + JMP C0711 +C0710: +; 2582: if i > len + LDY #$0A + LDA (FRMP),Y + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDY #$04 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + LDY #$00 + JSR ISGT + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0714 +: +; 2583: return idptr + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + JMP LEAVE +; 2584: fin +C0714: +C0715: +; 2585: fin +C0708: +C0709: +; 2586: idptr = idptr + (idptr).idname + idrecsz + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDY #$06 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$03 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR ADD + JSR LB + JSR ADD + DEX + LDA #$04 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDY #$06 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 2587: idcnt = idcnt - 1 + LDY #$08 + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + DEX + LDA #$01 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + JSR SUB + LDY #$08 + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y +; 2588: loop + INX + JMP C0706 +C0707: +; 2589: return 0 + DEX + LDY #$00 + STY ESTKL,X + STY ESTKH,X + JMP LEAVE +; 2590: end +; 2591: ;def dumpsym_20(idptr, idcnt) +; 2592: ; while idcnt +; 2593: ; prword_10((idptr):idval) +; 2594: ; cout(' ') +; 2595: ; prbyte_10((idptr).idtype) +; 2596: ; cout(' ') +; 2597: ; prstr(@(idptr).idname) +; 2598: ; cout('=') +; 2599: ; if (idptr).idtype & ADDR_TYPE +; 2600: ; if (idptr):idval & is_ctag +; 2601: ; prword_10(ctag_value:[(idptr):idval & mask_ctag]) +; 2602: ; else +; 2603: ; prword_10((idptr):idval + codebuff) +; 2604: ; fin +; 2605: ; else +; 2606: ; prword_10((idptr):idval) +; 2607: ; fin +; 2608: ; crout() +; 2609: ; idptr = idptr + (idptr).idname + idrecsz +; 2610: ; idcnt = idcnt - 1 +; 2611: ; loop +; 2612: ;end +; 2613: def id_lookup_21(nameptr, len) +C0716: ; id_lookup_21() + ; nameptr = 2 + ; len = 4 +; 2614: word idptr + ; idptr = 6 +; 2615: +; 2616: idptr = idmatch_41(nameptr, len, idlocal_tbl, locals) + JSR INTERP + DB $58,$08,$02 ; ENTER 8,2 + DB $66,$02 ; LLW 2 + DB $66,$04 ; LLW 4 + DB $2C,$00,$1E ; CW 7680 + DB $68,D0483 ; LAB D0483 + DB $54,C0704 ; CALL C0704 + DB $76,$06 ; SLW 6 +; 2617: if idptr + DB $66,$06 ; LLW 6 + DB $4C,C0718 ; SKPFLS C0718 +; 2618: return idptr + DB $66,$06 ; LLW 6 + DB $5A ; LEAVE +; 2619: fin +C0718: +C0719: +; 2620: idptr = idmatch_41(nameptr, len, idglobal_tbl, globals) + DB $66,$02 ; LLW 2 + DB $66,$04 ; LLW 4 + DB $2C,$00,$16 ; CW 5632 + DB $6A,D0477 ; LAW D0477 + DB $54,C0704 ; CALL C0704 + DB $76,$06 ; SLW 6 +; 2621: if idptr + DB $66,$06 ; LLW 6 + DB $4C,C0720 ; SKPFLS C0720 +; 2622: return idptr + DB $66,$06 ; LLW 6 + DB $5A ; LEAVE +; 2623: fin +C0720: +C0721: +; 2624: return parse_err_11(@undecl_id) + DB $26,D0559 ; LA D0559 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 2625: end +; 2626: def idglobal_lookup_21(nameptr, len) +C0722: ; idglobal_lookup_21() + ; nameptr = 2 + ; len = 4 +; 2627: return idmatch_41(nameptr, len, idglobal_tbl, globals) + JSR INTERP + DB $58,$06,$02 ; ENTER 6,2 + DB $66,$02 ; LLW 2 + DB $66,$04 ; LLW 4 + DB $2C,$00,$16 ; CW 5632 + DB $6A,D0477 ; LAW D0477 + DB $54,C0704 ; CALL C0704 + DB $5A ; LEAVE +; 2628: end +; 2629: def idlocal_add_41(namestr, len, type, size) +C0724: ; idlocal_add_41() + ; namestr = 2 + ; len = 4 + ; type = 6 + ; size = 8 +; 2630: if idmatch_41(namestr, len, @idlocal_tbl, locals) + JSR INTERP + DB $58,$0A,$04 ; ENTER 10,4 + DB $66,$02 ; LLW 2 + DB $66,$04 ; LLW 4 + DB $2C,$00,$1E ; CW 7680 + DB $68,D0483 ; LAB D0483 + DB $54,C0704 ; CALL C0704 + DB $4C,C0726 ; SKPFLS C0726 +; 2631: return parse_err_11(@dup_id) + DB $26,D0538 ; LA D0538 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 2632: fin +C0726: +C0727: +; 2633: (lastlocal):idval = framesize + DB $6A,D0486 ; LAW D0486 + DB $6A,D0484 ; LAW D0484 + DB $72 ; SW +; 2634: (lastlocal).idtype = type ? LOCAL_TYPE + DB $6A,D0486 ; LAW D0486 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $66,$06 ; LLW 6 + DB $2A,$10 ; CB 16 + DB $16 ; IOR + DB $70 ; SB +; 2635: nametostr_30(namestr, len, lastlocal + idname) + DB $66,$02 ; LLW 2 + DB $66,$04 ; LLW 4 + DB $6A,D0486 ; LAW D0486 + DB $2A,$03 ; CB 3 + DB $02 ; ADD + DB $54,C0125 ; CALL C0125 +; 2636: locals = locals + 1 + DB $68,D0483 ; LAB D0483 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $78,D0483 ; SAB D0483 +; 2637: lastlocal = lastlocal + idrecsz + len + DB $6A,D0486 ; LAW D0486 + DB $2A,$04 ; CB 4 + DB $02 ; ADD + DB $66,$04 ; LLW 4 + DB $02 ; ADD + DB $7A,D0486 ; SAW D0486 +; 2638: if lastlocal > idlocal_tbl + idlocal_tblsz + DB $6A,D0486 ; LAW D0486 + DB $2C,$00,$1E ; CW 7680 + DB $2C,$00,$02 ; CW 512 + DB $02 ; ADD + DB $44 ; ISGT + DB $4C,C0728 ; SKPFLS C0728 +; 2639: prstr(@local_sym_overflw) + DB $26,D0772 ; LA D0772 + DB $54,C0019 ; CALL C0019 +; 2640: exit + DB $54,C0023 ; CALL C0023 +; 2641: fin +C0728: +C0729: +; 2642: framesize = framesize + size + DB $6A,D0484 ; LAW D0484 + DB $66,$08 ; LLW 8 + DB $02 ; ADD + DB $7A,D0484 ; SAW D0484 +; 2643: if framesize > 255 + DB $6A,D0484 ; LAW D0484 + DB $2A,$FF ; CB 255 + DB $44 ; ISGT + DB $4C,C0730 ; SKPFLS C0730 +; 2644: prstr(@local_overflw) + DB $26,D0722 ; LA D0722 + DB $54,C0019 ; CALL C0019 +; 2645: return FALSE + DB $00 ; ZERO + DB $5A ; LEAVE +; 2646: fin +C0730: +C0731: +; 2647: return TRUE + DB $2C,$FF,$FF ; CW -1 + DB $5A ; LEAVE +; 2648: end +; 2649: def iddata_add_41(namestr, len, type, size) +C0732: ; iddata_add_41() + ; namestr = 2 + ; len = 4 + ; type = 6 + ; size = 8 +; 2650: if idmatch_41(namestr, len, idglobal_tbl, globals) + JSR INTERP + DB $58,$0A,$04 ; ENTER 10,4 + DB $66,$02 ; LLW 2 + DB $66,$04 ; LLW 4 + DB $2C,$00,$16 ; CW 5632 + DB $6A,D0477 ; LAW D0477 + DB $54,C0704 ; CALL C0704 + DB $4C,C0734 ; SKPFLS C0734 +; 2651: return parse_err_11(@dup_id) + DB $26,D0538 ; LA D0538 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 2652: fin +C0734: +C0735: +; 2653: (lastglobal):idval = datasize + DB $6A,D0481 ; LAW D0481 + DB $6A,D0479 ; LAW D0479 + DB $72 ; SW +; 2654: (lastglobal).idtype = type + DB $6A,D0481 ; LAW D0481 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $66,$06 ; LLW 6 + DB $70 ; SB +; 2655: nametostr_30(namestr, len, lastglobal + idname) + DB $66,$02 ; LLW 2 + DB $66,$04 ; LLW 4 + DB $6A,D0481 ; LAW D0481 + DB $2A,$03 ; CB 3 + DB $02 ; ADD + DB $54,C0125 ; CALL C0125 +; 2656: emit_iddata_30(datasize, size, lastglobal + idname) + DB $6A,D0479 ; LAW D0479 + DB $66,$08 ; LLW 8 + DB $6A,D0481 ; LAW D0481 + DB $2A,$03 ; CB 3 + DB $02 ; ADD + DB $54,C0471 ; CALL C0471 +; 2657: globals = globals + 1 + DB $6A,D0477 ; LAW D0477 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $7A,D0477 ; SAW D0477 +; 2658: lastglobal = lastglobal + idrecsz + len + DB $6A,D0481 ; LAW D0481 + DB $2A,$04 ; CB 4 + DB $02 ; ADD + DB $66,$04 ; LLW 4 + DB $02 ; ADD + DB $7A,D0481 ; SAW D0481 +; 2659: if lastglobal > idglobal_tbl + idglobal_tblsz + DB $6A,D0481 ; LAW D0481 + DB $2C,$00,$16 ; CW 5632 + DB $2C,$00,$08 ; CW 2048 + DB $02 ; ADD + DB $44 ; ISGT + DB $4C,C0736 ; SKPFLS C0736 +; 2660: prstr(@global_sym_overflw) + DB $26,D0743 ; LA D0743 + DB $54,C0019 ; CALL C0019 +; 2661: exit + DB $54,C0023 ; CALL C0023 +; 2662: fin +C0736: +C0737: +; 2663: datasize = datasize + size + DB $6A,D0479 ; LAW D0479 + DB $66,$08 ; LLW 8 + DB $02 ; ADD + DB $7A,D0479 ; SAW D0479 +; 2664: return TRUE + DB $2C,$FF,$FF ; CW -1 + DB $5A ; LEAVE +; 2665: end +; 2666: def iddata_size_30(type, varsize, initsize) +C0738: ; iddata_size_30() + ; type = 2 + ; varsize = 4 + ; initsize = 6 +; 2667: if varsize > initsize + JSR INTERP + DB $58,$08,$03 ; ENTER 8,3 + DB $66,$04 ; LLW 4 + DB $66,$06 ; LLW 6 + DB $44 ; ISGT + DB $4C,C0740 ; SKPFLS C0740 +; 2668: datasize = datasize + emit_data_41(0, 0, 0, varsize - initsize) + DB $6A,D0479 ; LAW D0479 + DB $00 ; ZERO + DB $00 ; ZERO + DB $00 ; ZERO + DB $66,$04 ; LLW 4 + DB $66,$06 ; LLW 6 + DB $04 ; SUB + DB $54,C0473 ; CALL C0473 + DB $02 ; ADD + DB $7A,D0479 ; SAW D0479 +; 2669: else + DB $50,C0741 ; SKIP C0741 +C0740: +; 2670: datasize = datasize + initsize + DB $6A,D0479 ; LAW D0479 + DB $66,$06 ; LLW 6 + DB $02 ; ADD + DB $7A,D0479 ; SAW D0479 +; 2671: fin +C0741: +; 2672: ; if datasize <> codeptr - codebuff +; 2673: ; prstr(@emiterr) +; 2674: ; keyin_01() +; 2675: ; fin +; 2676: end + DB $5A ; LEAVE +; 2677: def idglobal_add_41(namestr, len, type, value) +C0742: ; idglobal_add_41() + ; namestr = 2 + ; len = 4 + ; type = 6 + ; value = 8 +; 2678: if idmatch_41(namestr, len, idglobal_tbl, globals) + JSR INTERP + DB $58,$0A,$04 ; ENTER 10,4 + DB $66,$02 ; LLW 2 + DB $66,$04 ; LLW 4 + DB $2C,$00,$16 ; CW 5632 + DB $6A,D0477 ; LAW D0477 + DB $54,C0704 ; CALL C0704 + DB $4C,C0744 ; SKPFLS C0744 +; 2679: return parse_err_11(@dup_id) + DB $26,D0538 ; LA D0538 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 2680: fin +C0744: +C0745: +; 2681: (lastglobal):idval = value + DB $6A,D0481 ; LAW D0481 + DB $66,$08 ; LLW 8 + DB $72 ; SW +; 2682: (lastglobal).idtype = type + DB $6A,D0481 ; LAW D0481 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $66,$06 ; LLW 6 + DB $70 ; SB +; 2683: nametostr_30(namestr, len, lastglobal + idname) + DB $66,$02 ; LLW 2 + DB $66,$04 ; LLW 4 + DB $6A,D0481 ; LAW D0481 + DB $2A,$03 ; CB 3 + DB $02 ; ADD + DB $54,C0125 ; CALL C0125 +; 2684: globals = globals + 1 + DB $6A,D0477 ; LAW D0477 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $7A,D0477 ; SAW D0477 +; 2685: lastglobal = lastglobal + idrecsz + len + DB $6A,D0481 ; LAW D0481 + DB $2A,$04 ; CB 4 + DB $02 ; ADD + DB $66,$04 ; LLW 4 + DB $02 ; ADD + DB $7A,D0481 ; SAW D0481 +; 2686: if lastglobal > idglobal_tbl + idglobal_tblsz + DB $6A,D0481 ; LAW D0481 + DB $2C,$00,$16 ; CW 5632 + DB $2C,$00,$08 ; CW 2048 + DB $02 ; ADD + DB $44 ; ISGT + DB $4C,C0746 ; SKPFLS C0746 +; 2687: prstr(@global_sym_overflw) + DB $26,D0743 ; LA D0743 + DB $54,C0019 ; CALL C0019 +; 2688: exit + DB $54,C0023 ; CALL C0023 +; 2689: fin +C0746: +C0747: +; 2690: return TRUE + DB $2C,$FF,$FF ; CW -1 + DB $5A ; LEAVE +; 2691: end +; 2692: def idfunc_add_31(namestr, len, tag) +C0748: ; idfunc_add_31() + ; namestr = 2 + ; len = 4 + ; tag = 6 +; 2693: return idglobal_add_41(namestr, len, FUNC_TYPE, tag) + JSR INTERP + DB $58,$08,$03 ; ENTER 8,3 + DB $66,$02 ; LLW 2 + DB $66,$04 ; LLW 4 + DB $2A,$08 ; CB 8 + DB $66,$06 ; LLW 6 + DB $54,C0742 ; CALL C0742 + DB $5A ; LEAVE +; 2694: end +; 2695: def idconst_add_31(namestr, len, value) +C0750: ; idconst_add_31() + ; namestr = 2 + ; len = 4 + ; value = 6 +; 2696: return idglobal_add_41(namestr, len, CONST_TYPE, value) + JSR INTERP + DB $58,$08,$03 ; ENTER 8,3 + DB $66,$02 ; LLW 2 + DB $66,$04 ; LLW 4 + DB $2A,$01 ; CB 1 + DB $66,$06 ; LLW 6 + DB $54,C0742 ; CALL C0742 + DB $5A ; LEAVE +; 2697: end +; 2698: def idglobal_init +C0752: ; idglobal_init() +; 2699: word ctag + ; ctag = 2 +; 2700: +; 2701: lineno = 0 + JSR INTERP + DB $58,$04,$00 ; ENTER 4,0 + DB $00 ; ZERO + DB $7A,D0507 ; SAW D0507 +; 2702: parserr = 0 + DB $00 ; ZERO + DB $78,D0498 ; SAB D0498 +; 2703: codeptr = codebuff + DB $2C,$00,$A8 ; CW 43008 + DB $7A,D0490 ; SAW D0490 +; 2704: lastop = $FF + DB $2A,$FF ; CB 255 + DB $78,D0494 ; SAB D0494 +; 2705: entrypoint = 0 + DB $00 ; ZERO + DB $7A,D0492 ; SAW D0492 +; 2706: datasize = 0 + DB $00 ; ZERO + DB $7A,D0479 ; SAW D0479 +; 2707: globals = 0 + DB $00 ; ZERO + DB $7A,D0477 ; SAW D0477 +; 2708: lastglobal = idglobal_tbl + DB $2C,$00,$16 ; CW 5632 + DB $7A,D0481 ; SAW D0481 +; 2709: codetag = -1 + DB $2C,$FF,$FF ; CW -1 + DB $7A,D0488 ; SAW D0488 +; 2710: ctag = ctag_new_01() + DB $54,C0445 ; CALL C0445 + DB $76,$02 ; SLW 2 +; 2711: drop idfunc_add_31(@runtime0 + 1, runtime0, ctag) + DB $26,D1000 ; LA D1000 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D1000 ; LAB D1000 + DB $66,$02 ; LLW 2 + DB $54,C0748 ; CALL C0748 + DB $30 ; DROP +; 2712: drop idfunc_add_31(@RUNTIME0 + 1, RUNTIME0, ctag) + DB $26,D1008 ; LA D1008 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D1008 ; LAB D1008 + DB $66,$02 ; LLW 2 + DB $54,C0748 ; CALL C0748 + DB $30 ; DROP +; 2713: drop ctag_resolve_21(ctag, @romcall) + DB $66,$02 ; LLW 2 + DB $26,C0007 ; LA C0007 + DB $54,C0449 ; CALL C0449 + DB $30 ; DROP +; 2714: ctag = ctag_new_01() + DB $54,C0445 ; CALL C0445 + DB $76,$02 ; SLW 2 +; 2715: drop idfunc_add_31(@runtime1 + 1, runtime1, ctag) + DB $26,D1016 ; LA D1016 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D1016 ; LAB D1016 + DB $66,$02 ; LLW 2 + DB $54,C0748 ; CALL C0748 + DB $30 ; DROP +; 2716: drop idfunc_add_31(@RUNTIME1 + 1, RUNTIME1, ctag) + DB $26,D1024 ; LA D1024 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D1024 ; LAB D1024 + DB $66,$02 ; LLW 2 + DB $54,C0748 ; CALL C0748 + DB $30 ; DROP +; 2717: drop ctag_resolve_21(ctag, @syscall) + DB $66,$02 ; LLW 2 + DB $26,C0009 ; LA C0009 + DB $54,C0449 ; CALL C0449 + DB $30 ; DROP +; 2718: ctag = ctag_new_01() + DB $54,C0445 ; CALL C0445 + DB $76,$02 ; SLW 2 +; 2719: drop idfunc_add_31(@runtime2 + 1, runtime2, ctag) + DB $26,D1032 ; LA D1032 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D1032 ; LAB D1032 + DB $66,$02 ; LLW 2 + DB $54,C0748 ; CALL C0748 + DB $30 ; DROP +; 2720: drop idfunc_add_31(@RUNTIME2 + 1, RUNTIME2, ctag) + DB $26,D1039 ; LA D1039 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D1039 ; LAB D1039 + DB $66,$02 ; LLW 2 + DB $54,C0748 ; CALL C0748 + DB $30 ; DROP +; 2721: drop ctag_resolve_21(ctag, @memset) + DB $66,$02 ; LLW 2 + DB $26,C0011 ; LA C0011 + DB $54,C0449 ; CALL C0449 + DB $30 ; DROP +; 2722: ctag = ctag_new_01() + DB $54,C0445 ; CALL C0445 + DB $76,$02 ; SLW 2 +; 2723: drop idfunc_add_31(@runtime3 + 1, runtime3, ctag) + DB $26,D1046 ; LA D1046 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D1046 ; LAB D1046 + DB $66,$02 ; LLW 2 + DB $54,C0748 ; CALL C0748 + DB $30 ; DROP +; 2724: drop idfunc_add_31(@RUNTIME3 + 1, RUNTIME3, ctag) + DB $26,D1053 ; LA D1053 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D1053 ; LAB D1053 + DB $66,$02 ; LLW 2 + DB $54,C0748 ; CALL C0748 + DB $30 ; DROP +; 2725: drop ctag_resolve_21(ctag, @memcpy) + DB $66,$02 ; LLW 2 + DB $26,C0013 ; LA C0013 + DB $54,C0449 ; CALL C0449 + DB $30 ; DROP +; 2726: ctag = ctag_new_01() + DB $54,C0445 ; CALL C0445 + DB $76,$02 ; SLW 2 +; 2727: drop idfunc_add_31(@runtime4 + 1, runtime4, ctag) + DB $26,D1060 ; LA D1060 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D1060 ; LAB D1060 + DB $66,$02 ; LLW 2 + DB $54,C0748 ; CALL C0748 + DB $30 ; DROP +; 2728: drop idfunc_add_31(@RUNTIME4 + 1, RUNTIME4, ctag) + DB $26,D1065 ; LA D1065 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D1065 ; LAB D1065 + DB $66,$02 ; LLW 2 + DB $54,C0748 ; CALL C0748 + DB $30 ; DROP +; 2729: drop ctag_resolve_21(ctag, @cout) + DB $66,$02 ; LLW 2 + DB $26,C0015 ; LA C0015 + DB $54,C0449 ; CALL C0449 + DB $30 ; DROP +; 2730: ctag = ctag_new_01() + DB $54,C0445 ; CALL C0445 + DB $76,$02 ; SLW 2 +; 2731: drop idfunc_add_31(@runtime5 + 1, runtime5, ctag) + DB $26,D1070 ; LA D1070 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D1070 ; LAB D1070 + DB $66,$02 ; LLW 2 + DB $54,C0748 ; CALL C0748 + DB $30 ; DROP +; 2732: drop idfunc_add_31(@RUNTIME5 + 1, RUNTIME5, ctag) + DB $26,D1074 ; LA D1074 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D1074 ; LAB D1074 + DB $66,$02 ; LLW 2 + DB $54,C0748 ; CALL C0748 + DB $30 ; DROP +; 2733: drop ctag_resolve_21(ctag, @cin) + DB $66,$02 ; LLW 2 + DB $26,C0017 ; LA C0017 + DB $54,C0449 ; CALL C0449 + DB $30 ; DROP +; 2734: ctag = ctag_new_01() + DB $54,C0445 ; CALL C0445 + DB $76,$02 ; SLW 2 +; 2735: drop idfunc_add_31(@runtime6 + 1, runtime6, ctag) + DB $26,D1078 ; LA D1078 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D1078 ; LAB D1078 + DB $66,$02 ; LLW 2 + DB $54,C0748 ; CALL C0748 + DB $30 ; DROP +; 2736: drop idfunc_add_31(@RUNTIME6 + 1, RUNTIME6, ctag) + DB $26,D1084 ; LA D1084 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D1084 ; LAB D1084 + DB $66,$02 ; LLW 2 + DB $54,C0748 ; CALL C0748 + DB $30 ; DROP +; 2737: drop ctag_resolve_21(ctag, @prstr) + DB $66,$02 ; LLW 2 + DB $26,C0019 ; LA C0019 + DB $54,C0449 ; CALL C0449 + DB $30 ; DROP +; 2738: ctag = ctag_new_01() + DB $54,C0445 ; CALL C0445 + DB $76,$02 ; SLW 2 +; 2739: drop idfunc_add_31(@runtime7 + 1, runtime7, ctag) + DB $26,D1090 ; LA D1090 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D1090 ; LAB D1090 + DB $66,$02 ; LLW 2 + DB $54,C0748 ; CALL C0748 + DB $30 ; DROP +; 2740: drop idfunc_add_31(@RUNTIME7 + 1, RUNTIME7, ctag) + DB $26,D1096 ; LA D1096 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $68,D1096 ; LAB D1096 + DB $66,$02 ; LLW 2 + DB $54,C0748 ; CALL C0748 + DB $30 ; DROP +; 2741: drop ctag_resolve_21(ctag, @rdstr) + DB $66,$02 ; LLW 2 + DB $26,C0021 ; LA C0021 + DB $54,C0449 ; CALL C0449 + DB $30 ; DROP +; 2742: end + DB $5A ; LEAVE +; 2743: def idlocal_init +C0754: ; idlocal_init() +; 2744: locals = 0 + JSR INTERP + DB $00 ; ZERO + DB $78,D0483 ; SAB D0483 +; 2745: framesize = 2 + DB $2A,$02 ; CB 2 + DB $7A,D0484 ; SAW D0484 +; 2746: lastlocal = idlocal_tbl + DB $2C,$00,$1E ; CW 7680 + DB $7A,D0486 ; SAW D0486 +; 2747: end + DB $5C ; RET +; 2748: ; +; 2749: ; Parser +; 2750: ; +; 2751: def parse_term_01 +C0756: ; parse_term_01() +; 2752: when scan_01() + JSR INTERP + DB $54,C0629 ; CALL C0629 +; 2753: is ID_TKN + DB $2A,$D6 ; CB 214 + DB $3E,C0759 ; SKPNE C0759 +; 2754: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5C ; RET +; 2755: is INT_TKN + DB $50,C0758 ; SKIP C0758 +C0759: + DB $2A,$C9 ; CB 201 + DB $3E,C0760 ; SKPNE C0760 +; 2756: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5C ; RET +; 2757: is CHR_TKN + DB $50,C0758 ; SKIP C0758 +C0760: + DB $2A,$C3 ; CB 195 + DB $3E,C0761 ; SKPNE C0761 +; 2758: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5C ; RET +; 2759: is STR_TKN + DB $50,C0758 ; SKIP C0758 +C0761: + DB $2A,$D3 ; CB 211 + DB $3E,C0762 ; SKPNE C0762 +; 2760: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5C ; RET +; 2761: is OPEN_PAREN_TKN + DB $50,C0758 ; SKIP C0758 +C0762: + DB $2A,$A8 ; CB 168 + DB $3E,C0763 ; SKPNE C0763 +; 2762: if !parse_expr_01() + DB $54,C0001 ; CALL C0001 + DB $20 ; NOT + DB $4C,C0764 ; SKPFLS C0764 +; 2763: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5C ; RET +; 2764: fin +C0764: +C0765: +; 2765: if token <> CLOSE_PAREN_TKN + DB $68,D0495 ; LAB D0495 + DB $2A,$A9 ; CB 169 + DB $42 ; ISNE + DB $4C,C0766 ; SKPFLS C0766 +; 2766: return parse_err_11(@no_close_paren) + DB $30 ; DROP + DB $26,D0820 ; LA D0820 + DB $54,C0441 ; CALL C0441 + DB $5C ; RET +; 2767: fin +C0766: +C0767: +; 2768: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5C ; RET +; 2769: wend + DB $50,C0758 ; SKIP C0758 +C0763: +C0758: + DB $30 ; DROP +; 2770: return FALSE + DB $00 ; ZERO + DB $5C ; RET +; 2771: end +; 2772: def parse_constval_21(valptr, sizeptr) +C0769: ; parse_constval_21() + ; valptr = 2 + ; sizeptr = 4 +; 2773: byte mod, type + ; mod = 6 + ; type = 7 +; 2774: word idptr + ; idptr = 8 +; 2775: +; 2776: mod = 0 + JSR INTERP + DB $58,$0A,$02 ; ENTER 10,2 + DB $00 ; ZERO + DB $74,$06 ; SLB 6 +; 2777: type = 0 + DB $00 ; ZERO + DB $74,$07 ; SLB 7 +; 2778: *valptr = 0 + DB $66,$02 ; LLW 2 + DB $00 ; ZERO + DB $72 ; SW +; 2779: while !parse_term_01() +C0771: + DB $54,C0756 ; CALL C0756 + DB $20 ; NOT + DB $4C,C0772 ; SKPFLS C0772 +; 2780: when token + DB $68,D0495 ; LAB D0495 +; 2781: is SUB_TKN + DB $2A,$AD ; CB 173 + DB $3E,C0774 ; SKPNE C0774 +; 2782: mod = mod ? 1 + DB $64,$06 ; LLB 6 + DB $2A,$01 ; CB 1 + DB $16 ; IOR + DB $74,$06 ; SLB 6 +; 2783: is COMP_TKN + DB $50,C0773 ; SKIP C0773 +C0774: + DB $2A,$A3 ; CB 163 + DB $3E,C0775 ; SKPNE C0775 +; 2784: mod = mod ? 2 + DB $64,$06 ; LLB 6 + DB $2A,$02 ; CB 2 + DB $16 ; IOR + DB $74,$06 ; SLB 6 +; 2785: is LOGIC_NOT_TKN + DB $50,C0773 ; SKIP C0773 +C0775: + DB $2A,$A1 ; CB 161 + DB $3E,C0776 ; SKPNE C0776 +; 2786: mod = mod ? 4 + DB $64,$06 ; LLB 6 + DB $2A,$04 ; CB 4 + DB $16 ; IOR + DB $74,$06 ; SLB 6 +; 2787: is AT_TKN + DB $50,C0773 ; SKIP C0773 +C0776: + DB $2A,$C0 ; CB 192 + DB $3E,C0777 ; SKPNE C0777 +; 2788: mod = mod ? 8 + DB $64,$06 ; LLB 6 + DB $2A,$08 ; CB 8 + DB $16 ; IOR + DB $74,$06 ; SLB 6 +; 2789: otherwise + DB $50,C0773 ; SKIP C0773 +C0777: +; 2790: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2791: wend +C0773: + DB $30 ; DROP +; 2792: loop + DB $50,C0771 ; SKIP C0771 +C0772: +; 2793: when token + DB $68,D0495 ; LAB D0495 +; 2794: is STR_TKN + DB $2A,$D3 ; CB 211 + DB $3E,C0780 ; SKPNE C0780 +; 2795: *valptr = constval + DB $66,$02 ; LLW 2 + DB $6A,D0505 ; LAW D0505 + DB $72 ; SW +; 2796: ^sizeptr = tknlen - 1 + DB $66,$04 ; LLW 4 + DB $68,D0496 ; LAB D0496 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $70 ; SB +; 2797: type = STR_TYPE + DB $2A,$80 ; CB 128 + DB $74,$07 ; SLB 7 +; 2798: if mod + DB $64,$06 ; LLB 6 + DB $4C,C0781 ; SKPFLS C0781 +; 2799: return parse_err_11(@bad_op) + DB $30 ; DROP + DB $26,D0628 ; LA D0628 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 2800: fin +C0781: +C0782: +; 2801: is CHR_TKN + DB $50,C0779 ; SKIP C0779 +C0780: + DB $2A,$C3 ; CB 195 + DB $3E,C0783 ; SKPNE C0783 +; 2802: *valptr = constval + DB $66,$02 ; LLW 2 + DB $6A,D0505 ; LAW D0505 + DB $72 ; SW +; 2803: ^sizeptr = 1 + DB $66,$04 ; LLW 4 + DB $2A,$01 ; CB 1 + DB $70 ; SB +; 2804: type = BYTE_TYPE + DB $2A,$02 ; CB 2 + DB $74,$07 ; SLB 7 +; 2805: is INT_TKN + DB $50,C0779 ; SKIP C0779 +C0783: + DB $2A,$C9 ; CB 201 + DB $3E,C0784 ; SKPNE C0784 +; 2806: *valptr = constval + DB $66,$02 ; LLW 2 + DB $6A,D0505 ; LAW D0505 + DB $72 ; SW +; 2807: ^sizeptr = 2 + DB $66,$04 ; LLW 4 + DB $2A,$02 ; CB 2 + DB $70 ; SB +; 2808: type = WORD_TYPE + DB $2A,$04 ; CB 4 + DB $74,$07 ; SLB 7 +; 2809: is ID_TKN + DB $50,C0779 ; SKIP C0779 +C0784: + DB $2A,$D6 ; CB 214 + DB $3E,C0785 ; SKPNE C0785 +; 2810: ^sizeptr = 2 + DB $66,$04 ; LLW 4 + DB $2A,$02 ; CB 2 + DB $70 ; SB +; 2811: idptr = id_lookup_21(tknptr, tknlen) + DB $6A,D0501 ; LAW D0501 + DB $68,D0496 ; LAB D0496 + DB $54,C0716 ; CALL C0716 + DB $76,$08 ; SLW 8 +; 2812: if !idptr + DB $66,$08 ; LLW 8 + DB $20 ; NOT + DB $4C,C0786 ; SKPFLS C0786 +; 2813: return parse_err_11(@bad_cnst) + DB $30 ; DROP + DB $26,D0581 ; LA D0581 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 2814: fin +C0786: +C0787: +; 2815: type = (idptr).idtype + DB $66,$08 ; LLW 8 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $60 ; LB + DB $74,$07 ; SLB 7 +; 2816: *valptr = (idptr):idval + DB $66,$02 ; LLW 2 + DB $66,$08 ; LLW 8 + DB $62 ; LW + DB $72 ; SW +; 2817: if type & VAR_TYPE and !(mod & 8) + DB $64,$07 ; LLB 7 + DB $2A,$06 ; CB 6 + DB $14 ; BAND + DB $64,$06 ; LLB 6 + DB $2A,$08 ; CB 8 + DB $14 ; BAND + DB $20 ; NOT + DB $24 ; LAND + DB $4C,C0788 ; SKPFLS C0788 +; 2818: return parse_err_11(@bad_cnst) + DB $30 ; DROP + DB $26,D0581 ; LA D0581 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 2819: fin +C0788: +C0789: +; 2820: otherwise + DB $50,C0779 ; SKIP C0779 +C0785: +; 2821: return parse_err_11(@bad_cnst) + DB $30 ; DROP + DB $26,D0581 ; LA D0581 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 2822: wend +C0779: + DB $30 ; DROP +; 2823: if mod & 1 + DB $64,$06 ; LLB 6 + DB $2A,$01 ; CB 1 + DB $14 ; BAND + DB $4C,C0791 ; SKPFLS C0791 +; 2824: *valptr = -*valptr + DB $66,$02 ; LLW 2 + DB $66,$02 ; LLW 2 + DB $62 ; LW + DB $10 ; NEG + DB $72 ; SW +; 2825: fin +C0791: +C0792: +; 2826: if mod & 2 + DB $64,$06 ; LLB 6 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C0793 ; SKPFLS C0793 +; 2827: *valptr = #*valptr + DB $66,$02 ; LLW 2 + DB $66,$02 ; LLW 2 + DB $62 ; LW + DB $12 ; COMP + DB $72 ; SW +; 2828: fin +C0793: +C0794: +; 2829: if mod & 4 + DB $64,$06 ; LLB 6 + DB $2A,$04 ; CB 4 + DB $14 ; BAND + DB $4C,C0795 ; SKPFLS C0795 +; 2830: *valptr = !*valptr + DB $66,$02 ; LLW 2 + DB $66,$02 ; LLW 2 + DB $62 ; LW + DB $20 ; NOT + DB $72 ; SW +; 2831: fin +C0795: +C0796: +; 2832: return type + DB $64,$07 ; LLB 7 + DB $5A ; LEAVE +; 2833: end +; 2834: def ispostop_01 +C0797: ; ispostop_01() +; 2835: when token + JSR INTERP + DB $68,D0495 ; LAB D0495 +; 2836: is OPEN_PAREN_TKN + DB $2A,$A8 ; CB 168 + DB $3E,C0800 ; SKPNE C0800 +; 2837: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5C ; RET +; 2838: is OPEN_BRACKET_TKN + DB $50,C0799 ; SKIP C0799 +C0800: + DB $2A,$DB ; CB 219 + DB $3E,C0801 ; SKPNE C0801 +; 2839: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5C ; RET +; 2840: is DOT_TKN + DB $50,C0799 ; SKIP C0799 +C0801: + DB $2A,$AE ; CB 174 + DB $3E,C0802 ; SKPNE C0802 +; 2841: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5C ; RET +; 2842: is COLON_TKN + DB $50,C0799 ; SKIP C0799 +C0802: + DB $2A,$BA ; CB 186 + DB $3E,C0803 ; SKPNE C0803 +; 2843: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5C ; RET +; 2844: wend + DB $50,C0799 ; SKIP C0799 +C0803: +C0799: + DB $30 ; DROP +; 2845: return FALSE + DB $00 ; ZERO + DB $5C ; RET +; 2846: end +; 2847: def parse_value_11(rvalue) +C0805: ; parse_value_11() + ; rvalue = 2 +; 2848: byte cparams, deref, type, emit_val + ; cparams = 4 + ; deref = 5 + ; type = 6 + ; emit_val = 7 +; 2849: word optos, idptr, value + ; optos = 8 + ; idptr = 10 + ; value = 12 +; 2850: byte elem_type, elem_size + ; elem_type = 14 + ; elem_size = 15 +; 2851: word elem_offset + ; elem_offset = 16 +; 2852: +; 2853: deref = rvalue + JSR INTERP + DB $58,$12,$01 ; ENTER 18,1 + DB $66,$02 ; LLW 2 + DB $74,$05 ; SLB 5 +; 2854: optos = opsp + DB $6A,D0475 ; LAW D0475 + DB $76,$08 ; SLW 8 +; 2855: type = 0 + DB $00 ; ZERO + DB $74,$06 ; SLB 6 +; 2856: emit_val = 0 + DB $00 ; ZERO + DB $74,$07 ; SLB 7 +; 2857: value = 0 + DB $00 ; ZERO + DB $76,$0C ; SLW 12 +; 2858: +; 2859: ; +; 2860: ; Parse pre-ops +; 2861: ; +; 2862: while !parse_term_01() +C0807: + DB $54,C0756 ; CALL C0756 + DB $20 ; NOT + DB $4C,C0808 ; SKPFLS C0808 +; 2863: when token + DB $68,D0495 ; LAB D0495 +; 2864: is ADD_TKN + DB $2A,$AB ; CB 171 + DB $3E,C0810 ; SKPNE C0810 +; 2865: is BPTR_TKN + DB $50,C0809 ; SKIP C0809 +C0810: + DB $2A,$DE ; CB 222 + DB $3E,C0811 ; SKPNE C0811 +; 2866: if deref + DB $64,$05 ; LLB 5 + DB $4C,C0812 ; SKPFLS C0812 +; 2867: drop push_op_21(token, 0) + DB $68,D0495 ; LAB D0495 + DB $00 ; ZERO + DB $54,C0688 ; CALL C0688 + DB $30 ; DROP +; 2868: else + DB $50,C0813 ; SKIP C0813 +C0812: +; 2869: type = type ? BPTR_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$20 ; CB 32 + DB $16 ; IOR + DB $74,$06 ; SLB 6 +; 2870: deref = deref + 1 + DB $64,$05 ; LLB 5 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $74,$05 ; SLB 5 +; 2871: fin +C0813: +; 2872: is WPTR_TKN + DB $50,C0809 ; SKIP C0809 +C0811: + DB $2A,$AA ; CB 170 + DB $3E,C0814 ; SKPNE C0814 +; 2873: if deref + DB $64,$05 ; LLB 5 + DB $4C,C0815 ; SKPFLS C0815 +; 2874: drop push_op_21(token, 0) + DB $68,D0495 ; LAB D0495 + DB $00 ; ZERO + DB $54,C0688 ; CALL C0688 + DB $30 ; DROP +; 2875: else + DB $50,C0816 ; SKIP C0816 +C0815: +; 2876: type = type ? WPTR_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$40 ; CB 64 + DB $16 ; IOR + DB $74,$06 ; SLB 6 +; 2877: deref = deref + 1 + DB $64,$05 ; LLB 5 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $74,$05 ; SLB 5 +; 2878: fin +C0816: +; 2879: is AT_TKN + DB $50,C0809 ; SKIP C0809 +C0814: + DB $2A,$C0 ; CB 192 + DB $3E,C0817 ; SKPNE C0817 +; 2880: deref = deref - 1 + DB $64,$05 ; LLB 5 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $74,$05 ; SLB 5 +; 2881: is SUB_TKN + DB $50,C0809 ; SKIP C0809 +C0817: + DB $2A,$AD ; CB 173 + DB $3E,C0818 ; SKPNE C0818 +; 2882: drop push_op_21(token, 0) + DB $68,D0495 ; LAB D0495 + DB $00 ; ZERO + DB $54,C0688 ; CALL C0688 + DB $30 ; DROP +; 2883: is COMP_TKN + DB $50,C0809 ; SKIP C0809 +C0818: + DB $2A,$A3 ; CB 163 + DB $3E,C0819 ; SKPNE C0819 +; 2884: drop push_op_21(token, 0) + DB $68,D0495 ; LAB D0495 + DB $00 ; ZERO + DB $54,C0688 ; CALL C0688 + DB $30 ; DROP +; 2885: is LOGIC_NOT_TKN + DB $50,C0809 ; SKIP C0809 +C0819: + DB $2A,$A1 ; CB 161 + DB $3E,C0820 ; SKPNE C0820 +; 2886: drop push_op_21(token, 0) + DB $68,D0495 ; LAB D0495 + DB $00 ; ZERO + DB $54,C0688 ; CALL C0688 + DB $30 ; DROP +; 2887: otherwise + DB $50,C0809 ; SKIP C0809 +C0820: +; 2888: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2889: wend +C0809: + DB $30 ; DROP +; 2890: loop + DB $50,C0807 ; SKIP C0807 +C0808: +; 2891: ; +; 2892: ; Determine terminal type +; 2893: ; +; 2894: when token + DB $68,D0495 ; LAB D0495 +; 2895: is INT_TKN + DB $2A,$C9 ; CB 201 + DB $3E,C0823 ; SKPNE C0823 +; 2896: type = type ? CONST_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$01 ; CB 1 + DB $16 ; IOR + DB $74,$06 ; SLB 6 +; 2897: value = constval + DB $6A,D0505 ; LAW D0505 + DB $76,$0C ; SLW 12 +; 2898: is CHR_TKN + DB $50,C0822 ; SKIP C0822 +C0823: + DB $2A,$C3 ; CB 195 + DB $3E,C0824 ; SKPNE C0824 +; 2899: type = type ? CONST_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$01 ; CB 1 + DB $16 ; IOR + DB $74,$06 ; SLB 6 +; 2900: value = constval + DB $6A,D0505 ; LAW D0505 + DB $76,$0C ; SLW 12 +; 2901: is ID_TKN + DB $50,C0822 ; SKIP C0822 +C0824: + DB $2A,$D6 ; CB 214 + DB $3E,C0825 ; SKPNE C0825 +; 2902: idptr = id_lookup_21(tknptr, tknlen) + DB $6A,D0501 ; LAW D0501 + DB $68,D0496 ; LAB D0496 + DB $54,C0716 ; CALL C0716 + DB $76,$0A ; SLW 10 +; 2903: if !idptr + DB $66,$0A ; LLW 10 + DB $20 ; NOT + DB $4C,C0826 ; SKPFLS C0826 +; 2904: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2905: fin +C0826: +C0827: +; 2906: if !(idptr).idtype + DB $66,$0A ; LLW 10 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $60 ; LB + DB $20 ; NOT + DB $4C,C0828 ; SKPFLS C0828 +; 2907: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2908: fin +C0828: +C0829: +; 2909: type = type ? (idptr).idtype + DB $64,$06 ; LLB 6 + DB $66,$0A ; LLW 10 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $60 ; LB + DB $16 ; IOR + DB $74,$06 ; SLB 6 +; 2910: value = (idptr):idval + DB $66,$0A ; LLW 10 + DB $62 ; LW + DB $76,$0C ; SLW 12 +; 2911: is CLOSE_PAREN_TKN + DB $50,C0822 ; SKIP C0822 +C0825: + DB $2A,$A9 ; CB 169 + DB $3E,C0830 ; SKPNE C0830 +; 2912: type = type ? WORD_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$04 ; CB 4 + DB $16 ; IOR + DB $74,$06 ; SLB 6 +; 2913: emit_val = 1 + DB $2A,$01 ; CB 1 + DB $74,$07 ; SLB 7 +; 2914: otherwise + DB $50,C0822 ; SKIP C0822 +C0830: +; 2915: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 2916: wend +C0822: + DB $30 ; DROP +; 2917: ; +; 2918: ; Constant optimizations +; 2919: ; +; 2920: if type & CONST_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$01 ; CB 1 + DB $14 ; BAND + DB $4C,C0832 ; SKPFLS C0832 +; 2921: cparams = TRUE + DB $2C,$FF,$FF ; CW -1 + DB $74,$04 ; SLB 4 +; 2922: while optos < opsp and cparams +C0834: + DB $66,$08 ; LLW 8 + DB $6A,D0475 ; LAW D0475 + DB $46 ; ISLT + DB $64,$04 ; LLB 4 + DB $24 ; LAND + DB $4C,C0835 ; SKPFLS C0835 +; 2923: when tos_op_01() + DB $54,C0696 ; CALL C0696 +; 2924: is NEG_TKN + DB $2A,$AD ; CB 173 + DB $3E,C0837 ; SKPNE C0837 +; 2925: drop pop_op_01() + DB $54,C0692 ; CALL C0692 + DB $30 ; DROP +; 2926: value = -value + DB $66,$0C ; LLW 12 + DB $10 ; NEG + DB $76,$0C ; SLW 12 +; 2927: is COMP_TKN + DB $50,C0836 ; SKIP C0836 +C0837: + DB $2A,$A3 ; CB 163 + DB $3E,C0838 ; SKPNE C0838 +; 2928: drop pop_op_01() + DB $54,C0692 ; CALL C0692 + DB $30 ; DROP +; 2929: value = #value + DB $66,$0C ; LLW 12 + DB $12 ; COMP + DB $76,$0C ; SLW 12 +; 2930: is LOGIC_NOT_TKN + DB $50,C0836 ; SKIP C0836 +C0838: + DB $2A,$A1 ; CB 161 + DB $3E,C0839 ; SKPNE C0839 +; 2931: drop pop_op_01() + DB $54,C0692 ; CALL C0692 + DB $30 ; DROP +; 2932: value = !value + DB $66,$0C ; LLW 12 + DB $20 ; NOT + DB $76,$0C ; SLW 12 +; 2933: otherwise + DB $50,C0836 ; SKIP C0836 +C0839: +; 2934: cparams = FALSE + DB $00 ; ZERO + DB $74,$04 ; SLB 4 +; 2935: wend +C0836: + DB $30 ; DROP +; 2936: loop + DB $50,C0834 ; SKIP C0834 +C0835: +; 2937: fin +C0832: +C0833: +; 2938: ; +; 2939: ; Parse post-ops +; 2940: ; +; 2941: drop scan_01() + DB $54,C0629 ; CALL C0629 + DB $30 ; DROP +; 2942: while ispostop_01() +C0841: + DB $54,C0797 ; CALL C0797 + DB $4C,C0842 ; SKPFLS C0842 +; 2943: if token == OPEN_BRACKET_TKN + DB $68,D0495 ; LAB D0495 + DB $2A,$DB ; CB 219 + DB $40 ; ISEQ + DB $4C,C0843 ; SKPFLS C0843 +; 2944: ; +; 2945: ; Array +; 2946: ; +; 2947: if !emit_val + DB $64,$07 ; LLB 7 + DB $20 ; NOT + DB $4C,C0845 ; SKPFLS C0845 +; 2948: if type & ADDR_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$0E ; CB 14 + DB $14 ; BAND + DB $4C,C0847 ; SKPFLS C0847 +; 2949: if type & LOCAL_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$10 ; CB 16 + DB $14 ; BAND + DB $4C,C0849 ; SKPFLS C0849 +; 2950: emit_localaddr_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0529 ; CALL C0529 +; 2951: else + DB $50,C0850 ; SKIP C0850 +C0849: +; 2952: emit_globaladdr_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0531 ; CALL C0531 +; 2953: fin +C0850: +; 2954: elsif type & CONST_TYPE + DB $50,C0848 ; SKIP C0848 +C0847: + DB $64,$06 ; LLB 6 + DB $2A,$01 ; CB 1 + DB $14 ; BAND + DB $4C,C0851 ; SKPFLS C0851 +; 2955: emit_const_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0482 ; CALL C0482 +; 2956: fin +C0851: +C0848: +; 2957: emit_val = 1 + DB $2A,$01 ; CB 1 + DB $74,$07 ; SLB 7 +; 2958: fin ; !emit_val +C0845: +C0846: +; 2959: if type & PTR_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$60 ; CB 96 + DB $14 ; BAND + DB $4C,C0852 ; SKPFLS C0852 +; 2960: emit_lw() + DB $54,C0489 ; CALL C0489 +; 2961: fin +C0852: +C0853: +; 2962: if !parse_expr_01() + DB $54,C0001 ; CALL C0001 + DB $20 ; NOT + DB $4C,C0854 ; SKPFLS C0854 +; 2963: return 0 + DB $00 ; ZERO + DB $5A ; LEAVE +; 2964: fin +C0854: +C0855: +; 2965: if token <> CLOSE_BRACKET_TKN + DB $68,D0495 ; LAB D0495 + DB $2A,$DD ; CB 221 + DB $42 ; ISNE + DB $4C,C0856 ; SKPFLS C0856 +; 2966: return parse_err_11(@no_close_bracket) + DB $26,D0842 ; LA D0842 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 2967: fin +C0856: +C0857: +; 2968: if type & WORD_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$04 ; CB 4 + DB $14 ; BAND + DB $4C,C0858 ; SKPFLS C0858 +; 2969: type = WPTR_TYPE + DB $2A,$40 ; CB 64 + DB $74,$06 ; SLB 6 +; 2970: emit_indexword() + DB $54,C0535 ; CALL C0535 +; 2971: else + DB $50,C0859 ; SKIP C0859 +C0858: +; 2972: type = BPTR_TYPE + DB $2A,$20 ; CB 32 + DB $74,$06 ; SLB 6 +; 2973: emit_indexbyte() + DB $54,C0533 ; CALL C0533 +; 2974: fin +C0859: +; 2975: drop scan_01() + DB $54,C0629 ; CALL C0629 + DB $30 ; DROP +; 2976: elsif token == DOT_TKN or token == COLON_TKN + DB $50,C0844 ; SKIP C0844 +C0843: + DB $68,D0495 ; LAB D0495 + DB $2A,$AE ; CB 174 + DB $40 ; ISEQ + DB $68,D0495 ; LAB D0495 + DB $2A,$BA ; CB 186 + DB $40 ; ISEQ + DB $22 ; LOR + DB $4C,C0860 ; SKPFLS C0860 +; 2977: ; +; 2978: ; Dot and Colon +; 2979: ; +; 2980: if token == DOT_TKN + DB $68,D0495 ; LAB D0495 + DB $2A,$AE ; CB 174 + DB $40 ; ISEQ + DB $4C,C0861 ; SKPFLS C0861 +; 2981: elem_type = BPTR_TYPE + DB $2A,$20 ; CB 32 + DB $74,$0E ; SLB 14 +; 2982: else + DB $50,C0862 ; SKIP C0862 +C0861: +; 2983: elem_type = WPTR_TYPE + DB $2A,$40 ; CB 64 + DB $74,$0E ; SLB 14 +; 2984: fin +C0862: +; 2985: if parse_constval_21(@elem_offset, @elem_size) + DB $28,$10 ; LLA 16 + DB $28,$0F ; LLA 15 + DB $54,C0769 ; CALL C0769 + DB $4C,C0863 ; SKPFLS C0863 +; 2986: ; +; 2987: ; Constant structure offset +; 2988: ; +; 2989: if !emit_val + DB $64,$07 ; LLB 7 + DB $20 ; NOT + DB $4C,C0865 ; SKPFLS C0865 +; 2990: if type & VAR_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$06 ; CB 6 + DB $14 ; BAND + DB $4C,C0867 ; SKPFLS C0867 +; 2991: if type & LOCAL_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$10 ; CB 16 + DB $14 ; BAND + DB $4C,C0869 ; SKPFLS C0869 +; 2992: emit_localaddr_10(value + elem_offset) + DB $66,$0C ; LLW 12 + DB $66,$10 ; LLW 16 + DB $02 ; ADD + DB $54,C0529 ; CALL C0529 +; 2993: else + DB $50,C0870 ; SKIP C0870 +C0869: +; 2994: ; emit_globaladdr_10(value + elem_offset) +; 2995: emit_globaladdr_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0531 ; CALL C0531 +; 2996: emit_const_10(elem_offset) + DB $66,$10 ; LLW 16 + DB $54,C0482 ; CALL C0482 +; 2997: drop emit_binaryop_11(ADD_TKN) + DB $2A,$AB ; CB 171 + DB $54,C0548 ; CALL C0548 + DB $30 ; DROP +; 2998: fin +C0870: +; 2999: elsif type & CONST_TYPE + DB $50,C0868 ; SKIP C0868 +C0867: + DB $64,$06 ; LLB 6 + DB $2A,$01 ; CB 1 + DB $14 ; BAND + DB $4C,C0871 ; SKPFLS C0871 +; 3000: value = value + elem_offset + DB $66,$0C ; LLW 12 + DB $66,$10 ; LLW 16 + DB $02 ; ADD + DB $76,$0C ; SLW 12 +; 3001: emit_const_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0482 ; CALL C0482 +; 3002: else ; FUNC_TYPE + DB $50,C0868 ; SKIP C0868 +C0871: +; 3003: emit_globaladdr_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0531 ; CALL C0531 +; 3004: emit_const_10(elem_offset) + DB $66,$10 ; LLW 16 + DB $54,C0482 ; CALL C0482 +; 3005: drop emit_binaryop_11(ADD_TKN) + DB $2A,$AB ; CB 171 + DB $54,C0548 ; CALL C0548 + DB $30 ; DROP +; 3006: fin +C0868: +; 3007: emit_val = 1 + DB $2A,$01 ; CB 1 + DB $74,$07 ; SLB 7 +; 3008: else + DB $50,C0866 ; SKIP C0866 +C0865: +; 3009: if elem_offset <> 0 + DB $66,$10 ; LLW 16 + DB $00 ; ZERO + DB $42 ; ISNE + DB $4C,C0872 ; SKPFLS C0872 +; 3010: emit_const_10(elem_offset) + DB $66,$10 ; LLW 16 + DB $54,C0482 ; CALL C0482 +; 3011: drop emit_binaryop_11(ADD_TKN) + DB $2A,$AB ; CB 171 + DB $54,C0548 ; CALL C0548 + DB $30 ; DROP +; 3012: fin +C0872: +C0873: +; 3013: fin ; !emit_val +C0866: +; 3014: drop scan_01() + DB $54,C0629 ; CALL C0629 + DB $30 ; DROP +; 3015: elsif token == OPEN_BRACKET_TKN + DB $50,C0864 ; SKIP C0864 +C0863: + DB $68,D0495 ; LAB D0495 + DB $2A,$DB ; CB 219 + DB $40 ; ISEQ + DB $4C,C0874 ; SKPFLS C0874 +; 3016: ; +; 3017: ; Array of arrays +; 3018: ; +; 3019: if !emit_val + DB $64,$07 ; LLB 7 + DB $20 ; NOT + DB $4C,C0875 ; SKPFLS C0875 +; 3020: if type & ADDR_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$0E ; CB 14 + DB $14 ; BAND + DB $4C,C0877 ; SKPFLS C0877 +; 3021: if type & LOCAL_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$10 ; CB 16 + DB $14 ; BAND + DB $4C,C0879 ; SKPFLS C0879 +; 3022: emit_localaddr_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0529 ; CALL C0529 +; 3023: else + DB $50,C0880 ; SKIP C0880 +C0879: +; 3024: emit_globaladdr_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0531 ; CALL C0531 +; 3025: fin +C0880: +; 3026: elsif type & CONST_TYPE + DB $50,C0878 ; SKIP C0878 +C0877: + DB $64,$06 ; LLB 6 + DB $2A,$01 ; CB 1 + DB $14 ; BAND + DB $4C,C0881 ; SKPFLS C0881 +; 3027: emit_const_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0482 ; CALL C0482 +; 3028: fin +C0881: +C0878: +; 3029: emit_val = 1 + DB $2A,$01 ; CB 1 + DB $74,$07 ; SLB 7 +; 3030: fin ; !emit_val +C0875: +C0876: +; 3031: repeat +C0883: +; 3032: if emit_val > 1 + DB $64,$07 ; LLB 7 + DB $2A,$01 ; CB 1 + DB $44 ; ISGT + DB $4C,C0884 ; SKPFLS C0884 +; 3033: emit_indexword() + DB $54,C0535 ; CALL C0535 +; 3034: emit_lw() + DB $54,C0489 ; CALL C0489 +; 3035: fin +C0884: +C0885: +; 3036: emit_val = emit_val + 1 + DB $64,$07 ; LLB 7 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $74,$07 ; SLB 7 +; 3037: if !parse_expr_01() + DB $54,C0001 ; CALL C0001 + DB $20 ; NOT + DB $4C,C0886 ; SKPFLS C0886 +; 3038: return parse_err_11(@bad_expr) + DB $26,D0655 ; LA D0655 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3039: fin +C0886: +C0887: +; 3040: if token <> CLOSE_BRACKET_TKN + DB $68,D0495 ; LAB D0495 + DB $2A,$DD ; CB 221 + DB $42 ; ISNE + DB $4C,C0888 ; SKPFLS C0888 +; 3041: return parse_err_11(@no_close_bracket) + DB $26,D0842 ; LA D0842 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3042: fin +C0888: +C0889: +; 3043: until scan_01() <> OPEN_BRACKET_TKN + DB $54,C0629 ; CALL C0629 + DB $2A,$DB ; CB 219 + DB $42 ; ISNE + DB $4C,C0883 ; SKPFLS C0883 +C0882: +; 3044: if elem_type & WPTR_TYPE + DB $64,$0E ; LLB 14 + DB $2A,$40 ; CB 64 + DB $14 ; BAND + DB $4C,C0890 ; SKPFLS C0890 +; 3045: emit_indexword() + DB $54,C0535 ; CALL C0535 +; 3046: else + DB $50,C0891 ; SKIP C0891 +C0890: +; 3047: emit_indexbyte() + DB $54,C0533 ; CALL C0533 +; 3048: fin +C0891: +; 3049: else + DB $50,C0864 ; SKIP C0864 +C0874: +; 3050: return parse_err_11(@bad_offset) + DB $26,D0594 ; LA D0594 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3051: fin +C0864: +; 3052: type = elem_type + DB $64,$0E ; LLB 14 + DB $74,$06 ; SLB 6 +; 3053: elsif token == OPEN_PAREN_TKN + DB $50,C0844 ; SKIP C0844 +C0860: + DB $68,D0495 ; LAB D0495 + DB $2A,$A8 ; CB 168 + DB $40 ; ISEQ + DB $4C,C0892 ; SKPFLS C0892 +; 3054: ; +; 3055: ; Function call +; 3056: ; +; 3057: if !emit_val and type & VAR_TYPE + DB $64,$07 ; LLB 7 + DB $20 ; NOT + DB $64,$06 ; LLB 6 + DB $2A,$06 ; CB 6 + DB $14 ; BAND + DB $24 ; LAND + DB $4C,C0893 ; SKPFLS C0893 +; 3058: if type & LOCAL_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$10 ; CB 16 + DB $14 ; BAND + DB $4C,C0895 ; SKPFLS C0895 +; 3059: emit_localaddr_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0529 ; CALL C0529 +; 3060: else + DB $50,C0896 ; SKIP C0896 +C0895: +; 3061: emit_globaladdr_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0531 ; CALL C0531 +; 3062: fin +C0896: +; 3063: fin +C0893: +C0894: +; 3064: if !(type & FUNC_CONST_TYPE) + DB $64,$06 ; LLB 6 + DB $2A,$09 ; CB 9 + DB $14 ; BAND + DB $20 ; NOT + DB $4C,C0897 ; SKPFLS C0897 +; 3065: emit_push() + DB $54,C0523 ; CALL C0523 +; 3066: fin +C0897: +C0898: +; 3067: drop parse_expr_01() + DB $54,C0001 ; CALL C0001 + DB $30 ; DROP +; 3068: if token <> CLOSE_PAREN_TKN + DB $68,D0495 ; LAB D0495 + DB $2A,$A9 ; CB 169 + DB $42 ; ISNE + DB $4C,C0899 ; SKPFLS C0899 +; 3069: return parse_err_11(@no_close_paren) + DB $26,D0820 ; LA D0820 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3070: fin +C0899: +C0900: +; 3071: if type & FUNC_CONST_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$09 ; CB 9 + DB $14 ; BAND + DB $4C,C0901 ; SKPFLS C0901 +; 3072: emit_call_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0519 ; CALL C0519 +; 3073: else + DB $50,C0902 ; SKIP C0902 +C0901: +; 3074: emit_pull() + DB $54,C0525 ; CALL C0525 +; 3075: emit_ical() + DB $54,C0521 ; CALL C0521 +; 3076: fin +C0902: +; 3077: emit_val = 1 + DB $2A,$01 ; CB 1 + DB $74,$07 ; SLB 7 +; 3078: type = WORD_TYPE + DB $2A,$04 ; CB 4 + DB $74,$06 ; SLB 6 +; 3079: drop scan_01() + DB $54,C0629 ; CALL C0629 + DB $30 ; DROP +; 3080: fin +C0892: +C0844: +; 3081: loop + DB $50,C0841 ; SKIP C0841 +C0842: +; 3082: if emit_val + DB $64,$07 ; LLB 7 + DB $4C,C0903 ; SKPFLS C0903 +; 3083: if rvalue + DB $66,$02 ; LLW 2 + DB $4C,C0905 ; SKPFLS C0905 +; 3084: if deref and type & PTR_TYPE + DB $64,$05 ; LLB 5 + DB $64,$06 ; LLB 6 + DB $2A,$60 ; CB 96 + DB $14 ; BAND + DB $24 ; LAND + DB $4C,C0907 ; SKPFLS C0907 +; 3085: if type & BPTR_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$20 ; CB 32 + DB $14 ; BAND + DB $4C,C0909 ; SKPFLS C0909 +; 3086: emit_lb() + DB $54,C0487 ; CALL C0487 +; 3087: else + DB $50,C0910 ; SKIP C0910 +C0909: +; 3088: emit_lw() + DB $54,C0489 ; CALL C0489 +; 3089: fin +C0910: +; 3090: fin +C0907: +C0908: +; 3091: fin +C0905: +C0906: +; 3092: else ; emit_val + DB $50,C0904 ; SKIP C0904 +C0903: +; 3093: if type & CONST_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$01 ; CB 1 + DB $14 ; BAND + DB $4C,C0911 ; SKPFLS C0911 +; 3094: emit_const_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0482 ; CALL C0482 +; 3095: elsif deref + DB $50,C0912 ; SKIP C0912 +C0911: + DB $64,$05 ; LLB 5 + DB $4C,C0913 ; SKPFLS C0913 +; 3096: if type & FUNC_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$08 ; CB 8 + DB $14 ; BAND + DB $4C,C0914 ; SKPFLS C0914 +; 3097: emit_call_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0519 ; CALL C0519 +; 3098: elsif type & VAR_TYPE + DB $50,C0915 ; SKIP C0915 +C0914: + DB $64,$06 ; LLB 6 + DB $2A,$06 ; CB 6 + DB $14 ; BAND + DB $4C,C0916 ; SKPFLS C0916 +; 3099: if type & LOCAL_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$10 ; CB 16 + DB $14 ; BAND + DB $4C,C0917 ; SKPFLS C0917 +; 3100: if type & BYTE_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C0919 ; SKPFLS C0919 +; 3101: emit_llb_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0491 ; CALL C0491 +; 3102: else + DB $50,C0920 ; SKIP C0920 +C0919: +; 3103: emit_llw_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0493 ; CALL C0493 +; 3104: fin +C0920: +; 3105: else + DB $50,C0918 ; SKIP C0918 +C0917: +; 3106: if type & BYTE_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C0921 ; SKPFLS C0921 +; 3107: emit_lab_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0495 ; CALL C0495 +; 3108: else + DB $50,C0922 ; SKIP C0922 +C0921: +; 3109: emit_law_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0497 ; CALL C0497 +; 3110: fin +C0922: +; 3111: fin +C0918: +; 3112: elsif type & PTR_TYPE + DB $50,C0915 ; SKIP C0915 +C0916: + DB $64,$06 ; LLB 6 + DB $2A,$60 ; CB 96 + DB $14 ; BAND + DB $4C,C0923 ; SKPFLS C0923 +; 3113: if type & BPTR_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$20 ; CB 32 + DB $14 ; BAND + DB $4C,C0924 ; SKPFLS C0924 +; 3114: emit_lb() + DB $54,C0487 ; CALL C0487 +; 3115: else + DB $50,C0925 ; SKIP C0925 +C0924: +; 3116: emit_lw() + DB $54,C0489 ; CALL C0489 +; 3117: fin +C0925: +; 3118: fin +C0923: +C0915: +; 3119: else + DB $50,C0912 ; SKIP C0912 +C0913: +; 3120: if type & LOCAL_TYPE + DB $64,$06 ; LLB 6 + DB $2A,$10 ; CB 16 + DB $14 ; BAND + DB $4C,C0926 ; SKPFLS C0926 +; 3121: emit_localaddr_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0529 ; CALL C0529 +; 3122: else + DB $50,C0927 ; SKIP C0927 +C0926: +; 3123: emit_globaladdr_10(value) + DB $66,$0C ; LLW 12 + DB $54,C0531 ; CALL C0531 +; 3124: fin +C0927: +; 3125: fin +C0912: +; 3126: fin ; emit_val +C0904: +; 3127: while optos < opsp +C0928: + DB $66,$08 ; LLW 8 + DB $6A,D0475 ; LAW D0475 + DB $46 ; ISLT + DB $4C,C0929 ; SKPFLS C0929 +; 3128: if !emit_unaryop_11(pop_op_01()) + DB $54,C0692 ; CALL C0692 + DB $54,C0537 ; CALL C0537 + DB $20 ; NOT + DB $4C,C0930 ; SKPFLS C0930 +; 3129: return parse_err_11(@bad_op) + DB $26,D0628 ; LA D0628 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3130: fin +C0930: +C0931: +; 3131: loop + DB $50,C0928 ; SKIP C0928 +C0929: +; 3132: return type + DB $64,$06 ; LLB 6 + DB $5A ; LEAVE +; 3133: end +; 3134: def parse_constexpr_21(valptr, sizeptr) +C0932: ; parse_constexpr_21() + ; valptr = 2 + ; sizeptr = 4 +; 3135: byte type, size1, size2 + ; type = 6 + ; size1 = 7 + ; size2 = 8 +; 3136: word val1, val2 + ; val1 = 9 + ; val2 = 11 +; 3137: +; 3138: type = parse_constval_21(@val1, @size1) + JSR INTERP + DB $58,$0D,$02 ; ENTER 13,2 + DB $28,$09 ; LLA 9 + DB $28,$07 ; LLA 7 + DB $54,C0769 ; CALL C0769 + DB $74,$06 ; SLB 6 +; 3139: if !type + DB $64,$06 ; LLB 6 + DB $20 ; NOT + DB $4C,C0934 ; SKPFLS C0934 +; 3140: return 0 + DB $00 ; ZERO + DB $5A ; LEAVE +; 3141: fin +C0934: +C0935: +; 3142: size2 = 0 + DB $00 ; ZERO + DB $74,$08 ; SLB 8 +; 3143: when scan_01() + DB $54,C0629 ; CALL C0629 +; 3144: is ADD_TKN + DB $2A,$AB ; CB 171 + DB $3E,C0937 ; SKPNE C0937 +; 3145: type = parse_constval_21(@val2, @size2) + DB $28,$0B ; LLA 11 + DB $28,$08 ; LLA 8 + DB $54,C0769 ; CALL C0769 + DB $74,$06 ; SLB 6 +; 3146: if !type + DB $64,$06 ; LLB 6 + DB $20 ; NOT + DB $4C,C0938 ; SKPFLS C0938 +; 3147: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 3148: fin +C0938: +C0939: +; 3149: *valptr = val1 + val2 + DB $66,$02 ; LLW 2 + DB $66,$09 ; LLW 9 + DB $66,$0B ; LLW 11 + DB $02 ; ADD + DB $72 ; SW +; 3150: is SUB_TKN + DB $50,C0936 ; SKIP C0936 +C0937: + DB $2A,$AD ; CB 173 + DB $3E,C0940 ; SKPNE C0940 +; 3151: type = parse_constval_21(@val2, @size2) + DB $28,$0B ; LLA 11 + DB $28,$08 ; LLA 8 + DB $54,C0769 ; CALL C0769 + DB $74,$06 ; SLB 6 +; 3152: if !type + DB $64,$06 ; LLB 6 + DB $20 ; NOT + DB $4C,C0941 ; SKPFLS C0941 +; 3153: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 3154: fin +C0941: +C0942: +; 3155: *valptr = val1 - val2 + DB $66,$02 ; LLW 2 + DB $66,$09 ; LLW 9 + DB $66,$0B ; LLW 11 + DB $04 ; SUB + DB $72 ; SW +; 3156: is MUL_TKN + DB $50,C0936 ; SKIP C0936 +C0940: + DB $2A,$AA ; CB 170 + DB $3E,C0943 ; SKPNE C0943 +; 3157: type = parse_constval_21(@val2, @size2) + DB $28,$0B ; LLA 11 + DB $28,$08 ; LLA 8 + DB $54,C0769 ; CALL C0769 + DB $74,$06 ; SLB 6 +; 3158: if !type + DB $64,$06 ; LLB 6 + DB $20 ; NOT + DB $4C,C0944 ; SKPFLS C0944 +; 3159: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 3160: fin +C0944: +C0945: +; 3161: *valptr = val1 * val2 + DB $66,$02 ; LLW 2 + DB $66,$09 ; LLW 9 + DB $66,$0B ; LLW 11 + DB $06 ; MUL + DB $72 ; SW +; 3162: is DIV_TKN + DB $50,C0936 ; SKIP C0936 +C0943: + DB $2A,$AF ; CB 175 + DB $3E,C0946 ; SKPNE C0946 +; 3163: type = parse_constval_21(@val2, @size2) + DB $28,$0B ; LLA 11 + DB $28,$08 ; LLA 8 + DB $54,C0769 ; CALL C0769 + DB $74,$06 ; SLB 6 +; 3164: if !type + DB $64,$06 ; LLB 6 + DB $20 ; NOT + DB $4C,C0947 ; SKPFLS C0947 +; 3165: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 3166: fin +C0947: +C0948: +; 3167: *valptr = val1 + val2 + DB $66,$02 ; LLW 2 + DB $66,$09 ; LLW 9 + DB $66,$0B ; LLW 11 + DB $02 ; ADD + DB $72 ; SW +; 3168: is MOD_TKN + DB $50,C0936 ; SKIP C0936 +C0946: + DB $2A,$A5 ; CB 165 + DB $3E,C0949 ; SKPNE C0949 +; 3169: type = parse_constval_21(@val2, @size2) + DB $28,$0B ; LLA 11 + DB $28,$08 ; LLA 8 + DB $54,C0769 ; CALL C0769 + DB $74,$06 ; SLB 6 +; 3170: if !type + DB $64,$06 ; LLB 6 + DB $20 ; NOT + DB $4C,C0950 ; SKPFLS C0950 +; 3171: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 3172: fin +C0950: +C0951: +; 3173: *valptr = val1 % val2 + DB $66,$02 ; LLW 2 + DB $66,$09 ; LLW 9 + DB $66,$0B ; LLW 11 + DB $0A ; DIV,MOD + DB $72 ; SW +; 3174: drop + DB $30 ; DROP +; 3175: is AND_TKN + DB $50,C0936 ; SKIP C0936 +C0949: + DB $2A,$A6 ; CB 166 + DB $3E,C0952 ; SKPNE C0952 +; 3176: type = parse_constval_21(@val2, @size2) + DB $28,$0B ; LLA 11 + DB $28,$08 ; LLA 8 + DB $54,C0769 ; CALL C0769 + DB $74,$06 ; SLB 6 +; 3177: if !type + DB $64,$06 ; LLB 6 + DB $20 ; NOT + DB $4C,C0953 ; SKPFLS C0953 +; 3178: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 3179: fin +C0953: +C0954: +; 3180: *valptr = val1 & val2 + DB $66,$02 ; LLW 2 + DB $66,$09 ; LLW 9 + DB $66,$0B ; LLW 11 + DB $14 ; BAND + DB $72 ; SW +; 3181: is OR_TKN + DB $50,C0936 ; SKIP C0936 +C0952: + DB $2A,$BF ; CB 191 + DB $3E,C0955 ; SKPNE C0955 +; 3182: type = parse_constval_21(@val2, @size2) + DB $28,$0B ; LLA 11 + DB $28,$08 ; LLA 8 + DB $54,C0769 ; CALL C0769 + DB $74,$06 ; SLB 6 +; 3183: if !type + DB $64,$06 ; LLB 6 + DB $20 ; NOT + DB $4C,C0956 ; SKPFLS C0956 +; 3184: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 3185: fin +C0956: +C0957: +; 3186: *valptr = val1 ? val2 + DB $66,$02 ; LLW 2 + DB $66,$09 ; LLW 9 + DB $66,$0B ; LLW 11 + DB $16 ; IOR + DB $72 ; SW +; 3187: is EOR_TKN + DB $50,C0936 ; SKIP C0936 +C0955: + DB $2A,$DE ; CB 222 + DB $3E,C0958 ; SKPNE C0958 +; 3188: type = parse_constval_21(@val2, @size2) + DB $28,$0B ; LLA 11 + DB $28,$08 ; LLA 8 + DB $54,C0769 ; CALL C0769 + DB $74,$06 ; SLB 6 +; 3189: if !type + DB $64,$06 ; LLB 6 + DB $20 ; NOT + DB $4C,C0959 ; SKPFLS C0959 +; 3190: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 3191: fin +C0959: +C0960: +; 3192: *valptr = val1 ^ val2 + DB $66,$02 ; LLW 2 + DB $66,$09 ; LLW 9 + DB $66,$0B ; LLW 11 + DB $18 ; XOR + DB $72 ; SW +; 3193: otherwise + DB $50,C0936 ; SKIP C0936 +C0958: +; 3194: *valptr = val1 + DB $66,$02 ; LLW 2 + DB $66,$09 ; LLW 9 + DB $72 ; SW +; 3195: wend +C0936: + DB $30 ; DROP +; 3196: if size1 > size2 + DB $64,$07 ; LLB 7 + DB $64,$08 ; LLB 8 + DB $44 ; ISGT + DB $4C,C0962 ; SKPFLS C0962 +; 3197: ^sizeptr = size1 + DB $66,$04 ; LLW 4 + DB $64,$07 ; LLB 7 + DB $70 ; SB +; 3198: else + DB $50,C0963 ; SKIP C0963 +C0962: +; 3199: ^sizeptr = size2 + DB $66,$04 ; LLW 4 + DB $64,$08 ; LLB 8 + DB $70 ; SB +; 3200: fin +C0963: +; 3201: return type + DB $64,$06 ; LLB 6 + DB $5A ; LEAVE +; 3202: end +; 3203: def parse_expr_01 +C0001: ; parse_expr_01() +; 3204: byte prevmatch, matchop, i + ; prevmatch = 2 + ; matchop = 3 + ; i = 4 +; 3205: word optos + ; optos = 5 +; 3206: +; 3207: matchop = 0 + JSR INTERP + DB $58,$07,$00 ; ENTER 7,0 + DB $00 ; ZERO + DB $74,$03 ; SLB 3 +; 3208: optos = opsp + DB $6A,D0475 ; LAW D0475 + DB $76,$05 ; SLW 5 +; 3209: repeat +C0966: +; 3210: prevmatch = matchop + DB $64,$03 ; LLB 3 + DB $74,$02 ; SLB 2 +; 3211: matchop = 0 + DB $00 ; ZERO + DB $74,$03 ; SLB 3 +; 3212: if parse_value_11(1) + DB $2A,$01 ; CB 1 + DB $54,C0805 ; CALL C0805 + DB $4C,C0967 ; SKPFLS C0967 +; 3213: matchop = 1 + DB $2A,$01 ; CB 1 + DB $74,$03 ; SLB 3 +; 3214: for i = 0 to bops_tblsz + DB $00 ; ZERO +C0970: + DB $6C,$04 ; DLB 4 + DB $2A,$12 ; CB 18 + DB $3A,C0969 ; SKPGT C0969 + DB $0C ; INCR +; 3215: if token == bops_tbl[i] + DB $68,D0495 ; LAB D0495 + DB $26,D0405 ; LA D0405 + DB $64,$04 ; LLB 4 + DB $02 ; IDXB + DB $60 ; LB + DB $40 ; ISEQ + DB $4C,C0971 ; SKPFLS C0971 +; 3216: matchop = 2 + DB $2A,$02 ; CB 2 + DB $74,$03 ; SLB 3 +; 3217: if bops_prec[i] >= tos_op_prec_11(optos) + DB $26,D0424 ; LA D0424 + DB $64,$04 ; LLB 4 + DB $02 ; IDXB + DB $60 ; LB + DB $66,$05 ; LLW 5 + DB $54,C0700 ; CALL C0700 + DB $48 ; ISGE + DB $4C,C0973 ; SKPFLS C0973 +; 3218: if !emit_binaryop_11(pop_op_01()) + DB $54,C0692 ; CALL C0692 + DB $54,C0548 ; CALL C0548 + DB $20 ; NOT + DB $4C,C0975 ; SKPFLS C0975 +; 3219: return parse_err_11(@bad_op) + DB $30 ; DROP + DB $26,D0628 ; LA D0628 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3220: fin +C0975: +C0976: +; 3221: fin +C0973: +C0974: +; 3222: drop push_op_21(token, bops_prec[i]) + DB $68,D0495 ; LAB D0495 + DB $26,D0424 ; LA D0424 + DB $64,$04 ; LLB 4 + DB $02 ; IDXB + DB $60 ; LB + DB $54,C0688 ; CALL C0688 + DB $30 ; DROP +; 3223: break + DB $50,C0969 ; SKIP C0969 +; 3224: fin +C0971: +C0972: +; 3225: next + DB $50,C0970 ; SKIP C0970 +C0969: + DB $30 ; DROP +; 3226: fin +C0967: +C0968: +; 3227: until matchop <> 2 + DB $64,$03 ; LLB 3 + DB $2A,$02 ; CB 2 + DB $42 ; ISNE + DB $4C,C0966 ; SKPFLS C0966 +C0965: +; 3228: if matchop == 0 and prevmatch == 2 + DB $64,$03 ; LLB 3 + DB $00 ; ZERO + DB $40 ; ISEQ + DB $64,$02 ; LLB 2 + DB $2A,$02 ; CB 2 + DB $40 ; ISEQ + DB $24 ; LAND + DB $4C,C0977 ; SKPFLS C0977 +; 3229: return parse_err_11(@missing_op) + DB $26,D0866 ; LA D0866 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3230: fin +C0977: +C0978: +; 3231: while optos < opsp +C0979: + DB $66,$05 ; LLW 5 + DB $6A,D0475 ; LAW D0475 + DB $46 ; ISLT + DB $4C,C0980 ; SKPFLS C0980 +; 3232: if !emit_binaryop_11(pop_op_01()) + DB $54,C0692 ; CALL C0692 + DB $54,C0548 ; CALL C0548 + DB $20 ; NOT + DB $4C,C0981 ; SKPFLS C0981 +; 3233: return parse_err_11(@bad_op) + DB $26,D0628 ; LA D0628 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3234: fin +C0981: +C0982: +; 3235: loop + DB $50,C0979 ; SKIP C0979 +C0980: +; 3236: return matchop or prevmatch + DB $64,$03 ; LLB 3 + DB $64,$02 ; LLB 2 + DB $22 ; LOR + DB $5A ; LEAVE +; 3237: end +; 3238: def parse_setlist_21(addr, type) +C0983: ; parse_setlist_21() + ; addr = 2 + ; type = 4 +; 3239: word nexttype, nextaddr, idptr, saveptr + ; nexttype = 6 + ; nextaddr = 8 + ; idptr = 10 + ; saveptr = 12 +; 3240: +; 3241: if !(type & VAR_TYPE) + JSR INTERP + DB $58,$0E,$02 ; ENTER 14,2 + DB $66,$04 ; LLW 4 + DB $2A,$06 ; CB 6 + DB $14 ; BAND + DB $20 ; NOT + DB $4C,C0985 ; SKPFLS C0985 +; 3242: emit_push() + DB $54,C0523 ; CALL C0523 +; 3243: fin +C0985: +C0986: +; 3244: nexttype = 0 + DB $00 ; ZERO + DB $76,$06 ; SLW 6 +; 3245: nextaddr = 0 + DB $00 ; ZERO + DB $76,$08 ; SLW 8 +; 3246: if scan_01() == ID_TKN + DB $54,C0629 ; CALL C0629 + DB $2A,$D6 ; CB 214 + DB $40 ; ISEQ + DB $4C,C0987 ; SKPFLS C0987 +; 3247: idptr = id_lookup_21(tknptr, tknlen) + DB $6A,D0501 ; LAW D0501 + DB $68,D0496 ; LAB D0496 + DB $54,C0716 ; CALL C0716 + DB $76,$0A ; SLW 10 +; 3248: if !idptr + DB $66,$0A ; LLW 10 + DB $20 ; NOT + DB $4C,C0989 ; SKPFLS C0989 +; 3249: return FALSE + DB $00 ; ZERO + DB $5A ; LEAVE +; 3250: fin +C0989: +C0990: +; 3251: nexttype = (idptr).idtype + DB $66,$0A ; LLW 10 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $60 ; LB + DB $76,$06 ; SLW 6 +; 3252: if type & VAR_TYPE + DB $66,$04 ; LLW 4 + DB $2A,$06 ; CB 6 + DB $14 ; BAND + DB $4C,C0991 ; SKPFLS C0991 +; 3253: nextaddr = (idptr):idval + DB $66,$0A ; LLW 10 + DB $62 ; LW + DB $76,$08 ; SLW 8 +; 3254: fin +C0991: +C0992: +; 3255: fin +C0987: +C0988: +; 3256: saveptr = tknptr + DB $6A,D0501 ; LAW D0501 + DB $76,$0C ; SLW 12 +; 3257: drop scan_01() + DB $54,C0629 ; CALL C0629 + DB $30 ; DROP +; 3258: if nexttype & VAR_TYPE and token == SET_TKN + DB $66,$06 ; LLW 6 + DB $2A,$06 ; CB 6 + DB $14 ; BAND + DB $68,D0495 ; LAB D0495 + DB $2A,$BD ; CB 189 + DB $40 ; ISEQ + DB $24 ; LAND + DB $4C,C0993 ; SKPFLS C0993 +; 3259: drop parse_expr_01() + DB $54,C0001 ; CALL C0001 + DB $30 ; DROP +; 3260: if type & LOCAL_TYPE + DB $66,$04 ; LLW 4 + DB $2A,$10 ; CB 16 + DB $14 ; BAND + DB $4C,C0995 ; SKPFLS C0995 +; 3261: if type & BYTE_TYPE + DB $66,$04 ; LLW 4 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C0997 ; SKPFLS C0997 +; 3262: emit_slb_10(nextaddr) + DB $66,$08 ; LLW 8 + DB $54,C0503 ; CALL C0503 +; 3263: else + DB $50,C0998 ; SKIP C0998 +C0997: +; 3264: emit_slw_10(nextaddr) + DB $66,$08 ; LLW 8 + DB $54,C0505 ; CALL C0505 +; 3265: fin +C0998: +; 3266: else + DB $50,C0996 ; SKIP C0996 +C0995: +; 3267: if type & BYTE_TYPE + DB $66,$04 ; LLW 4 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C0999 ; SKPFLS C0999 +; 3268: emit_sab_10(nextaddr) + DB $66,$08 ; LLW 8 + DB $54,C0511 ; CALL C0511 +; 3269: else + DB $50,C1000 ; SKIP C1000 +C0999: +; 3270: emit_saw_10(nextaddr) + DB $66,$08 ; LLW 8 + DB $54,C0513 ; CALL C0513 +; 3271: fin +C1000: +; 3272: fin +C0996: +; 3273: elsif nexttype & VAR_TYPE and token == SETLIST_TKN + DB $50,C0994 ; SKIP C0994 +C0993: + DB $66,$06 ; LLW 6 + DB $2A,$06 ; CB 6 + DB $14 ; BAND + DB $68,D0495 ; LAB D0495 + DB $2A,$B9 ; CB 185 + DB $40 ; ISEQ + DB $24 ; LAND + DB $4C,C1001 ; SKPFLS C1001 +; 3274: if !parse_setlist_21(nextaddr, nexttype) + DB $66,$08 ; LLW 8 + DB $66,$06 ; LLW 6 + DB $54,C0983 ; CALL C0983 + DB $20 ; NOT + DB $4C,C1002 ; SKPFLS C1002 +; 3275: return FALSE + DB $00 ; ZERO + DB $5A ; LEAVE +; 3276: fin +C1002: +C1003: +; 3277: else + DB $50,C0994 ; SKIP C0994 +C1001: +; 3278: tknptr = saveptr + DB $66,$0C ; LLW 12 + DB $7A,D0501 ; SAW D0501 +; 3279: rewind_10(tknptr) + DB $6A,D0501 ; LAW D0501 + DB $54,C0680 ; CALL C0680 +; 3280: nexttype = parse_value_11(0) + DB $00 ; ZERO + DB $54,C0805 ; CALL C0805 + DB $76,$06 ; SLW 6 +; 3281: if nexttype <> 0 + DB $66,$06 ; LLW 6 + DB $00 ; ZERO + DB $42 ; ISNE + DB $4C,C1004 ; SKPFLS C1004 +; 3282: if token == SET_TKN + DB $68,D0495 ; LAB D0495 + DB $2A,$BD ; CB 189 + DB $40 ; ISEQ + DB $4C,C1006 ; SKPFLS C1006 +; 3283: emit_push() + DB $54,C0523 ; CALL C0523 +; 3284: drop parse_expr_01() + DB $54,C0001 ; CALL C0001 + DB $30 ; DROP +; 3285: emit_pull() + DB $54,C0525 ; CALL C0525 +; 3286: emit_swap() + DB $54,C0593 ; CALL C0593 +; 3287: if nexttype & (BYTE_TYPE ? BPTR_TYPE) + DB $66,$06 ; LLW 6 + DB $2A,$02 ; CB 2 + DB $2A,$20 ; CB 32 + DB $16 ; IOR + DB $14 ; BAND + DB $4C,C1008 ; SKPFLS C1008 +; 3288: emit_sb() + DB $54,C0499 ; CALL C0499 +; 3289: else + DB $50,C1009 ; SKIP C1009 +C1008: +; 3290: emit_sw() + DB $54,C0501 ; CALL C0501 +; 3291: fin +C1009: +; 3292: fin +C1006: +C1007: +; 3293: elsif token == SETLIST_TKN + DB $50,C1005 ; SKIP C1005 +C1004: + DB $68,D0495 ; LAB D0495 + DB $2A,$B9 ; CB 185 + DB $40 ; ISEQ + DB $4C,C1010 ; SKPFLS C1010 +; 3294: if !parse_setlist_21(0, nexttype) + DB $00 ; ZERO + DB $66,$06 ; LLW 6 + DB $54,C0983 ; CALL C0983 + DB $20 ; NOT + DB $4C,C1011 ; SKPFLS C1011 +; 3295: return FALSE + DB $00 ; ZERO + DB $5A ; LEAVE +; 3296: fin +C1011: +C1012: +; 3297: else + DB $50,C1005 ; SKIP C1005 +C1010: +; 3298: return parse_err_11(@bad_syntax) + DB $26,D0670 ; LA D0670 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3299: fin +C1005: +; 3300: fin +C0994: +; 3301: if type & VAR_TYPE + DB $66,$04 ; LLW 4 + DB $2A,$06 ; CB 6 + DB $14 ; BAND + DB $4C,C1013 ; SKPFLS C1013 +; 3302: if type & LOCAL_TYPE + DB $66,$04 ; LLW 4 + DB $2A,$10 ; CB 16 + DB $14 ; BAND + DB $4C,C1015 ; SKPFLS C1015 +; 3303: if type & BYTE_TYPE + DB $66,$04 ; LLW 4 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C1017 ; SKPFLS C1017 +; 3304: emit_slb_10(addr) + DB $66,$02 ; LLW 2 + DB $54,C0503 ; CALL C0503 +; 3305: else + DB $50,C1018 ; SKIP C1018 +C1017: +; 3306: emit_slw_10(addr) + DB $66,$02 ; LLW 2 + DB $54,C0505 ; CALL C0505 +; 3307: fin +C1018: +; 3308: else + DB $50,C1016 ; SKIP C1016 +C1015: +; 3309: if type & BYTE_TYPE + DB $66,$04 ; LLW 4 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C1019 ; SKPFLS C1019 +; 3310: emit_sab_10(addr) + DB $66,$02 ; LLW 2 + DB $54,C0511 ; CALL C0511 +; 3311: else + DB $50,C1020 ; SKIP C1020 +C1019: +; 3312: emit_saw_10(addr) + DB $66,$02 ; LLW 2 + DB $54,C0513 ; CALL C0513 +; 3313: fin +C1020: +; 3314: fin +C1016: +; 3315: else + DB $50,C1014 ; SKIP C1014 +C1013: +; 3316: emit_pull() + DB $54,C0525 ; CALL C0525 +; 3317: emit_swap() + DB $54,C0593 ; CALL C0593 +; 3318: if type & (BYTE_TYPE ? BPTR_TYPE) + DB $66,$04 ; LLW 4 + DB $2A,$02 ; CB 2 + DB $2A,$20 ; CB 32 + DB $16 ; IOR + DB $14 ; BAND + DB $4C,C1021 ; SKPFLS C1021 +; 3319: emit_sb() + DB $54,C0499 ; CALL C0499 +; 3320: else + DB $50,C1022 ; SKIP C1022 +C1021: +; 3321: emit_sw() + DB $54,C0501 ; CALL C0501 +; 3322: fin +C1022: +; 3323: fin +C1014: +; 3324: return TRUE + DB $2C,$FF,$FF ; CW -1 + DB $5A ; LEAVE +; 3325: end +; 3326: def parse_stmnt_01 +C1023: ; parse_stmnt_01() +; 3327: byte type, i + ; type = 2 + ; i = 3 +; 3328: word tag_prevbrk, tag_else, tag_endif, tag_while, tag_wend + ; tag_prevbrk = 4 + ; tag_else = 6 + ; tag_endif = 8 + ; tag_while = 10 + ; tag_wend = 12 +; 3329: word tag_repeat, tag_for, tag_choice, idptr, saveptr, addr, stepdir + ; tag_repeat = 14 + ; tag_for = 16 + ; tag_choice = 18 + ; idptr = 20 + ; saveptr = 22 + ; addr = 24 + ; stepdir = 26 +; 3330: +; 3331: if token <> END_TKN and token <> DONE_TKN + JSR INTERP + DB $58,$1C,$00 ; ENTER 28,0 + DB $68,D0495 ; LAB D0495 + DB $2A,$87 ; CB 135 + DB $42 ; ISNE + DB $68,D0495 ; LAB D0495 + DB $2A,$98 ; CB 152 + DB $42 ; ISNE + DB $24 ; LAND + DB $4C,C1025 ; SKPFLS C1025 +; 3332: prevstmnt = token + DB $68,D0495 ; LAB D0495 + DB $78,D1104 ; SAB D1104 +; 3333: fin +C1025: +C1026: +; 3334: when token + DB $68,D0495 ; LAB D0495 +; 3335: is IF_TKN + DB $2A,$83 ; CB 131 + DB $3E,C1028 ; SKPNE C1028 +; 3336: drop parse_expr_01() + DB $54,C0001 ; CALL C0001 + DB $30 ; DROP +; 3337: tag_else = ctag_new_01() + DB $54,C0445 ; CALL C0445 + DB $76,$06 ; SLW 6 +; 3338: tag_endif = ctag_new_01() + DB $54,C0445 ; CALL C0445 + DB $76,$08 ; SLW 8 +; 3339: emit_brfls_10(tag_else) + DB $66,$06 ; LLW 6 + DB $54,C0581 ; CALL C0581 +; 3340: drop scan_01() + DB $54,C0629 ; CALL C0629 + DB $30 ; DROP +; 3341: repeat +C1030: +; 3342: while parse_stmnt_01() +C1031: + DB $54,C1023 ; CALL C1023 + DB $4C,C1032 ; SKPFLS C1032 +; 3343: drop nextln_01() + DB $54,C0682 ; CALL C0682 + DB $30 ; DROP +; 3344: loop + DB $50,C1031 ; SKIP C1031 +C1032: +; 3345: if token <> ELSEIF_TKN + DB $68,D0495 ; LAB D0495 + DB $2A,$84 ; CB 132 + DB $42 ; ISNE + DB $4C,C1033 ; SKPFLS C1033 +; 3346: break + DB $50,C1029 ; SKIP C1029 +; 3347: fin +C1033: +C1034: +; 3348: emit_jump_10(tag_endif) + DB $66,$08 ; LLW 8 + DB $54,C0589 ; CALL C0589 +; 3349: emit_codetag_10(tag_else) + DB $66,$06 ; LLW 6 + DB $54,C0461 ; CALL C0461 +; 3350: if !parse_expr_01() + DB $54,C0001 ; CALL C0001 + DB $20 ; NOT + DB $4C,C1035 ; SKPFLS C1035 +; 3351: return 0 + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 3352: fin +C1035: +C1036: +; 3353: tag_else = ctag_new_01() + DB $54,C0445 ; CALL C0445 + DB $76,$06 ; SLW 6 +; 3354: emit_brfls_10(tag_else) + DB $66,$06 ; LLW 6 + DB $54,C0581 ; CALL C0581 +; 3355: until FALSE + DB $00 ; ZERO + DB $4C,C1030 ; SKPFLS C1030 +C1029: +; 3356: if token == ELSE_TKN + DB $68,D0495 ; LAB D0495 + DB $2A,$85 ; CB 133 + DB $40 ; ISEQ + DB $4C,C1037 ; SKPFLS C1037 +; 3357: emit_jump_10(tag_endif) + DB $66,$08 ; LLW 8 + DB $54,C0589 ; CALL C0589 +; 3358: emit_codetag_10(tag_else) + DB $66,$06 ; LLW 6 + DB $54,C0461 ; CALL C0461 +; 3359: drop scan_01() + DB $54,C0629 ; CALL C0629 + DB $30 ; DROP +; 3360: while parse_stmnt_01() +C1039: + DB $54,C1023 ; CALL C1023 + DB $4C,C1040 ; SKPFLS C1040 +; 3361: drop nextln_01() + DB $54,C0682 ; CALL C0682 + DB $30 ; DROP +; 3362: loop + DB $50,C1039 ; SKIP C1039 +C1040: +; 3363: emit_codetag_10(tag_endif) + DB $66,$08 ; LLW 8 + DB $54,C0461 ; CALL C0461 +; 3364: else + DB $50,C1038 ; SKIP C1038 +C1037: +; 3365: emit_codetag_10(tag_else) + DB $66,$06 ; LLW 6 + DB $54,C0461 ; CALL C0461 +; 3366: emit_codetag_10(tag_endif) + DB $66,$08 ; LLW 8 + DB $54,C0461 ; CALL C0461 +; 3367: fin +C1038: +; 3368: if token <> FIN_TKN + DB $68,D0495 ; LAB D0495 + DB $2A,$86 ; CB 134 + DB $42 ; ISNE + DB $4C,C1041 ; SKPFLS C1041 +; 3369: return parse_err_11(@no_fin) + DB $30 ; DROP + DB $26,D0882 ; LA D0882 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3370: fin +C1041: +C1042: +; 3371: is FOR_TKN + DB $50,C1027 ; SKIP C1027 +C1028: + DB $2A,$8E ; CB 142 + DB $3E,C1043 ; SKPNE C1043 +; 3372: stack_loop = stack_loop + 1 + DB $68,D1103 ; LAB D1103 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $78,D1103 ; SAB D1103 +; 3373: tag_for = ctag_new_01() + DB $54,C0445 ; CALL C0445 + DB $76,$10 ; SLW 16 +; 3374: tag_prevbrk = break_tag + DB $6A,D1107 ; LAW D1107 + DB $76,$04 ; SLW 4 +; 3375: break_tag = ctag_new_01() + DB $54,C0445 ; CALL C0445 + DB $7A,D1107 ; SAW D1107 +; 3376: if scan_01() <> ID_TKN + DB $54,C0629 ; CALL C0629 + DB $2A,$D6 ; CB 214 + DB $42 ; ISNE + DB $4C,C1044 ; SKPFLS C1044 +; 3377: return parse_err_11(@bad_stmnt) + DB $30 ; DROP + DB $26,D0642 ; LA D0642 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3378: fin +C1044: +C1045: +; 3379: idptr = id_lookup_21(tknptr, tknlen) + DB $6A,D0501 ; LAW D0501 + DB $68,D0496 ; LAB D0496 + DB $54,C0716 ; CALL C0716 + DB $76,$14 ; SLW 20 +; 3380: if idptr + DB $66,$14 ; LLW 20 + DB $4C,C1046 ; SKPFLS C1046 +; 3381: type = (idptr).idtype + DB $66,$14 ; LLW 20 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $60 ; LB + DB $74,$02 ; SLB 2 +; 3382: addr = (idptr):idval + DB $66,$14 ; LLW 20 + DB $62 ; LW + DB $76,$18 ; SLW 24 +; 3383: else + DB $50,C1047 ; SKIP C1047 +C1046: +; 3384: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 3385: fin +C1047: +; 3386: if scan_01() <> SET_TKN + DB $54,C0629 ; CALL C0629 + DB $2A,$BD ; CB 189 + DB $42 ; ISNE + DB $4C,C1048 ; SKPFLS C1048 +; 3387: return parse_err_11(@bad_stmnt) + DB $30 ; DROP + DB $26,D0642 ; LA D0642 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3388: fin +C1048: +C1049: +; 3389: if !parse_expr_01() + DB $54,C0001 ; CALL C0001 + DB $20 ; NOT + DB $4C,C1050 ; SKPFLS C1050 +; 3390: return parse_err_11(@bad_stmnt) + DB $30 ; DROP + DB $26,D0642 ; LA D0642 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3391: fin +C1050: +C1051: +; 3392: emit_codetag_10(tag_for) + DB $66,$10 ; LLW 16 + DB $54,C0461 ; CALL C0461 +; 3393: if type & LOCAL_TYPE + DB $64,$02 ; LLB 2 + DB $2A,$10 ; CB 16 + DB $14 ; BAND + DB $4C,C1052 ; SKPFLS C1052 +; 3394: if type & BYTE_TYPE + DB $64,$02 ; LLB 2 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C1054 ; SKPFLS C1054 +; 3395: emit_dlb_10(addr) + DB $66,$18 ; LLW 24 + DB $54,C0507 ; CALL C0507 +; 3396: else + DB $50,C1055 ; SKIP C1055 +C1054: +; 3397: emit_dlw_10(addr) + DB $66,$18 ; LLW 24 + DB $54,C0509 ; CALL C0509 +; 3398: fin +C1055: +; 3399: else + DB $50,C1053 ; SKIP C1053 +C1052: +; 3400: if type & BYTE_TYPE + DB $64,$02 ; LLB 2 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C1056 ; SKPFLS C1056 +; 3401: emit_dab_10(addr) + DB $66,$18 ; LLW 24 + DB $54,C0515 ; CALL C0515 +; 3402: else + DB $50,C1057 ; SKIP C1057 +C1056: +; 3403: emit_daw_10(addr) + DB $66,$18 ; LLW 24 + DB $54,C0517 ; CALL C0517 +; 3404: fin +C1057: +; 3405: fin +C1053: +; 3406: stepdir = 1 + DB $2A,$01 ; CB 1 + DB $76,$1A ; SLW 26 +; 3407: if token == TO_TKN + DB $68,D0495 ; LAB D0495 + DB $2A,$8F ; CB 143 + DB $40 ; ISEQ + DB $4C,C1058 ; SKPFLS C1058 +; 3408: drop parse_expr_01() + DB $54,C0001 ; CALL C0001 + DB $30 ; DROP +; 3409: elsif token == DOWNTO_TKN + DB $50,C1059 ; SKIP C1059 +C1058: + DB $68,D0495 ; LAB D0495 + DB $2A,$90 ; CB 144 + DB $40 ; ISEQ + DB $4C,C1060 ; SKPFLS C1060 +; 3410: drop parse_expr_01() + DB $54,C0001 ; CALL C0001 + DB $30 ; DROP +; 3411: stepdir = -1 + DB $2C,$FF,$FF ; CW -1 + DB $76,$1A ; SLW 26 +; 3412: fin +C1060: +C1059: +; 3413: if stepdir > 0 + DB $66,$1A ; LLW 26 + DB $00 ; ZERO + DB $44 ; ISGT + DB $4C,C1061 ; SKPFLS C1061 +; 3414: emit_brgt_10(break_tag) + DB $6A,D1107 ; LAW D1107 + DB $54,C0583 ; CALL C0583 +; 3415: else + DB $50,C1062 ; SKIP C1062 +C1061: +; 3416: emit_brlt_10(break_tag) + DB $6A,D1107 ; LAW D1107 + DB $54,C0585 ; CALL C0585 +; 3417: fin +C1062: +; 3418: if token == STEP_TKN + DB $68,D0495 ; LAB D0495 + DB $2A,$91 ; CB 145 + DB $40 ; ISEQ + DB $4C,C1063 ; SKPFLS C1063 +; 3419: drop parse_expr_01() + DB $54,C0001 ; CALL C0001 + DB $30 ; DROP +; 3420: if stepdir > 0 + DB $66,$1A ; LLW 26 + DB $00 ; ZERO + DB $44 ; ISGT + DB $4C,C1065 ; SKPFLS C1065 +; 3421: drop emit_binaryop_11(ADD_TKN) + DB $2A,$AB ; CB 171 + DB $54,C0548 ; CALL C0548 + DB $30 ; DROP +; 3422: else + DB $50,C1066 ; SKIP C1066 +C1065: +; 3423: drop emit_binaryop_11(SUB_TKN) + DB $2A,$AD ; CB 173 + DB $54,C0548 ; CALL C0548 + DB $30 ; DROP +; 3424: fin +C1066: +; 3425: else + DB $50,C1064 ; SKIP C1064 +C1063: +; 3426: if stepdir > 0 + DB $66,$1A ; LLW 26 + DB $00 ; ZERO + DB $44 ; ISGT + DB $4C,C1067 ; SKPFLS C1067 +; 3427: drop emit_unaryop_11(INC_TKN) + DB $2A,$C1 ; CB 193 + DB $54,C0537 ; CALL C0537 + DB $30 ; DROP +; 3428: else + DB $50,C1068 ; SKIP C1068 +C1067: +; 3429: drop emit_unaryop_11(DEC_TKN) + DB $2A,$C4 ; CB 196 + DB $54,C0537 ; CALL C0537 + DB $30 ; DROP +; 3430: fin +C1068: +; 3431: fin +C1064: +; 3432: while parse_stmnt_01() +C1069: + DB $54,C1023 ; CALL C1023 + DB $4C,C1070 ; SKPFLS C1070 +; 3433: drop nextln_01() + DB $54,C0682 ; CALL C0682 + DB $30 ; DROP +; 3434: loop + DB $50,C1069 ; SKIP C1069 +C1070: +; 3435: if token <> NEXT_TKN + DB $68,D0495 ; LAB D0495 + DB $2A,$92 ; CB 146 + DB $42 ; ISNE + DB $4C,C1071 ; SKPFLS C1071 +; 3436: return parse_err_11(@bad_stmnt) + DB $30 ; DROP + DB $26,D0642 ; LA D0642 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3437: fin +C1071: +C1072: +; 3438: emit_jump_10(tag_for) + DB $66,$10 ; LLW 16 + DB $54,C0589 ; CALL C0589 +; 3439: emit_codetag_10(break_tag) + DB $6A,D1107 ; LAW D1107 + DB $54,C0461 ; CALL C0461 +; 3440: emit_drop() + DB $54,C0591 ; CALL C0591 +; 3441: break_tag = tag_prevbrk + DB $66,$04 ; LLW 4 + DB $7A,D1107 ; SAW D1107 +; 3442: stack_loop = stack_loop - 1 + DB $68,D1103 ; LAB D1103 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $78,D1103 ; SAB D1103 +; 3443: is WHILE_TKN + DB $50,C1027 ; SKIP C1027 +C1043: + DB $2A,$88 ; CB 136 + DB $3E,C1073 ; SKPNE C1073 +; 3444: tag_while = ctag_new_01() + DB $54,C0445 ; CALL C0445 + DB $76,$0A ; SLW 10 +; 3445: tag_wend = ctag_new_01() + DB $54,C0445 ; CALL C0445 + DB $76,$0C ; SLW 12 +; 3446: tag_prevbrk = break_tag + DB $6A,D1107 ; LAW D1107 + DB $76,$04 ; SLW 4 +; 3447: break_tag = tag_wend + DB $66,$0C ; LLW 12 + DB $7A,D1107 ; SAW D1107 +; 3448: emit_codetag_10(tag_while) + DB $66,$0A ; LLW 10 + DB $54,C0461 ; CALL C0461 +; 3449: drop parse_expr_01() + DB $54,C0001 ; CALL C0001 + DB $30 ; DROP +; 3450: emit_brfls_10(tag_wend) + DB $66,$0C ; LLW 12 + DB $54,C0581 ; CALL C0581 +; 3451: while parse_stmnt_01() +C1074: + DB $54,C1023 ; CALL C1023 + DB $4C,C1075 ; SKPFLS C1075 +; 3452: drop nextln_01() + DB $54,C0682 ; CALL C0682 + DB $30 ; DROP +; 3453: loop + DB $50,C1074 ; SKIP C1074 +C1075: +; 3454: if token <> LOOP_TKN + DB $68,D0495 ; LAB D0495 + DB $2A,$89 ; CB 137 + DB $42 ; ISNE + DB $4C,C1076 ; SKPFLS C1076 +; 3455: return parse_err_11(@no_loop) + DB $30 ; DROP + DB $26,D0894 ; LA D0894 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3456: fin +C1076: +C1077: +; 3457: emit_jump_10(tag_while) + DB $66,$0A ; LLW 10 + DB $54,C0589 ; CALL C0589 +; 3458: emit_codetag_10(tag_wend) + DB $66,$0C ; LLW 12 + DB $54,C0461 ; CALL C0461 +; 3459: break_tag = tag_prevbrk + DB $66,$04 ; LLW 4 + DB $7A,D1107 ; SAW D1107 +; 3460: is REPEAT_TKN + DB $50,C1027 ; SKIP C1027 +C1073: + DB $2A,$93 ; CB 147 + DB $3E,C1078 ; SKPNE C1078 +; 3461: tag_repeat = ctag_new_01() + DB $54,C0445 ; CALL C0445 + DB $76,$0E ; SLW 14 +; 3462: tag_prevbrk = break_tag + DB $6A,D1107 ; LAW D1107 + DB $76,$04 ; SLW 4 +; 3463: break_tag = ctag_new_01() + DB $54,C0445 ; CALL C0445 + DB $7A,D1107 ; SAW D1107 +; 3464: emit_codetag_10(tag_repeat) + DB $66,$0E ; LLW 14 + DB $54,C0461 ; CALL C0461 +; 3465: drop scan_01() + DB $54,C0629 ; CALL C0629 + DB $30 ; DROP +; 3466: while parse_stmnt_01() +C1079: + DB $54,C1023 ; CALL C1023 + DB $4C,C1080 ; SKPFLS C1080 +; 3467: drop nextln_01() + DB $54,C0682 ; CALL C0682 + DB $30 ; DROP +; 3468: loop + DB $50,C1079 ; SKIP C1079 +C1080: +; 3469: if token <> UNTIL_TKN + DB $68,D0495 ; LAB D0495 + DB $2A,$94 ; CB 148 + DB $42 ; ISNE + DB $4C,C1081 ; SKPFLS C1081 +; 3470: return parse_err_11(@no_until) + DB $30 ; DROP + DB $26,D0907 ; LA D0907 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3471: fin +C1081: +C1082: +; 3472: drop parse_expr_01() + DB $54,C0001 ; CALL C0001 + DB $30 ; DROP +; 3473: emit_brfls_10(tag_repeat) + DB $66,$0E ; LLW 14 + DB $54,C0581 ; CALL C0581 +; 3474: emit_codetag_10(break_tag) + DB $6A,D1107 ; LAW D1107 + DB $54,C0461 ; CALL C0461 +; 3475: break_tag = tag_prevbrk + DB $66,$04 ; LLW 4 + DB $7A,D1107 ; SAW D1107 +; 3476: is CASE_TKN + DB $50,C1027 ; SKIP C1027 +C1078: + DB $2A,$8A ; CB 138 + DB $3E,C1083 ; SKPNE C1083 +; 3477: stack_loop = stack_loop + 1 + DB $68,D1103 ; LAB D1103 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $78,D1103 ; SAB D1103 +; 3478: tag_choice = ctag_new_01() + DB $54,C0445 ; CALL C0445 + DB $76,$12 ; SLW 18 +; 3479: tag_prevbrk = break_tag + DB $6A,D1107 ; LAW D1107 + DB $76,$04 ; SLW 4 +; 3480: break_tag = ctag_new_01() + DB $54,C0445 ; CALL C0445 + DB $7A,D1107 ; SAW D1107 +; 3481: drop parse_expr_01() + DB $54,C0001 ; CALL C0001 + DB $30 ; DROP +; 3482: drop nextln_01() + DB $54,C0682 ; CALL C0682 + DB $30 ; DROP +; 3483: while token <> ENDCASE_TKN +C1084: + DB $68,D0495 ; LAB D0495 + DB $2A,$8D ; CB 141 + DB $42 ; ISNE + DB $4C,C1085 ; SKPFLS C1085 +; 3484: when token + DB $68,D0495 ; LAB D0495 +; 3485: is OF_TKN + DB $2A,$8B ; CB 139 + DB $3E,C1087 ; SKPNE C1087 +; 3486: if !parse_expr_01() + DB $54,C0001 ; CALL C0001 + DB $20 ; NOT + DB $4C,C1088 ; SKPFLS C1088 +; 3487: return parse_err_11(@bad_stmnt) + DB $30 ; DROP + DB $30 ; DROP + DB $26,D0642 ; LA D0642 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3488: fin +C1088: +C1089: +; 3489: emit_brne_10(tag_choice) + DB $66,$12 ; LLW 18 + DB $54,C0587 ; CALL C0587 +; 3490: while parse_stmnt_01() +C1090: + DB $54,C1023 ; CALL C1023 + DB $4C,C1091 ; SKPFLS C1091 +; 3491: drop nextln_01() + DB $54,C0682 ; CALL C0682 + DB $30 ; DROP +; 3492: loop + DB $50,C1090 ; SKIP C1090 +C1091: +; 3493: emit_jump_10(break_tag) + DB $6A,D1107 ; LAW D1107 + DB $54,C0589 ; CALL C0589 +; 3494: emit_codetag_10(tag_choice) + DB $66,$12 ; LLW 18 + DB $54,C0461 ; CALL C0461 +; 3495: tag_choice = ctag_new_01() + DB $54,C0445 ; CALL C0445 + DB $76,$12 ; SLW 18 +; 3496: is DEFAULT_TKN + DB $50,C1086 ; SKIP C1086 +C1087: + DB $2A,$8C ; CB 140 + DB $3E,C1092 ; SKPNE C1092 +; 3497: drop scan_01() + DB $54,C0629 ; CALL C0629 + DB $30 ; DROP +; 3498: while parse_stmnt_01() +C1093: + DB $54,C1023 ; CALL C1023 + DB $4C,C1094 ; SKPFLS C1094 +; 3499: drop nextln_01() + DB $54,C0682 ; CALL C0682 + DB $30 ; DROP +; 3500: loop + DB $50,C1093 ; SKIP C1093 +C1094: +; 3501: if token <> ENDCASE_TKN + DB $68,D0495 ; LAB D0495 + DB $2A,$8D ; CB 141 + DB $42 ; ISNE + DB $4C,C1095 ; SKPFLS C1095 +; 3502: return parse_err_11(@bad_stmnt) + DB $30 ; DROP + DB $30 ; DROP + DB $26,D0642 ; LA D0642 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3503: fin +C1095: +C1096: +; 3504: otherwise + DB $50,C1086 ; SKIP C1086 +C1092: +; 3505: return parse_err_11(@bad_stmnt) + DB $30 ; DROP + DB $30 ; DROP + DB $26,D0642 ; LA D0642 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3506: wend +C1086: + DB $30 ; DROP +; 3507: loop + DB $50,C1084 ; SKIP C1084 +C1085: +; 3508: emit_codetag_10(break_tag) + DB $6A,D1107 ; LAW D1107 + DB $54,C0461 ; CALL C0461 +; 3509: emit_drop() + DB $54,C0591 ; CALL C0591 +; 3510: break_tag = tag_prevbrk + DB $66,$04 ; LLW 4 + DB $7A,D1107 ; SAW D1107 +; 3511: stack_loop = stack_loop - 1 + DB $68,D1103 ; LAB D1103 + DB $2A,$01 ; CB 1 + DB $04 ; SUB + DB $78,D1103 ; SAB D1103 +; 3512: is BREAK_TKN + DB $50,C1027 ; SKIP C1027 +C1083: + DB $2A,$9A ; CB 154 + DB $3E,C1098 ; SKPNE C1098 +; 3513: if break_tag + DB $6A,D1107 ; LAW D1107 + DB $4C,C1099 ; SKPFLS C1099 +; 3514: emit_jump_10(break_tag) + DB $6A,D1107 ; LAW D1107 + DB $54,C0589 ; CALL C0589 +; 3515: else + DB $50,C1100 ; SKIP C1100 +C1099: +; 3516: return parse_err_11(@bad_stmnt) + DB $30 ; DROP + DB $26,D0642 ; LA D0642 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3517: fin +C1100: +; 3518: is RETURN_TKN + DB $50,C1027 ; SKIP C1027 +C1098: + DB $2A,$99 ; CB 153 + DB $3E,C1101 ; SKPNE C1101 +; 3519: if infunc + DB $68,D1102 ; LAB D1102 + DB $4C,C1102 ; SKPFLS C1102 +; 3520: for i = 1 to stack_loop + DB $2A,$01 ; CB 1 +C1105: + DB $6C,$03 ; DLB 3 + DB $68,D1103 ; LAB D1103 + DB $3A,C1104 ; SKPGT C1104 + DB $0C ; INCR +; 3521: emit_drop() + DB $54,C0591 ; CALL C0591 +; 3522: next + DB $50,C1105 ; SKIP C1105 +C1104: + DB $30 ; DROP +; 3523: drop parse_expr_01() + DB $54,C0001 ; CALL C0001 + DB $30 ; DROP +; 3524: emit_leave_10(framesize) + DB $6A,D0484 ; LAW D0484 + DB $54,C0595 ; CALL C0595 +; 3525: else + DB $50,C1103 ; SKIP C1103 +C1102: +; 3526: return parse_err_11(@bad_stmnt) + DB $30 ; DROP + DB $26,D0642 ; LA D0642 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3527: fin +C1103: +; 3528: is EXIT_TKN + DB $50,C1027 ; SKIP C1027 +C1101: + DB $2A,$9C ; CB 156 + DB $3E,C1106 ; SKPNE C1106 +; 3529: drop parse_expr_01() + DB $54,C0001 ; CALL C0001 + DB $30 ; DROP +; 3530: emit_exit() + DB $54,C0605 ; CALL C0605 +; 3531: is DROP_TKN + DB $50,C1027 ; SKIP C1027 +C1106: + DB $2A,$97 ; CB 151 + DB $3E,C1107 ; SKPNE C1107 +; 3532: drop parse_expr_01() + DB $54,C0001 ; CALL C0001 + DB $30 ; DROP +; 3533: emit_drop() + DB $54,C0591 ; CALL C0591 +; 3534: is ELSE_TKN + DB $50,C1027 ; SKIP C1027 +C1107: + DB $2A,$85 ; CB 133 + DB $3E,C1108 ; SKPNE C1108 +; 3535: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 3536: is ELSEIF_TKN + DB $50,C1027 ; SKIP C1027 +C1108: + DB $2A,$84 ; CB 132 + DB $3E,C1109 ; SKPNE C1109 +; 3537: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 3538: is FIN_TKN + DB $50,C1027 ; SKIP C1027 +C1109: + DB $2A,$86 ; CB 134 + DB $3E,C1110 ; SKPNE C1110 +; 3539: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 3540: is LOOP_TKN + DB $50,C1027 ; SKIP C1027 +C1110: + DB $2A,$89 ; CB 137 + DB $3E,C1111 ; SKPNE C1111 +; 3541: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 3542: is UNTIL_TKN + DB $50,C1027 ; SKIP C1027 +C1111: + DB $2A,$94 ; CB 148 + DB $3E,C1112 ; SKPNE C1112 +; 3543: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 3544: is NEXT_TKN + DB $50,C1027 ; SKIP C1027 +C1112: + DB $2A,$92 ; CB 146 + DB $3E,C1113 ; SKPNE C1113 +; 3545: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 3546: is OF_TKN + DB $50,C1027 ; SKIP C1027 +C1113: + DB $2A,$8B ; CB 139 + DB $3E,C1114 ; SKPNE C1114 +; 3547: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 3548: is DEFAULT_TKN + DB $50,C1027 ; SKIP C1027 +C1114: + DB $2A,$8C ; CB 140 + DB $3E,C1115 ; SKPNE C1115 +; 3549: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 3550: is ENDCASE_TKN + DB $50,C1027 ; SKIP C1027 +C1115: + DB $2A,$8D ; CB 141 + DB $3E,C1116 ; SKPNE C1116 +; 3551: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 3552: is END_TKN + DB $50,C1027 ; SKIP C1027 +C1116: + DB $2A,$87 ; CB 135 + DB $3E,C1117 ; SKPNE C1117 +; 3553: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 3554: is DONE_TKN + DB $50,C1027 ; SKIP C1027 +C1117: + DB $2A,$98 ; CB 152 + DB $3E,C1118 ; SKPNE C1118 +; 3555: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 3556: is IFUNC_TKN + DB $50,C1027 ; SKIP C1027 +C1118: + DB $2A,$95 ; CB 149 + DB $3E,C1119 ; SKPNE C1119 +; 3557: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 3558: is NFUNC_TKN + DB $50,C1027 ; SKIP C1027 +C1119: + DB $2A,$96 ; CB 150 + DB $3E,C1120 ; SKPNE C1120 +; 3559: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 3560: is EOF_TKN + DB $50,C1027 ; SKIP C1027 +C1120: + DB $2A,$01 ; CB 1 + DB $3E,C1121 ; SKPNE C1121 +; 3561: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 3562: is EOL_TKN + DB $50,C1027 ; SKIP C1027 +C1121: + DB $2A,$02 ; CB 2 + DB $3E,C1122 ; SKPNE C1122 +; 3563: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5A ; LEAVE +; 3564: otherwise + DB $50,C1027 ; SKIP C1027 +C1122: +; 3565: if token == ID_TKN + DB $68,D0495 ; LAB D0495 + DB $2A,$D6 ; CB 214 + DB $40 ; ISEQ + DB $4C,C1124 ; SKPFLS C1124 +; 3566: saveptr = tknptr + DB $6A,D0501 ; LAW D0501 + DB $76,$16 ; SLW 22 +; 3567: idptr = id_lookup_21(tknptr, tknlen) + DB $6A,D0501 ; LAW D0501 + DB $68,D0496 ; LAB D0496 + DB $54,C0716 ; CALL C0716 + DB $76,$14 ; SLW 20 +; 3568: if !idptr + DB $66,$14 ; LLW 20 + DB $20 ; NOT + DB $4C,C1126 ; SKPFLS C1126 +; 3569: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 3570: fin +C1126: +C1127: +; 3571: type = (idptr).idtype + DB $66,$14 ; LLW 20 + DB $2A,$02 ; CB 2 + DB $02 ; ADD + DB $60 ; LB + DB $74,$02 ; SLB 2 +; 3572: if type & ADDR_TYPE + DB $64,$02 ; LLB 2 + DB $2A,$0E ; CB 14 + DB $14 ; BAND + DB $4C,C1128 ; SKPFLS C1128 +; 3573: addr = (idptr):idval + DB $66,$14 ; LLW 20 + DB $62 ; LW + DB $76,$18 ; SLW 24 +; 3574: if scan_01() == SET_TKN + DB $54,C0629 ; CALL C0629 + DB $2A,$BD ; CB 189 + DB $40 ; ISEQ + DB $4C,C1130 ; SKPFLS C1130 +; 3575: if type & VAR_TYPE + DB $64,$02 ; LLB 2 + DB $2A,$06 ; CB 6 + DB $14 ; BAND + DB $4C,C1132 ; SKPFLS C1132 +; 3576: drop parse_expr_01() + DB $54,C0001 ; CALL C0001 + DB $30 ; DROP +; 3577: if type & LOCAL_TYPE + DB $64,$02 ; LLB 2 + DB $2A,$10 ; CB 16 + DB $14 ; BAND + DB $4C,C1134 ; SKPFLS C1134 +; 3578: if type & BYTE_TYPE + DB $64,$02 ; LLB 2 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C1136 ; SKPFLS C1136 +; 3579: emit_slb_10(addr) + DB $66,$18 ; LLW 24 + DB $54,C0503 ; CALL C0503 +; 3580: else + DB $50,C1137 ; SKIP C1137 +C1136: +; 3581: emit_slw_10(addr) + DB $66,$18 ; LLW 24 + DB $54,C0505 ; CALL C0505 +; 3582: fin +C1137: +; 3583: else + DB $50,C1135 ; SKIP C1135 +C1134: +; 3584: if type & BYTE_TYPE + DB $64,$02 ; LLB 2 + DB $2A,$02 ; CB 2 + DB $14 ; BAND + DB $4C,C1138 ; SKPFLS C1138 +; 3585: emit_sab_10(addr) + DB $66,$18 ; LLW 24 + DB $54,C0511 ; CALL C0511 +; 3586: else + DB $50,C1139 ; SKIP C1139 +C1138: +; 3587: emit_saw_10(addr) + DB $66,$18 ; LLW 24 + DB $54,C0513 ; CALL C0513 +; 3588: fin +C1139: +; 3589: fin +C1135: +; 3590: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5A ; LEAVE +; 3591: fin +C1132: +C1133: +; 3592: elsif token == SETLIST_TKN and type & VAR_TYPE + DB $50,C1131 ; SKIP C1131 +C1130: + DB $68,D0495 ; LAB D0495 + DB $2A,$B9 ; CB 185 + DB $40 ; ISEQ + DB $64,$02 ; LLB 2 + DB $2A,$06 ; CB 6 + DB $14 ; BAND + DB $24 ; LAND + DB $4C,C1140 ; SKPFLS C1140 +; 3593: return parse_setlist_21(addr, type); + DB $30 ; DROP + DB $66,$18 ; LLW 24 + DB $64,$02 ; LLB 2 + DB $54,C0983 ; CALL C0983 + DB $5A ; LEAVE +; 3594: elsif token == EOL_TKN and type & FUNC_TYPE + DB $50,C1131 ; SKIP C1131 +C1140: + DB $68,D0495 ; LAB D0495 + DB $2A,$02 ; CB 2 + DB $40 ; ISEQ + DB $64,$02 ; LLB 2 + DB $2A,$08 ; CB 8 + DB $14 ; BAND + DB $24 ; LAND + DB $4C,C1141 ; SKPFLS C1141 +; 3595: emit_call_10(addr) + DB $66,$18 ; LLW 24 + DB $54,C0519 ; CALL C0519 +; 3596: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5A ; LEAVE +; 3597: fin +C1141: +C1131: +; 3598: fin +C1128: +C1129: +; 3599: tknptr = saveptr + DB $66,$16 ; LLW 22 + DB $7A,D0501 ; SAW D0501 +; 3600: fin +C1124: +C1125: +; 3601: rewind_10(tknptr) + DB $6A,D0501 ; LAW D0501 + DB $54,C0680 ; CALL C0680 +; 3602: type = parse_value_11(0) + DB $00 ; ZERO + DB $54,C0805 ; CALL C0805 + DB $74,$02 ; SLB 2 +; 3603: if type + DB $64,$02 ; LLB 2 + DB $4C,C1142 ; SKPFLS C1142 +; 3604: if token == SET_TKN + DB $68,D0495 ; LAB D0495 + DB $2A,$BD ; CB 189 + DB $40 ; ISEQ + DB $4C,C1144 ; SKPFLS C1144 +; 3605: drop parse_expr_01() + DB $54,C0001 ; CALL C0001 + DB $30 ; DROP +; 3606: if type & XBYTE_TYPE + DB $64,$02 ; LLB 2 + DB $2A,$22 ; CB 34 + DB $14 ; BAND + DB $4C,C1146 ; SKPFLS C1146 +; 3607: emit_sb() + DB $54,C0499 ; CALL C0499 +; 3608: else + DB $50,C1147 ; SKIP C1147 +C1146: +; 3609: emit_sw() + DB $54,C0501 ; CALL C0501 +; 3610: fin +C1147: +; 3611: elsif token == SETLIST_TKN + DB $50,C1145 ; SKIP C1145 +C1144: + DB $68,D0495 ; LAB D0495 + DB $2A,$B9 ; CB 185 + DB $40 ; ISEQ + DB $4C,C1148 ; SKPFLS C1148 +; 3612: return parse_setlist_21(0, type); + DB $30 ; DROP + DB $00 ; ZERO + DB $64,$02 ; LLB 2 + DB $54,C0983 ; CALL C0983 + DB $5A ; LEAVE +; 3613: else + DB $50,C1145 ; SKIP C1145 +C1148: +; 3614: if type & BPTR_TYPE + DB $64,$02 ; LLB 2 + DB $2A,$20 ; CB 32 + DB $14 ; BAND + DB $4C,C1149 ; SKPFLS C1149 +; 3615: emit_lb() + DB $54,C0487 ; CALL C0487 +; 3616: elsif type & WPTR_TYPE + DB $50,C1150 ; SKIP C1150 +C1149: + DB $64,$02 ; LLB 2 + DB $2A,$40 ; CB 64 + DB $14 ; BAND + DB $4C,C1151 ; SKPFLS C1151 +; 3617: emit_lw() + DB $54,C0489 ; CALL C0489 +; 3618: fin +C1151: +C1150: +; 3619: fin +C1145: +; 3620: else + DB $50,C1143 ; SKIP C1143 +C1142: +; 3621: return parse_err_11(@bad_syntax) + DB $30 ; DROP + DB $26,D0670 ; LA D0670 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3622: fin +C1143: +; 3623: wend +C1027: + DB $30 ; DROP +; 3624: if scan_01() <> EOL_TKN + DB $54,C0629 ; CALL C0629 + DB $2A,$02 ; CB 2 + DB $42 ; ISNE + DB $4C,C1152 ; SKPFLS C1152 +; 3625: return parse_err_11(@bad_syntax) + DB $26,D0670 ; LA D0670 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3626: fin +C1152: +C1153: +; 3627: return TRUE + DB $2C,$FF,$FF ; CW -1 + DB $5A ; LEAVE +; 3628: end +; 3629: def parse_var_11(type) +C1154: ; parse_var_11() + ; type = 2 +; 3630: byte consttype, constsize, idlen + ; consttype = 4 + ; constsize = 5 + ; idlen = 6 +; 3631: word idptr, constval, arraysize, size + ; idptr = 7 + ; constval = 9 + ; arraysize = 11 + ; size = 13 +; 3632: +; 3633: idlen = 0 + JSR INTERP + DB $58,$0F,$01 ; ENTER 15,1 + DB $00 ; ZERO + DB $74,$06 ; SLB 6 +; 3634: size = 1 + DB $2A,$01 ; CB 1 + DB $76,$0D ; SLW 13 +; 3635: if scan_01() == ID_TKN + DB $54,C0629 ; CALL C0629 + DB $2A,$D6 ; CB 214 + DB $40 ; ISEQ + DB $4C,C1156 ; SKPFLS C1156 +; 3636: idptr = tknptr + DB $6A,D0501 ; LAW D0501 + DB $76,$07 ; SLW 7 +; 3637: idlen = tknlen + DB $68,D0496 ; LAB D0496 + DB $74,$06 ; SLB 6 +; 3638: if scan_01() == OPEN_BRACKET_TKN + DB $54,C0629 ; CALL C0629 + DB $2A,$DB ; CB 219 + DB $40 ; ISEQ + DB $4C,C1158 ; SKPFLS C1158 +; 3639: size = 0 + DB $00 ; ZERO + DB $76,$0D ; SLW 13 +; 3640: drop parse_constexpr_21(@size, @constsize) + DB $28,$0D ; LLA 13 + DB $28,$05 ; LLA 5 + DB $54,C0932 ; CALL C0932 + DB $30 ; DROP +; 3641: if token <> CLOSE_BRACKET_TKN + DB $68,D0495 ; LAB D0495 + DB $2A,$DD ; CB 221 + DB $42 ; ISNE + DB $4C,C1160 ; SKPFLS C1160 +; 3642: return parse_err_11(@no_close_bracket) + DB $26,D0842 ; LA D0842 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3643: fin +C1160: +C1161: +; 3644: drop scan_01() + DB $54,C0629 ; CALL C0629 + DB $30 ; DROP +; 3645: fin +C1158: +C1159: +; 3646: fin +C1156: +C1157: +; 3647: if type == WORD_TYPE + DB $66,$02 ; LLW 2 + DB $2A,$04 ; CB 4 + DB $40 ; ISEQ + DB $4C,C1162 ; SKPFLS C1162 +; 3648: size = size * 2 + DB $66,$0D ; LLW 13 + DB $2A,$02 ; CB 2 + DB $06 ; MUL + DB $76,$0D ; SLW 13 +; 3649: fin +C1162: +C1163: +; 3650: if token == SET_TKN + DB $68,D0495 ; LAB D0495 + DB $2A,$BD ; CB 189 + DB $40 ; ISEQ + DB $4C,C1164 ; SKPFLS C1164 +; 3651: if infunc + DB $68,D1102 ; LAB D1102 + DB $4C,C1166 ; SKPFLS C1166 +; 3652: return parse_err_11(@no_local_init) + DB $26,D0934 ; LA D0934 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3653: fin +C1166: +C1167: +; 3654: if idlen + DB $64,$06 ; LLB 6 + DB $4C,C1168 ; SKPFLS C1168 +; 3655: drop iddata_add_41(idptr, idlen, type, 0) + DB $66,$07 ; LLW 7 + DB $64,$06 ; LLB 6 + DB $66,$02 ; LLW 2 + DB $00 ; ZERO + DB $54,C0732 ; CALL C0732 + DB $30 ; DROP +; 3656: fin +C1168: +C1169: +; 3657: consttype = parse_constexpr_21(@constval, @constsize) + DB $28,$09 ; LLA 9 + DB $28,$05 ; LLA 5 + DB $54,C0932 ; CALL C0932 + DB $74,$04 ; SLB 4 +; 3658: if consttype + DB $64,$04 ; LLB 4 + DB $4C,C1170 ; SKPFLS C1170 +; 3659: arraysize = emit_data_41(type, consttype, constval, constsize) + DB $66,$02 ; LLW 2 + DB $64,$04 ; LLB 4 + DB $66,$09 ; LLW 9 + DB $64,$05 ; LLB 5 + DB $54,C0473 ; CALL C0473 + DB $76,$0B ; SLW 11 +; 3660: while token == COMMA_TKN +C1172: + DB $68,D0495 ; LAB D0495 + DB $2A,$AC ; CB 172 + DB $40 ; ISEQ + DB $4C,C1173 ; SKPFLS C1173 +; 3661: consttype = parse_constexpr_21(@constval, @constsize) + DB $28,$09 ; LLA 9 + DB $28,$05 ; LLA 5 + DB $54,C0932 ; CALL C0932 + DB $74,$04 ; SLB 4 +; 3662: if consttype + DB $64,$04 ; LLB 4 + DB $4C,C1174 ; SKPFLS C1174 +; 3663: arraysize = arraysize + emit_data_41(type, consttype, constval, constsize) + DB $66,$0B ; LLW 11 + DB $66,$02 ; LLW 2 + DB $64,$04 ; LLB 4 + DB $66,$09 ; LLW 9 + DB $64,$05 ; LLB 5 + DB $54,C0473 ; CALL C0473 + DB $02 ; ADD + DB $76,$0B ; SLW 11 +; 3664: else + DB $50,C1175 ; SKIP C1175 +C1174: +; 3665: return parse_err_11(@bad_decl) + DB $26,D0612 ; LA D0612 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3666: fin +C1175: +; 3667: loop + DB $50,C1172 ; SKIP C1172 +C1173: +; 3668: if token <> EOL_TKN + DB $68,D0495 ; LAB D0495 + DB $2A,$02 ; CB 2 + DB $42 ; ISNE + DB $4C,C1176 ; SKPFLS C1176 +; 3669: return parse_err_11(@no_close_bracket) + DB $26,D0842 ; LA D0842 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3670: fin +C1176: +C1177: +; 3671: iddata_size_30(PTR_TYPE, size, arraysize); + DB $2A,$60 ; CB 96 + DB $66,$0D ; LLW 13 + DB $66,$0B ; LLW 11 + DB $54,C0738 ; CALL C0738 +; 3672: else + DB $50,C1171 ; SKIP C1171 +C1170: +; 3673: return parse_err_11(@bad_decl) + DB $26,D0612 ; LA D0612 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3674: fin +C1171: +; 3675: elsif idlen + DB $50,C1165 ; SKIP C1165 +C1164: + DB $64,$06 ; LLB 6 + DB $4C,C1178 ; SKPFLS C1178 +; 3676: if infunc + DB $68,D1102 ; LAB D1102 + DB $4C,C1179 ; SKPFLS C1179 +; 3677: drop idlocal_add_41(idptr, idlen, type, size) + DB $66,$07 ; LLW 7 + DB $64,$06 ; LLB 6 + DB $66,$02 ; LLW 2 + DB $66,$0D ; LLW 13 + DB $54,C0724 ; CALL C0724 + DB $30 ; DROP +; 3678: else + DB $50,C1180 ; SKIP C1180 +C1179: +; 3679: drop iddata_add_41(idptr, idlen, type, size) + DB $66,$07 ; LLW 7 + DB $64,$06 ; LLB 6 + DB $66,$02 ; LLW 2 + DB $66,$0D ; LLW 13 + DB $54,C0732 ; CALL C0732 + DB $30 ; DROP +; 3680: fin +C1180: +; 3681: fin +C1178: +C1165: +; 3682: return TRUE + DB $2C,$FF,$FF ; CW -1 + DB $5A ; LEAVE +; 3683: end +; 3684: def parse_vars_01 +C1181: ; parse_vars_01() +; 3685: byte idlen, type, size + ; idlen = 2 + ; type = 3 + ; size = 4 +; 3686: word value, idptr + ; value = 5 + ; idptr = 7 +; 3687: +; 3688: when token + JSR INTERP + DB $58,$09,$00 ; ENTER 9,0 + DB $68,D0495 ; LAB D0495 +; 3689: is CONST_TKN + DB $2A,$80 ; CB 128 + DB $3E,C1184 ; SKPNE C1184 +; 3690: if scan_01() <> ID_TKN + DB $54,C0629 ; CALL C0629 + DB $2A,$D6 ; CB 214 + DB $42 ; ISNE + DB $4C,C1185 ; SKPFLS C1185 +; 3691: return parse_err_11(@bad_cnst) + DB $30 ; DROP + DB $26,D0581 ; LA D0581 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3692: fin +C1185: +C1186: +; 3693: idptr = tknptr; + DB $6A,D0501 ; LAW D0501 + DB $76,$07 ; SLW 7 +; 3694: idlen = tknlen + DB $68,D0496 ; LAB D0496 + DB $74,$02 ; SLB 2 +; 3695: if scan_01() <> SET_TKN + DB $54,C0629 ; CALL C0629 + DB $2A,$BD ; CB 189 + DB $42 ; ISNE + DB $4C,C1187 ; SKPFLS C1187 +; 3696: return parse_err_11(@bad_cnst) + DB $30 ; DROP + DB $26,D0581 ; LA D0581 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3697: fin +C1187: +C1188: +; 3698: if !parse_constexpr_21(@value, @size) + DB $28,$05 ; LLA 5 + DB $28,$04 ; LLA 4 + DB $54,C0932 ; CALL C0932 + DB $20 ; NOT + DB $4C,C1189 ; SKPFLS C1189 +; 3699: return parse_err_11(@bad_cnst) + DB $30 ; DROP + DB $26,D0581 ; LA D0581 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3700: fin +C1189: +C1190: +; 3701: drop idconst_add_31(idptr, idlen, value) + DB $66,$07 ; LLW 7 + DB $64,$02 ; LLB 2 + DB $66,$05 ; LLW 5 + DB $54,C0750 ; CALL C0750 + DB $30 ; DROP +; 3702: is BYTE_TKN + DB $50,C1183 ; SKIP C1183 +C1184: + DB $2A,$81 ; CB 129 + DB $3E,C1191 ; SKPNE C1191 +; 3703: type = BYTE_TYPE + DB $2A,$02 ; CB 2 + DB $74,$03 ; SLB 3 +; 3704: repeat +C1193: +; 3705: if !parse_var_11(type) + DB $64,$03 ; LLB 3 + DB $54,C1154 ; CALL C1154 + DB $20 ; NOT + DB $4C,C1194 ; SKPFLS C1194 +; 3706: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 3707: fin +C1194: +C1195: +; 3708: until token <> COMMA_TKN + DB $68,D0495 ; LAB D0495 + DB $2A,$AC ; CB 172 + DB $42 ; ISNE + DB $4C,C1193 ; SKPFLS C1193 +C1192: +; 3709: is WORD_TKN + DB $50,C1183 ; SKIP C1183 +C1191: + DB $2A,$82 ; CB 130 + DB $3E,C1196 ; SKPNE C1196 +; 3710: type = WORD_TYPE + DB $2A,$04 ; CB 4 + DB $74,$03 ; SLB 3 +; 3711: repeat +C1198: +; 3712: if !parse_var_11(type) + DB $64,$03 ; LLB 3 + DB $54,C1154 ; CALL C1154 + DB $20 ; NOT + DB $4C,C1199 ; SKPFLS C1199 +; 3713: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 3714: fin +C1199: +C1200: +; 3715: until token <> COMMA_TKN + DB $68,D0495 ; LAB D0495 + DB $2A,$AC ; CB 172 + DB $42 ; ISNE + DB $4C,C1198 ; SKPFLS C1198 +C1197: +; 3716: is FUNC_TKN + DB $50,C1183 ; SKIP C1183 +C1196: + DB $2A,$9E ; CB 158 + DB $3E,C1201 ; SKPNE C1201 +; 3717: repeat +C1203: +; 3718: if scan_01() == ID_TKN + DB $54,C0629 ; CALL C0629 + DB $2A,$D6 ; CB 214 + DB $40 ; ISEQ + DB $4C,C1204 ; SKPFLS C1204 +; 3719: drop idfunc_add_31(tknptr, tknlen, ctag_new_01()) + DB $6A,D0501 ; LAW D0501 + DB $68,D0496 ; LAB D0496 + DB $54,C0445 ; CALL C0445 + DB $54,C0748 ; CALL C0748 + DB $30 ; DROP +; 3720: else + DB $50,C1205 ; SKIP C1205 +C1204: +; 3721: return parse_err_11(@bad_decl) + DB $30 ; DROP + DB $26,D0612 ; LA D0612 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3722: fin +C1205: +; 3723: until scan_01() <> COMMA_TKN + DB $54,C0629 ; CALL C0629 + DB $2A,$AC ; CB 172 + DB $42 ; ISNE + DB $4C,C1203 ; SKPFLS C1203 +C1202: +; 3724: is EOL_TKN + DB $50,C1183 ; SKIP C1183 +C1201: + DB $2A,$02 ; CB 2 + DB $3E,C1206 ; SKPNE C1206 +; 3725: return TRUE + DB $30 ; DROP + DB $2C,$FF,$FF ; CW -1 + DB $5A ; LEAVE +; 3726: otherwise + DB $50,C1183 ; SKIP C1183 +C1206: +; 3727: return FALSE + DB $30 ; DROP + DB $00 ; ZERO + DB $5A ; LEAVE +; 3728: wend +C1183: + DB $30 ; DROP +; 3729: return TRUE + DB $2C,$FF,$FF ; CW -1 + DB $5A ; LEAVE +; 3730: end +; 3731: def parse_func_01 +C1208: ; parse_func_01() +; 3732: byte opt, cfnparms + ; opt = 2 + ; cfnparms = 3 +; 3733: word func_tag, idptr + ; func_tag = 4 + ; idptr = 6 +; 3734: +; 3735: if token == IFUNC_TKN or token == NFUNC_TKN + JSR INTERP + DB $58,$08,$00 ; ENTER 8,0 + DB $68,D0495 ; LAB D0495 + DB $2A,$95 ; CB 149 + DB $40 ; ISEQ + DB $68,D0495 ; LAB D0495 + DB $2A,$96 ; CB 150 + DB $40 ; ISEQ + DB $22 ; LOR + DB $4C,C1210 ; SKPFLS C1210 +; 3736: opt = token - IFUNC_TKN + DB $68,D0495 ; LAB D0495 + DB $2A,$95 ; CB 149 + DB $04 ; SUB + DB $74,$02 ; SLB 2 +; 3737: if scan_01() <> ID_TKN + DB $54,C0629 ; CALL C0629 + DB $2A,$D6 ; CB 214 + DB $42 ; ISNE + DB $4C,C1212 ; SKPFLS C1212 +; 3738: return parse_err_11(@bad_decl) + DB $26,D0612 ; LA D0612 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3739: fin +C1212: +C1213: +; 3740: cfnparms = 0 + DB $00 ; ZERO + DB $74,$03 ; SLB 3 +; 3741: infunc = TRUE + DB $2C,$FF,$FF ; CW -1 + DB $78,D1102 ; SAB D1102 +; 3742: idptr = idglobal_lookup_21(tknptr, tknlen) + DB $6A,D0501 ; LAW D0501 + DB $68,D0496 ; LAB D0496 + DB $54,C0722 ; CALL C0722 + DB $76,$06 ; SLW 6 +; 3743: if idptr + DB $66,$06 ; LLW 6 + DB $4C,C1214 ; SKPFLS C1214 +; 3744: func_tag = (idptr):idval + DB $66,$06 ; LLW 6 + DB $62 ; LW + DB $76,$04 ; SLW 4 +; 3745: else + DB $50,C1215 ; SKIP C1215 +C1214: +; 3746: func_tag = ctag_new_01() + DB $54,C0445 ; CALL C0445 + DB $76,$04 ; SLW 4 +; 3747: drop idfunc_add_31(tknptr, tknlen, func_tag) + DB $6A,D0501 ; LAW D0501 + DB $68,D0496 ; LAB D0496 + DB $66,$04 ; LLW 4 + DB $54,C0748 ; CALL C0748 + DB $30 ; DROP +; 3748: fin +C1215: +; 3749: emit_codetag_10(func_tag) + DB $66,$04 ; LLW 4 + DB $54,C0461 ; CALL C0461 +; 3750: retfunc_tag = ctag_new_01() + DB $54,C0445 ; CALL C0445 + DB $7A,D1105 ; SAW D1105 +; 3751: idlocal_init() + DB $54,C0754 ; CALL C0754 +; 3752: if scan_01() == OPEN_PAREN_TKN + DB $54,C0629 ; CALL C0629 + DB $2A,$A8 ; CB 168 + DB $40 ; ISEQ + DB $4C,C1216 ; SKPFLS C1216 +; 3753: repeat +C1219: +; 3754: if scan_01() == ID_TKN + DB $54,C0629 ; CALL C0629 + DB $2A,$D6 ; CB 214 + DB $40 ; ISEQ + DB $4C,C1220 ; SKPFLS C1220 +; 3755: cfnparms = cfnparms + 1 + DB $64,$03 ; LLB 3 + DB $2A,$01 ; CB 1 + DB $02 ; ADD + DB $74,$03 ; SLB 3 +; 3756: drop idlocal_add_41(tknptr, tknlen, WORD_TYPE, 2) + DB $6A,D0501 ; LAW D0501 + DB $68,D0496 ; LAB D0496 + DB $2A,$04 ; CB 4 + DB $2A,$02 ; CB 2 + DB $54,C0724 ; CALL C0724 + DB $30 ; DROP +; 3757: drop scan_01() + DB $54,C0629 ; CALL C0629 + DB $30 ; DROP +; 3758: fin +C1220: +C1221: +; 3759: until token <> COMMA_TKN + DB $68,D0495 ; LAB D0495 + DB $2A,$AC ; CB 172 + DB $42 ; ISNE + DB $4C,C1219 ; SKPFLS C1219 +C1218: +; 3760: if token <> CLOSE_PAREN_TKN + DB $68,D0495 ; LAB D0495 + DB $2A,$A9 ; CB 169 + DB $42 ; ISNE + DB $4C,C1222 ; SKPFLS C1222 +; 3761: return parse_err_11(@bad_decl) + DB $26,D0612 ; LA D0612 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3762: fin +C1222: +C1223: +; 3763: drop scan_01() + DB $54,C0629 ; CALL C0629 + DB $30 ; DROP +; 3764: fin +C1216: +C1217: +; 3765: while parse_vars_01() +C1224: + DB $54,C1181 ; CALL C1181 + DB $4C,C1225 ; SKPFLS C1225 +; 3766: drop nextln_01() + DB $54,C0682 ; CALL C0682 + DB $30 ; DROP +; 3767: loop + DB $50,C1224 ; SKIP C1224 +C1225: +; 3768: emit_enter_20(framesize, cfnparms) + DB $6A,D0484 ; LAW D0484 + DB $64,$03 ; LLB 3 + DB $54,C0599 ; CALL C0599 +; 3769: prevstmnt = 0 + DB $00 ; ZERO + DB $78,D1104 ; SAB D1104 +; 3770: while parse_stmnt_01() +C1226: + DB $54,C1023 ; CALL C1023 + DB $4C,C1227 ; SKPFLS C1227 +; 3771: drop nextln_01() + DB $54,C0682 ; CALL C0682 + DB $30 ; DROP +; 3772: loop + DB $50,C1226 ; SKIP C1226 +C1227: +; 3773: infunc = FALSE + DB $00 ; ZERO + DB $78,D1102 ; SAB D1102 +; 3774: if token <> END_TKN + DB $68,D0495 ; LAB D0495 + DB $2A,$87 ; CB 135 + DB $42 ; ISNE + DB $4C,C1228 ; SKPFLS C1228 +; 3775: return parse_err_11(@bad_syntax) + DB $26,D0670 ; LA D0670 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3776: fin +C1228: +C1229: +; 3777: if scan_01() <> EOL_TKN + DB $54,C0629 ; CALL C0629 + DB $2A,$02 ; CB 2 + DB $42 ; ISNE + DB $4C,C1230 ; SKPFLS C1230 +; 3778: return parse_err_11(@bad_syntax) + DB $26,D0670 ; LA D0670 + DB $54,C0441 ; CALL C0441 + DB $5A ; LEAVE +; 3779: fin +C1230: +C1231: +; 3780: if prevstmnt <> RETURN_TKN + DB $68,D1104 ; LAB D1104 + DB $2A,$99 ; CB 153 + DB $42 ; ISNE + DB $4C,C1232 ; SKPFLS C1232 +; 3781: emit_leave_10(framesize) + DB $6A,D0484 ; LAW D0484 + DB $54,C0595 ; CALL C0595 +; 3782: fin +C1232: +C1233: +; 3783: return TRUE + DB $2C,$FF,$FF ; CW -1 + DB $5A ; LEAVE +; 3784: elsif token == EOL_TKN + DB $50,C1211 ; SKIP C1211 +C1210: + DB $68,D0495 ; LAB D0495 + DB $2A,$02 ; CB 2 + DB $40 ; ISEQ + DB $4C,C1234 ; SKPFLS C1234 +; 3785: return TRUE + DB $2C,$FF,$FF ; CW -1 + DB $5A ; LEAVE +; 3786: fin +C1234: +C1211: +; 3787: return FALSE + DB $00 ; ZERO + DB $5A ; LEAVE +; 3788: end +; 3789: def parse_module_01 +C0002: ; parse_module_01() +; 3790: entrypoint = 0 + JSR INTERP + DB $00 ; ZERO + DB $7A,D0492 ; SAW D0492 +; 3791: idglobal_init() + DB $54,C0752 ; CALL C0752 +; 3792: idlocal_init() + DB $54,C0754 ; CALL C0754 +; 3793: if nextln_01() + DB $54,C0682 ; CALL C0682 + DB $4C,C1236 ; SKPFLS C1236 +; 3794: while parse_vars_01() +C1238: + DB $54,C1181 ; CALL C1181 + DB $4C,C1239 ; SKPFLS C1239 +; 3795: drop nextln_01() + DB $54,C0682 ; CALL C0682 + DB $30 ; DROP +; 3796: loop + DB $50,C1238 ; SKIP C1238 +C1239: +; 3797: while parse_func_01() +C1240: + DB $54,C1208 ; CALL C1208 + DB $4C,C1241 ; SKPFLS C1241 +; 3798: drop nextln_01() + DB $54,C0682 ; CALL C0682 + DB $30 ; DROP +; 3799: loop + DB $50,C1240 ; SKIP C1240 +C1241: +; 3800: if token <> DONE_TKN + DB $68,D0495 ; LAB D0495 + DB $2A,$98 ; CB 152 + DB $42 ; ISNE + DB $4C,C1242 ; SKPFLS C1242 +; 3801: emit_start() + DB $54,C0603 ; CALL C0603 +; 3802: prevstmnt = 0 + DB $00 ; ZERO + DB $78,D1104 ; SAB D1104 +; 3803: while parse_stmnt_01() +C1244: + DB $54,C1023 ; CALL C1023 + DB $4C,C1245 ; SKPFLS C1245 +; 3804: drop nextln_01() + DB $54,C0682 ; CALL C0682 + DB $30 ; DROP +; 3805: loop + DB $50,C1244 ; SKIP C1244 +C1245: +; 3806: if token <> DONE_TKN + DB $68,D0495 ; LAB D0495 + DB $2A,$98 ; CB 152 + DB $42 ; ISNE + DB $4C,C1246 ; SKPFLS C1246 +; 3807: drop parse_err_11(@no_done) + DB $26,D0921 ; LA D0921 + DB $54,C0441 ; CALL C0441 + DB $30 ; DROP +; 3808: fin +C1246: +C1247: +; 3809: if prevstmnt <> EXIT_TKN + DB $68,D1104 ; LAB D1104 + DB $2A,$9C ; CB 156 + DB $42 ; ISNE + DB $4C,C1248 ; SKPFLS C1248 +; 3810: emit_const_10(0) + DB $00 ; ZERO + DB $54,C0482 ; CALL C0482 +; 3811: emit_exit() + DB $54,C0605 ; CALL C0605 +; 3812: fin +C1248: +C1249: +; 3813: fin +C1242: +C1243: +; 3814: ; dumpsym(idglobal_tbl, globals) +; 3815: ; prstr(@entrypt_str) +; 3816: ; prword(entrypoint) +; 3817: ; crout() +; 3818: ; keyin_01() +; 3819: return TRUE + DB $2C,$FF,$FF ; CW -1 + DB $5C ; RET +; 3820: fin +C1236: +C1237: +; 3821: return FALSE + DB $00 ; ZERO + DB $5C ; RET +; 3822: end +; 3823: ; +; 3824: ; Init editor +; 3825: ; +; 3826: if !(^machid & $80) +START: ; JSR INTERP + DB $2C,$98,$BF ; CW 49048 + DB $60 ; LB + DB $2A,$80 ; CB 128 + DB $14 ; BAND + DB $20 ; NOT + DB $4C,C1250 ; SKPFLS C1250 +; 3827: flags = uppercase ? shiftlock + DB $2A,$08 ; CB 8 + DB $2A,$80 ; CB 128 + DB $16 ; IOR + DB $78,D0192 ; SAB D0192 +; 3828: keyin_01 = @keyin2_01 + DB $26,C0240 ; LA C0240 + DB $7A,D0210 ; SAW D0210 +; 3829: else + DB $50,C1251 ; SKIP C1251 +C1250: +; 3830: keyin_01 = @keyin2e_01 + DB $26,C0236 ; LA C0236 + DB $7A,D0210 ; SAW D0210 +; 3831: fin +C1251: +; 3832: inittxtbuf() + DB $54,C0085 ; CALL C0085 +; 3833: if ^argbuff + DB $2C,$06,$20 ; CW 8198 + DB $60 ; LB + DB $4C,C1252 ; SKPFLS C1252 +; 3834: strcpy_20(argbuff, @txtfile) + DB $2C,$06,$20 ; CW 8198 + DB $26,D0141 ; LA D0141 + DB $54,C0047 ; CALL C0047 +; 3835: prstr(@txtfile) + DB $26,D0141 ; LA D0141 + DB $54,C0019 ; CALL C0019 +; 3836: readtxt_10(@txtfile) + DB $26,D0141 ; LA D0141 + DB $54,C0135 ; CALL C0135 +; 3837: else + DB $50,C1253 ; SKIP C1253 +C1252: +; 3838: numlines = 1 + DB $2A,$01 ; CB 1 + DB $7A,D0206 ; SAW D0206 +; 3839: fin +C1253: +; 3840: curschr = '+' + DB $2A,$2B ; CB 43 + DB $78,D0199 ; SAB D0199 +; 3841: flags = flags ? insmode + DB $68,D0192 ; LAB D0192 + DB $2A,$02 ; CB 2 + DB $16 ; IOR + DB $78,D0192 ; SAB D0192 +; 3842: drawscrn_20(scrntop, scrnleft) + DB $6A,D0202 ; LAW D0202 + DB $68,D0196 ; LAB D0196 + DB $54,C0165 ; CALL C0165 +; 3843: curson() + DB $54,C0177 ; CALL C0177 +; 3844: editmode() + DB $54,C0332 ; CALL C0332 +; 3845: done + DB $5C ; RET diff --git a/plasma2/plink.pla b/plasma2/plink.pla new file mode 100755 index 0000000..fa0be11 --- /dev/null +++ b/plasma2/plink.pla @@ -0,0 +1,832 @@ +CONST FALSE = 0 +CONST TRUE = NOT FALSE +CONST OK = 0 +CONST ERROR = -1 +CONST INPUTSTR = $01FF +CONST INBUFF = $0800 +CONST OUTBUFF = $0C00 +CONST SYMTABLE = $1000 +CONST SYMSIZE = $1000 +CONST MODFILES = $7F00 +CONST DATABUFF = $8000 +WORD NEXTENTRY = SYMTABLE +BYTE PLASMASTR[] = "PLASMA LINKER 0.8" +BYTE NULLSTR[] = "" +BYTE BADMODSTR[] = "MODULE NOT FOUND" +BYTE ASMADR[] = "ASM ADDRESS: $" +BYTE LOADADR[] = "LOAD ADDRESS: $" +BYTE DATASZ[] = "DATA SIZE: $" +BYTE RELOFSTSTR[] = "REL OFFSET: $" +BYTE FIX16STR[] = "FIXUP 16-BIT ADDRESS: $" +BYTE FIX8STR[] = "FIXUP 8-BIT ADDRESS: $" +BYTE RLDLBL[] = "RELOCATION DIRECTORY:" +BYTE ESDLBL[] = "SYMBOL TABLE:" +BYTE MATCHEXTRNSTR = "MATCH EXTRN: " +BYTE INPUTFILESTR = "INPUT FILE" +BYTE OUTPUTFILESTR = "OUTPUT FILE" +BYTE BADEXT[] = "UNRESOLVED EXTERNAL SYMBOL: " +BYTE DUPSYMERR[] = "DUPLICATE EXTERNAL SYMBOL: " +BYTE ERROUTSTR = "ERROR CREATING OUTPUT FILE" +BYTE PRESSANYKEY[] = "PRESS ANY KEY TO CONTINUE..." +BYTE BINFILESTR[80] +BYTE MODCOUNT, MODI +BYTE BINREF, BINTYPE +WORD MODFILE,MODBUFF,MODLEN,MODADDR,LINKADDR +BYTE PERR +; +; Defines for ASM routines +; +ASM EQUATES + TMP EQU $F0 + TMPL EQU TMP + TMPH EQU TMP+1 + SRC EQU TMP + SRCL EQU SRC + SRCH EQU SRC+1 + DST EQU SRC+2 + DSTL EQU DST + DSTH EQU DST+1 + ESP EQU DST+2 +JMPTMP: JMP (TMP) +END +; +; CALL 6502 ROUTINE +; ROMCALL(AREG, XREG, YREG, STATUS, ADDR) +; +ASM ROMCALL + PHP + LDA ESTKL,X + STA TMPL + LDA ESTKH,X + STA TMPH + INX + LDA ESTKL,X + PHA + INX + LDA ESTKL,X + TAY + INX + LDA ESTKL+1,X + PHA + LDA ESTKL,X + INX + STX ESP + TAX + PLA + BIT ROMIN + PLP + JSR JMPTMP + PHP + BIT LCBNK2 + STA REGVALS+0 + STX REGVALS+1 + STY REGVALS+2 + PLA + STA REGVALS+3 + LDX ESP + LDA #REGVALS + STA ESTKL,X + STY ESTKH,X + PLP + RTS +REGVALS: DS 4 +END +; +; CALL PRODOS +; SYSCALL(CMD, PARAMS) +; +ASM SYSCALL + LDA ESTKL,X + LDY ESTKH,X + STA PARAMS + STY PARAMS+1 + INX + LDA ESTKL,X + STA CMD + STX ESP + BIT ROMIN + JSR $BF00 +CMD: DB 00 +PARAMS: DW 0000 + BIT LCBNK2 + LDX ESP + STA ESTKL,X + LDY #$00 + STY ESTKH,X +END +; +; SET MEMORY TO VALUE +; MEMSET(VALUE, ADDR, SIZE) +; +ASM MEMSET + LDY #$00 + LDA ESTKL+1,X + STA DSTL + LDA ESTKH+1,X + STA DSTH + INC ESTKL,X + INC ESTKH,X +SETMEM: DEC ESTKL,X + BNE :+ + DEC ESTKH,X + BEQ MEMEXIT +: LDA ESTKL+2,X + STA (DST),Y + INY + BNE :+ + INC DSTH +: DEC ESTKL,X + BNE :+ + DEC ESTKH,X + BEQ MEMEXIT +: LDA ESTKH+2,X + STA (DST),Y + INY + BNE SETMEM + INC DSTH + BNE SETMEM +MEMEXIT: INX + INX + INX +END +; +; COPY MEMORY +; MEMCPY(SRCADDR, DSTADDR, SIZE) +; +ASM MEMCPY + LDY #$00 + LDA ESTKL,X + BNE :+ + LDA ESTKH,X + BEQ MEMEXIT +: LDA ESTKL+1,X + STA DSTL + LDA ESTKH+1,X + STA DSTH + LDA ESTKL+2,X + STA SRCL + LDA ESTKH+2,X + STA SRCH + CMP DSTH + BCC REVCPY + BNE FORCPY + LDA SRCL + CMP DSTL + BCS FORCPY +REVCPY: ; REVERSE DIRECTION COPY +; CLC + LDA ESTKL,X + ADC DSTL + STA DSTL + LDA ESTKH,X + ADC DSTH + STA DSTH + CLC + LDA ESTKL,X + ADC SRCL + STA SRCL + LDA ESTKH,X + ADC SRCH + STA SRCH + INC ESTKH,X +REVCPYLP: + LDA DSTL + BNE :+ + DEC DSTH +: DEC DSTL + LDA SRCL + BNE :+ + DEC SRCH +: DEC SRCL + LDA (SRC),Y + STA (DST),Y + DEC ESTKL,X + BNE REVCPYLP + DEC ESTKH,X + BNE REVCPYLP + BEQ MEMEXIT +FORCPY: INC ESTKH,X +FORCPYLP: + LDA (SRC),Y + STA (DST),Y + INC DSTL + BNE :+ + INC DSTH +: INC SRCL + BNE :+ + INC SRCH +: DEC ESTKL,X + BNE FORCPYLP + DEC ESTKH,X + BNE FORCPYLP + BEQ MEMEXIT +END +; +; CHAR OUT +; COUT(CHAR) +; +ASM COUT + LDA ESTKL,X + INX + ORA #$80 + BIT ROMIN + JSR $FDED + BIT LCBNK2 +END +; +; CHAR IN +; RDKEY() +; +ASM CIN + BIT ROMIN + STX ESP + JSR $FD0C + LDX ESP + BIT LCBNK2 + DEX + AND #$7F + STA ESTKL,X + LDY #$00 + STY ESTKH,X +END +; +; PRINT STRING +; PRSTR(STR) +; +ASM PRSTR + LDY #$00 + LDA ESTKL,X + STA SRCL + LDA ESTKH,X + STA SRCH + BIT ROMIN + LDA (SRC),Y + STA ESTKL,X + BEQ :+ +_PRS1: INY + LDA (SRC),Y + ORA #$80 + JSR $FDED + TYA + CMP ESTKL,X + BNE _PRS1 +: INX + BIT LCBNK2 +END +; +; READ STRING +; STR = RDSTR(PROMPTCHAR) +; +ASM RDSTR + LDA ESTKL,X + STA $33 + STX ESP + BIT ROMIN + JSR $FD6A + BIT LCBNK2 + STX $01FF +: LDA $01FF,X + AND #$7F + STA $01FF,X + DEX + BPL :- + LDX ESP + LDA #$FF + STA ESTKL,X + LDA #$01 + STA ESTKH,X +END +; +; CONVERT CHARACTER TO UPPER CASE (AND STRIP MSB) +; CH = TOUPPER(CH) +; +ASM TOUPPER + LDA ESTKL,X + AND #$7F + CMP #'a' + BCC :+ + CMP #'z'+1 + BCS :+ + ; SEC + SBC #$1F ; SBC #$20 +: STA ESTKL,X +END +DEF CROUT + COUT($0D) +END +DEF BADMOD + PRSTR(@BADMODSTR) + CROUT() +END +DEF PRBYTE(VAL) + DROP ROMCALL(VAL, 0, 0, 0, $FDDA) +END +DEF PRWORD(VAL) + DROP ROMCALL(VAL >> 8, VAL, 0, 0, $F941) +END +; +; BASIC FILE I/O +; +DEF GETFILEINFO(PATH, INFOPTR) + BYTE PARAMS[18] + + PARAMS.0 = 10 + PARAMS:1 = PATH + PERR = SYSCALL($C4, @PARAMS) + IF NOT PERR + MEMCPY(@PARAMS.3, INFOPTR, 15) + FIN + RETURN PERR +END +DEF DESTROY(PATH) + BYTE PARAMS[3] + + PARAMS.0 = 1 + PARAMS:1 = PATH + PERR = SYSCALL($C1, @PARAMS) + RETURN PERR +END +DEF CREATE(PATH, ACCESS, TYPE, AUX) + BYTE PARAMS[12] + + PARAMS.0 = 7 + PARAMS:1 = PATH + PARAMS.3 = ACCESS + PARAMS.4 = TYPE + PARAMS:5 = AUX + PARAMS.7 = $1 + PARAMS:8 = 0 + PARAMS:10 = 0 + PERR = SYSCALL($C0, @PARAMS) + RETURN PERR +END +DEF OPEN(PATH, BUFF) + BYTE PARAMS[6] + + PARAMS.0 = 3 + PARAMS:1 = PATH + PARAMS:3 = BUFF + PARAMS.5 = 0 + PERR = SYSCALL($C8, @PARAMS) + RETURN PARAMS.5 +END +DEF CLOSE(REFNUM) + BYTE PARAMS[2] + + PARAMS.0 = 1 + PARAMS.1 = REFNUM + PERR = SYSCALL($CC, @PARAMS) + RETURN PERR +END +DEF READ(REFNUM, BUFF, LEN) + BYTE PARAMS[8] + + PARAMS.0 = 4 + PARAMS.1 = REFNUM + PARAMS:2 = BUFF + PARAMS:4 = LEN + PARAMS:6 = 0 + PERR = SYSCALL($CA, @PARAMS) + RETURN PARAMS:6 +END +DEF WRITE(REFNUM, BUFF, LEN) + BYTE PARAMS[8] + PARAMS.0 = 4 + PARAMS.1 = REFNUM + PARAMS:2 = BUFF + PARAMS:4 = LEN + PARAMS:6 = 0 + PERR = SYSCALL($CB, @PARAMS) + RETURN PARAMS:6 +END +; +; REL MODULE FIXUPS +; +;DEF DUMPRLD(RLD) +; COUT('$') +; PRBYTE(^RLD) +; COUT(':') +; COUT(' ') +; COUT('$') +; PRWORD(*(RLD + 1)) +; COUT(' ') +; COUT('$') +; PRBYTE(^(RLD + 3)) +; CROUT +; RETURN RLD + 4 +;END +;DEF DUMPESD(ESD) +; WHILE ^ESD & $80 +; COUT(^ESD) +; ESD = ESD + 1 +; LOOP +; COUT(^ESD) +; COUT(':') +; COUT(' ') +; COUT('$') +; PRBYTE(^(ESD + 1)) +; COUT(' ') +; COUT('$') +; PRWORD(^(ESD + 2)) +; CROUT +; RETURN ESD + 4 +;END +DEF MATCHSTR(STR1, STR2) + BYTE I + IF ^STR1 == ^STR2 + FOR I = ^STR1 DOWNTO 1 + IF (STR1).[I] <> (STR2).[I] + RETURN FALSE + FIN + NEXT + RETURN TRUE + FIN + RETURN FALSE +END +; +; THE GLOBAL SYMBOL DICTIONARY HAS THE FORMAT OF: +; STRING: NAME (VARIABLE LENGTH) +; WORD: ADDRESS +; +DEF DUMPDICT + WORD DICTPTR + + DICTPTR = SYMTABLE + CROUT() + WHILE ^DICTPTR + PRSTR(DICTPTR) + COUT(':') + COUT(' ') + COUT('$') + PRWORD(*(DICTPTR + ^DICTPTR + 1)) + CROUT() + DICTPTR = DICTPTR + ^DICTPTR + 3 ; NEXT ENTRY + LOOP +END +DEF SEARCHDICT(SYMSTR) + WORD DICTPTR + + DICTPTR = SYMTABLE + ; + ; SEARCH GLOBAL DICTIONARY LOOKING FOR MATCH + ; + WHILE ^DICTPTR + IF MATCHSTR(DICTPTR, SYMSTR) + RETURN DICTPTR + ^DICTPTR + 1 + FIN + DICTPTR = DICTPTR + ^DICTPTR + 3 ; NEXT ENTRY + LOOP + RETURN 0 +END +DEF ADDSYM(SYMSTR, ADDR) + IF SEARCHDICT(SYMSTR) + PRSTR(@DUPSYMERR) + PRSTR(SYMSTR) + CROUT() + RETURN ERROR + FIN + MEMCPY(SYMSTR, NEXTENTRY, ^SYMSTR + 1) + NEXTENTRY = NEXTENTRY + ^NEXTENTRY + (NEXTENTRY):1 = ADDR + NEXTENTRY = NEXTENTRY + 3 + RETURN OK +END +DEF MATCHEXTRN(INDEX, ESD) + BYTE SYMSTR[$81], I + WORD SYMPTR + + ; + ; FIND MATCHING ESD INDEX + ; + WHILE ^ESD + SYMPTR = ESD + I = 1 + WHILE ^ESD & $80 + SYMSTR[I] = TOUPPER(^ESD) + I = I + 1 + ESD = ESD + 1 + LOOP + SYMSTR[I] = TOUPPER(^ESD) + SYMSTR = I + IF ^(ESD + 1) & $10 + IF ^(ESD + 2) == INDEX + RETURN SEARCHDICT(@SYMSTR) + FIN + FIN + ESD = ESD + 4 + LOOP + RETURN 0 +END +DEF PREXTRN(INDEX, ESD) + BYTE SYMSTR[$81], I + WORD SYMPTR + + ; + ; FIND MATCHING ESD INDEX + ; + WHILE ^ESD + SYMPTR = ESD + I = 1 + WHILE ^ESD & $80 + SYMSTR[I] = TOUPPER(^ESD) + I = I + 1 + ESD = ESD + 1 + LOOP + SYMSTR[I] = TOUPPER(^ESD) + SYMSTR = I + IF ^(ESD + 1) & $10 + IF ^(ESD + 2) == INDEX + PRSTR(@SYMSTR) + FIN + FIN + ESD = ESD + 4 + LOOP +END +; +; THE EXTENDED MODULE FORMAT CONTAINS: +; DATA_SIZE (WORD) +; IF DATA_SIZE <> 0 +; DATA_SEGMENT (0..DATA_SIZE) +; ELSE +; DATA_SIZE (WORD) +; BYTECODE_SIZE (WORD) +; BYTECODE_FUNCTION_COUNT (BYTE) +; DATA_SEGMENT (1..DATA_SIZE) +; BYTECODE_SEGMENT (1..BYTECODE_SIZE) +; BYTECODE_FUNCTION_DICTIONARY (0..BYTECODE_FUNCTION_COUNT * 6) +; BYTE: FLAGS +; BIT 7: ENTRY DEF +; BIT 0..1: OPTIMIZATION LEVEL (0, 1, 2, 3) +; WORD: FUNC SIZE +; WORD: FUNC OFFSET +; BYTE: ESD INDEX IF ENTRY +; FIN +; RELOCATEABLE_DICTIONARY +; BYTE: FLAGS +; BIT 7: SIZE OF RELOC FIELD - 1 = WORD, 0 = BYTE +; BIT 6: MSB/LSB OF WORD - 1 = MSB, 0 = LSB +; BIT 5: ENDIANNESS OF WORD - 1 = BIG, 0 = LITTLE +; BIT 4: EXTRN REF - 1 = EXTRN, 0 = NOT EXTERN +; BIT 3: BYTCODE FUNC - 1 = FUNC, 0 NOT FUNC +; BIT 2: SEGMENT FIXUP - 1 = BYTECODE, 0 = DATA +; BIT 0: NOT END OF RLD - 1 = NOT END, 0 = END +; WORD: FIXUP_OFFSET +; BYTE: 8 BIT VALUE/ESD INDEX IF EXTERN/FUNC INDEX IF BYTECODE FUNC +; END_OF_RLD = $00 (BYTE) +; EXTERNAL_SYMBOL_DICTIONARY +; STRING: NAME +; BYTE: FLAGS +; BIT 4: EXTRN REF +; BIT 3: EXPORT DEF +; BIT 2: MODULE DEP (UNUSED MACRO-BIT) +; BIT 1: BYTECODE ENTRY +; BYTE: EXTRN SYMBOL INDEX/BYTECODE ENTRY INDEX/LSB OF EXPORT OFFSET +; BYTE: EXTERN SYMBOL MODULE INDEX/MSB OF EXPORT OFFSET +; END_OF_ESD = $00 (BYTE) +; +DEF FIXUP(DATASEGPTR, CODESEGPTR, BFD, RLD, OFST, ESD, PASS) + WORD FIXVAL, FIXADDR, EXTRNVAL + + WHILE ^RLD + IF ^RLD & $04 + FIXADDR = CODESEGPTR + *(RLD + 1) + ELSE + FIXADDR = DATASEGPTR + *(RLD + 1) + FIN + IF ^RLD & $08 + ; + ; BYTCODE FUNC INDEX ADDRESS + ; + FIXVAL = BFD + (^(RLD + 3) * 6) + ELSIF ^RLD & $10 + ; + ; EXTERNAL SYMBOL + ; + EXTRNVAL = MATCHEXTRN(^(RLD + 3), ESD) + IF EXTRNVAL + FIXVAL = *EXTRNVAL + ELSIF PASS == 2 + PRSTR(@BADEXT) + PREXTRN(^(RLD + 3), ESD) + CROUT() + RETURN ERROR + FIN + ELSE + ; + ; DATA ADDRESS + ; + IF ^RLD & $80 + ; + ; 16 BIT OFFSET + ; + FIXVAL = OFST + ELSE + ; + ; 8 BIT VALUE FROM RLD TABLE + ; + FIXVAL = ^(RLD + 3) + OFST + FIN + FIN + IF ^RLD & $80 + ; + ; 16 BIT FIXUP + ; + IF ^RLD & $20 ; REVERSE HI AND LO BYTES + FIXVAL = FIXVAL + ((FIXADDR).1 ? ((FIXADDR).0 << 8)) + *FIXADDR = ((FIXVAL >> 8) & $FF) ? (FIXVAL << 8) + ELSE + *FIXADDR = FIXVAL + *FIXADDR + FIN + ELSE + ; + ; 8 BIT FIXUP + ; + IF ^RLD & $40 + ^FIXADDR = (FIXVAL >> 8) + ^FIXADDR + ELSE + ^FIXADDR = FIXVAL + ^FIXADDR + FIN + FIN + RLD = RLD + 4 + LOOP + RETURN OK +END +DEF LOADMOD(MODSTR, PASS) + BYTE REFNUM, I, INFO[15], SYMSTR[81] + WORD RELOFST, MODPTR, MODSYMTBL, MODSYMSZ, LEN + WORD DATASEG, CODESEG, DATALEN, CODELEN, NUMDEFS, BFD, RLD, ESD + WORD CODEOFST, BFDOFST + + DROP GETFILEINFO(MODSTR, @INFO) + IF PERR OR INFO.1 <> $FE ; REL FILE TYPE + RETURN 0, 0 + FIN + IF MODADDR + RELOFST = MODADDR - INFO:2 + ELSE + MODADDR = INFO:2 + LINKADDR = MODADDR + RELOFST = 0 + FIN + MODADDR = MODADDR + DATALEN + ; + ; READ REL FILE + ; + REFNUM = OPEN(MODSTR, INBUFF) + LEN = READ(REFNUM, DATABUFF, 16384) + DROP CLOSE(REFNUM) + ; + ; GET POINTERS TO IMPORTANT SECTIONS + ; + DATALEN = *DATABUFF + IF DATALEN == 0 + ; + ; EXTENDED FORMAT REL + ; + MODPTR = DATABUFF + 2 + DATALEN = (MODPTR):0 + CODELEN = (MODPTR):2 + NUMDEFS = (MODPTR).4 + DATASEG = MODPTR + 5 + CODESEG = DATASEG + DATALEN + CODEOFST = RELOFST + DATALEN + BFD = CODESEG + CODELEN + BFDOFST = CODEOFST + CODELEN + MODPTR = BFD + FOR I = 0 TO NUMDEFS + ; + ; REFORMAT BFD + ; + (MODPTR).0 = $20 ; JSR + (MODPTR):1 = $03D6 ; INTERPX + (MODPTR):3 = (MODPTR):3 + CODEOFST ; FIXUP + (MODPTR).5 = $00 ; EXTERNAL BANK # (0 = MAIN MEM) + MODPTR = MODPTR + 6 + NEXT + ELSE + ; + ; NORMAL FORMAT REL + ; + CODELEN = 0 + DATASEG = DATABUFF + 2 + CODESEG = 0 + BFD = 0 + NUMDEFS = 0 + MODPTR = DATASEG + DATALEN + FIN + RLD = MODPTR + ESD = RLD + WHILE ^ESD ; SKIP OVER RLD + ESD = ESD + 4 + LOOP + ESD = ESD + 1 + ; + ; RUN THROUGH DATA FIXUP TABLE + ; + IF FIXUP(DATASEG, CODESEG, BFD, RLD, RELOFST, ESD, PASS) + RETURN 0, 0 + FIN + ; + ; CHECK SYMBOL TABLE FOR EXPORTS/IMPORTS/MODULE DEPENDENCIES + ; + IF PASS == 1 + WHILE ^ESD + I = 1 + WHILE ^ESD & $80 + SYMSTR[I] = TOUPPER(^ESD) + I = I + 1 + ESD = ESD + 1 + LOOP + SYMSTR[I] = TOUPPER(^ESD) + SYMSTR = I + IF ^(ESD + 1) & $08 ; EXPORT SYMBOL + ; + ; ADD TO GLOBAL SYMBOL TABLE + ; + IF ADDSYM(@SYMSTR, *(ESD + 2) + RELOFST) + RETURN 0, 0 + FIN + ELSIF ^(ESD + 1) & $02 ; BYTECODE ENTRY SYMBOL + ; + ; ADD TO GLOBAL SYMBOL TABLE + ; + IF ADDSYM(@SYMSTR, ^(ESD + 2) * 6 + BFDOFST) + RETURN 0, 0 + FIN + ELSIF ^(ESD + 1) & $04 ; MODULE DEPENDENCY + ; + ; ADD MODULE DEPENDENCY TO MODFILE LIST + ; + MEMCPY(@SYMSTR, MODFILE, I + 1) + MODFILE = MODFILE + I + 1 + MODCOUNT = MODCOUNT + 1 + FIN + ESD = ESD + 4 + LOOP + FIN + RETURN DATASEG, DATALEN + CODELEN + NUMDEFS * 6 +END + +CROUT() +PRSTR(@PLASMASTR) +CROUT() +MEMSET(0, SYMTABLE, SYMSIZE) +MODCOUNT = 0 +MODFILE = MODFILES +MODADDR = 0 +PRSTR(@INPUTFILESTR) +WHILE ^(RDSTR($BA)) + MEMCPY(INPUTSTR, MODFILE, ^INPUTSTR + 1) + MODFILE = MODFILE + ^MODFILE + 1 + MODCOUNT = MODCOUNT + 1 +LOOP +IF MODCOUNT + MODFILE = MODFILES + FOR MODI = 0 TO MODCOUNT - 1 + IF NOT LOADMOD(MODFILE, 1) + PRSTR(MODFILE) + COUT('?') + COUT(7) + CROUT() + FIN + DROP + MODFILE = MODFILE + ^MODFILE + 1 + NEXT + MODADDR = 0 + MODFILE = MODFILES + IF LINKADDR == $2000 + BINTYPE = $FF + ELSE + BINTYPE = $06 + FIN + PRSTR(@OUTPUTFILESTR) + RDSTR($BA) + MEMCPY(INPUTSTR, BINFILESTR, ^INPUTSTR + 1) + DROP DESTROY(BINFILESTR) + DROP CREATE(BINFILESTR, $C3, BINTYPE, LINKADDR) + BINREF = OPEN(BINFILESTR, OUTBUFF) + IF BINREF == 0 + PRSTR(@ERROUTSTR) + PRSTR(INPUTSTR) + ELSE + FOR MODI = 0 TO MODCOUNT - 1 + MODBUFF =, MODLEN = LOADMOD(MODFILE, 2) + DROP WRITE(BINREF, MODBUFF, MODLEN) + PRSTR(MODFILE) + COUT('@') + COUT('$') + PRWORD(MODADDR - MODLEN) + CROUT() + MODFILE = MODFILE + ^MODFILE + 1 + NEXT + DROP CLOSE(BINREF) + DUMPDICT() + FIN + CROUT() + PRSTR(@PRESSANYKEY) + WHILE ^$C000 < 128 + LOOP + DROP ^$C010 +FIN +DONE diff --git a/plasma2/plinky.pla b/plasma2/plinky.pla new file mode 100755 index 0000000..b25092c --- /dev/null +++ b/plasma2/plinky.pla @@ -0,0 +1 @@ +CONST FALSE = 0 CONST TRUE = NOT FALSE CONST OK = 0 CONST ERROR = -1 CONST INPUTSTR = $01FF CONST INBUFF = $0800 CONST OUTBUFF = $0C00 CONST SYMTABLE = $B000 CONST SYMSIZE = $0A00 CONST DATABUFF = $A000 WORD NEXTENTRY = SYMTABLE BYTE PLASMASTR[] = "PLASMA LINKER 0.8" BYTE NULLSTR[] = "" BYTE BADMODSTR[] = "MODULE NOT FOUND" BYTE ASMADR[] = "ASM ADDRESS: $" BYTE LOADADR[] = "LOAD ADDRESS: $" BYTE DATASZ[] = "DATA SIZE: $" BYTE RELOFSTSTR[] = "REL OFFSET: $" BYTE FIX16STR[] = "FIXUP 16-BIT ADDRESS: $" BYTE FIX8STR[] = "FIXUP 8-BIT ADDRESS: $" BYTE RLDLBL[] = "RELOCATION DIRECTORY:" BYTE ESDLBL[] = "SYMBOL TABLE:" BYTE MATCHEXTRNSTR = "MATCH EXTRN: " BYTE INPUTFILESTR = "INPUT FILE" BYTE OUTPUTFILESTR = "OUTPUT FILE" BYTE ERROUTSTR = "ERROR CREATING OUTPUT FILE" BYTE PRESSANYKEY[] = "PRESS ANY KEY TO CONTINUE..." BYTE MODCOUNT, MODI BYTE BINREF, BINTYPE WORD MODBUFF,MODLEN,MODADDR,LINKADDR BYTE MODFILES[170] BYTE PERR ; ; SYMBOL TABLE TYPE CONSTANTS ; CONST LOBYTE_TYPE = $01 CONST HIBYTE_TYPE = $02 CONST WORD_TYPE = $03 CONST FUNC_TYPE = $04 CONST CONST_TYPE = $08 ; ; CONVERT CHARACTER TO UPPER CASE (AND STRIP MSB) ; DEF TOUPPER(CH) CH = CH & $7F IF CH >= 'a' AND CH <= 'z' CH = CH - $20 FIN RETURN CH END DEF CROUT COUT($0D) END DEF BADMOD PRSTR(@BADMODSTR) CROUT() END DEF PRBYTE(VAL) DROP ROMCALL(VAL, 0, 0, 0, $FDDA) END DEF PRWORD(VAL) DROP ROMCALL(VAL >> 8, VAL, 0, 0, $F941) END ; ; BASIC FILE I/O ; DEF GETFILEINFO(PATH, INFOPTR) BYTE PARAMS[18] PARAMS.0 = 10 PARAMS:1 = PATH PERR = SYSCALL($C4, @PARAMS) IF NOT PERR MEMCPY(@PARAMS.3, INFOPTR, 15) FIN RETURN PERR END DEF DESTROY(PATH) BYTE PARAMS[3] PARAMS.0 = 1 PARAMS:1 = PATH PERR = SYSCALL($C1, @PARAMS) RETURN PERR END DEF CREATE(PATH, ACCESS, TYPE, AUX) BYTE PARAMS[12] PARAMS.0 = 7 PARAMS:1 = PATH PARAMS.3 = ACCESS PARAMS.4 = TYPE PARAMS:5 = AUX PARAMS.7 = $1 PARAMS:8 = 0 PARAMS:10 = 0 PERR = SYSCALL($C0, @PARAMS) RETURN PERR END DEF OPEN(PATH, BUFF) BYTE PARAMS[6] PARAMS.0 = 3 PARAMS:1 = PATH PARAMS:3 = BUFF PARAMS.5 = 0 PERR = SYSCALL($C8, @PARAMS) RETURN PARAMS.5 END DEF CLOSE(REFNUM) BYTE PARAMS[2] PARAMS.0 = 1 PARAMS.1 = REFNUM PERR = SYSCALL($CC, @PARAMS) RETURN PERR END DEF READ(REFNUM, BUFF, LEN) BYTE PARAMS[8] PARAMS.0 = 4 PARAMS.1 = REFNUM PARAMS:2 = BUFF PARAMS:4 = LEN PARAMS:6 = 0 PERR = SYSCALL($CA, @PARAMS) RETURN PARAMS:6 END DEF WRITE(REFNUM, BUFF, LEN) BYTE PARAMS[8] PARAMS.0 = 4 PARAMS.1 = REFNUM PARAMS:2 = BUFF PARAMS:4 = LEN PARAMS:6 = 0 PERR = SYSCALL($CB, @PARAMS) RETURN PARAMS:6 END ; ; REL MODULE FIXUPS ; DEF DUMPRLD(RLD) COUT('$') PRBYTE(^RLD) COUT(':') COUT(' ') COUT('$') PRWORD(*(RLD + 1)) COUT(' ') COUT('$') PRBYTE(^(RLD + 3)) CROUT RETURN RLD + 4 END DEF DUMPESD(ESD) WHILE ^ESD & $80 COUT(^ESD) ESD = ESD + 1 LOOP COUT(^ESD) COUT(':') COUT(' ') COUT('$') PRBYTE(^(ESD + 1)) COUT(' ') COUT('$') PRWORD(^(ESD + 2)) CROUT RETURN ESD + 4 END DEF MATCHSTR(STR1, STR2) BYTE I IF ^STR1 == ^STR2 FOR I = ^STR1 DOWNTO 1 IF (STR1).[I] <> (STR2).[I] RETURN FALSE FIN NEXT RETURN TRUE FIN RETURN FALSE END ; ; THE GLOBAL SYMBOL DICTIONARY HAS THE FORMAT OF: ; STRING: NAME (VARIABLE LENGTH) ; WORD: ADDRESS ; DEF DUMPDICT WORD DICTPTR DICTPTR = SYMTABLE CROUT() WHILE ^DICTPTR PRSTR(DICTPTR) COUT(':') COUT(' ') COUT('$') PRWORD(*(DICTPTR + ^DICTPTR + 1)) CROUT() DICTPTR = DICTPTR + ^DICTPTR + 3 ; NEXT ENTRY LOOP END DEF ADDSYM(SYMSTR, ADDR) MEMCPY(SYMSTR, NEXTENTRY, ^SYMSTR + 1) NEXTENTRY = NEXTENTRY + ^NEXTENTRY (NEXTENTRY):1 = ADDR NEXTENTRY = NEXTENTRY + 3 END DEF SEARCHDICT(SYMSTR) WORD DICTPTR DICTPTR = SYMTABLE ; ; SEARCH GLOBAL DICTIONARY LOOKING FOR MATCH ; WHILE ^DICTPTR ; CROUT ; PRSTR(DICTPTR) IF MATCHSTR(DICTPTR, SYMSTR) ; COUT('$') ; PRWORD(*(DICTPTR + ^DICTPTR + 1)) RETURN DICTPTR + ^DICTPTR + 1 FIN DICTPTR = DICTPTR + ^DICTPTR + 3 ; NEXT ENTRY LOOP RETURN 0 END DEF MATCHEXTRN(INDEX, ESD) BYTE SYMSTR[$81], I WORD SYMPTR ; ; FIND MATCHING ESD INDEX ; WHILE ^ESD ; DUMPESD(ESD) SYMPTR = ESD I = 1 WHILE ^ESD & $80 SYMSTR[I] = TOUPPER(^ESD) I = I + 1 ESD = ESD + 1 LOOP SYMSTR[I] = TOUPPER(^ESD) SYMSTR = I ; CROUT IF ^(ESD + 1) & $10 ; PRSTR(@MATCHEXTRNSTR) ; PRSTR(@SYMSTR) IF ^(ESD + 2) == INDEX RETURN SEARCHDICT(@SYMSTR) FIN FIN ESD = ESD + 4 LOOP RETURN 0 END DEF FIXUP(SEGPTR, RLD, OFST, ESD, PASS) WORD FIXVAL, FIXADDR, EXTRNVAL WHILE ^RLD ; DUMPRLD(RLD) FIXADDR = SEGPTR + *(RLD + 1) IF ^RLD & $80 ; ; 16 BIT FIXUP ; ; PRSTR(@FIX16STR) ; PRWORD(FIXADDR) ; CROUT FIXVAL = *FIXADDR IF ^RLD & $10 ; ; EXTERNAL SYMBOL ; EXTRNVAL = MATCHEXTRN(^(RLD + 3), ESD) IF EXTRNVAL FIXVAL = FIXVAL + *EXTRNVAL ELSIF PASS == 2 RETURN ERROR FIN ELSE FIXVAL = FIXVAL + OFST FIN IF ^RLD & $20 ; REVERSE HI AND LO BYTES FIXVAL = ((FIXVAL >> 8) & $FF) ? (FIXVAL << 8) FIN *FIXADDR = FIXVAL ELSE ; ; 8 BIT FIXUP ; ; PRSTR(@FIX8STR) ; PRWORD(FIXADDR) ; CROUT IF ^RLD & $10 ; ; EXTERNAL SYMBOL ; EXTRNVAL = MATCHEXTRN(^(RLD + 3), ESD) IF EXTRNVAL FIXVAL = FIXVAL + ^EXTRNVAL ELSIF PASS == 2 RETURN ERROR FIN ELSE IF ^RLD & $40 FIXVAL = ^FIXADDR << 8 ? ^(RLD + 3) FIXVAL = FIXVAL + OFST ELSE FIXVAL = ^(RLD + 3) << 8 ? ^FIXADDR FIXVAL = FIXVAL + OFST FIN FIN IF ^RLD & $40 ^FIXADDR = FIXVAL >> 8 ELSE ^FIXADDR = FIXVAL FIN FIN RLD = RLD + 4 LOOP RETURN OK END DEF LOADMOD(MODSTR, PASS) BYTE REFNUM, I, INFO[15], SYMSTR[81] WORD RELOFST, MODPTR, MODSYMTBL, MODSYMSZ, LEN, DATALEN, RLD, ESD DROP GETFILEINFO(MODSTR, @INFO) IF PERR OR INFO.1 <> $FE ; REL FILE TYPE RETURN 0, 0 FIN ; ; READ REL FILE ; REFNUM = OPEN(MODSTR, INBUFF) LEN = READ(REFNUM, DATABUFF, 32768) DROP CLOSE(REFNUM) ; ; GET POINTERS TO IMPORTANT SECTIONS ; DATALEN = *DATABUFF MODPTR = DATABUFF + 2 RLD = MODPTR + DATALEN ESD = RLD IF MODADDR RELOFST = MODADDR - INFO:2 ELSE MODADDR = INFO:2 LINKADDR = MODADDR RELOFST = 0 FIN MODADDR = MODADDR + DATALEN WHILE ^ESD ; SKIP OVER RLD ESD = ESD + 4 LOOP ESD = ESD + 1 ; PRSTR(@RELOFSTSTR) ; PRWORD(RELOFST) ; CROUT() ; ; RUN THROUGH DATA FIXUP TABLE ; IF FIXUP(MODPTR, RLD, RELOFST, ESD, PASS) RETURN 0, 0 FIN ; ; CREATE SYMBOL TABLE FOR EXPORTS ; IF PASS == 1 WHILE ^ESD ; DUMPESD(ESD) I = 1 WHILE ^ESD & $80 SYMSTR[I] = TOUPPER(^ESD) I = I + 1 ESD = ESD + 1 LOOP SYMSTR[I] = TOUPPER(^ESD) SYMSTR = I IF ^(ESD + 1) & $08 ; ENTRY SYMBOL ADDSYM(@SYMSTR, *(ESD + 2) + RELOFST) FIN ESD = ESD + 4 LOOP FIN RETURN DATABUFF + 2, DATALEN END CROUT() PRSTR(@PLASMASTR) CROUT() MEMSET(0, SYMTABLE, SYMSIZE) MODCOUNT = 0 MODADDR = 0 PRSTR(@INPUTFILESTR) WHILE LOADMOD(RDSTR($BA), 1) DROP MEMCPY(INPUTSTR, @MODFILES[MODCOUNT * 17], ^INPUTSTR + 1) MODCOUNT = MODCOUNT + 1 LOOP DROP IF MODCOUNT MODADDR = 0 IF LINKADDR == $2000 BINTYPE = $FF ELSE BINTYPE = $06 FIN PRSTR(@OUTPUTFILESTR) DROP DESTROY(RDSTR($BA)) DROP CREATE(INPUTSTR, $C3, BINTYPE, LINKADDR) BINREF = OPEN(INPUTSTR, OUTBUFF) IF BINREF == 0 PRSTR(@ERROUTSTR) ELSE FOR MODI = 0 TO MODCOUNT - 1 MODBUFF =, MODLEN = LOADMOD(@MODFILES[MODI * 17], 2) DROP WRITE(BINREF, MODBUFF, MODLEN) NEXT DROP CLOSE(BINREF) DUMPDICT() FIN PRSTR(@PRESSANYKEY) WHILE ^$C000 < 128 LOOP DROP ^$C010 FIN DONE \ No newline at end of file diff --git a/plasma2/plstub.s b/plasma2/plstub.s new file mode 100755 index 0000000..2847ea5 --- /dev/null +++ b/plasma2/plstub.s @@ -0,0 +1,333 @@ +.PC02 +.DEFINE EQU = +.DEFINE DB .BYTE +.DEFINE DW .WORD +.DEFINE DS .RES +;* +;* LANGUAGE CARD CONTROL +;* +LCBNK2 EQU $C080 +ROMIN EQU $C081 +;********************************************************** +;* +;* VM ZERO PAGE LOCATIONS +;* +;********************************************************** +ESTKSZ EQU $20 +ESTK EQU $C0 +ESTKL EQU ESTK +ESTKH EQU ESTK+ESTKSZ/2 +VMZP EQU ESTK+ESTKSZ +FRMP EQU VMZP+$00 +FRMPL EQU FRMP +FRMPH EQU FRMP+1 +PC EQU VMZP+$02 +PCL EQU PC +PCH EQU PC+1 +JSROP EQU VMZP+$0D +;* +;* PAGE 3 ENTRYPOINTS TO INTERNAL ROUTINES +;* +INTERP EQU $03D0 +INTERPX EQU $03D6 +LEAVE EQU $03DC +ENTER EQU $03E2 +;* +;* INTERNAL OPCODE ADDRESS ADDRESSES (FROM OPTBL) +;* +_ZERO EQU $D000 +_ADD EQU $D002 +_SUB EQU $D004 +_MUL EQU $D006 +_DIV EQU $D008 +_DIVMOD EQU $D00A +_INCR EQU $D00C +_DECR EQU $D00E + +_NEG EQU $D010 +_COMP EQU $D012 +_BAND EQU $D014 +_IOR EQU $D016 +_XOR EQU $D018 +_SHL EQU $D01A +_SHR EQU $D01C +_IDXW EQU $D01E + +_NOT EQU $D020 +_LOR EQU $D022 +_LAND EQU $D024 +_LA EQU $D026 +_LLA EQU $D028 +_CB EQU $D02A +_CW EQU $D02C +_SWAP EQU $D02E + +_DROP EQU $D030 +_DUP EQU $D032 +_PUSH EQU $D034 +_PULL EQU $D036 +_SKPLT EQU $D038 +_SKPGT EQU $D03A +_SKPEQ EQU $D03C +_SKPNE EQU $D03E + +_ISEQ EQU $D040 +_ISNE EQU $D042 +_ISGT EQU $D044 +_ISLT EQU $D046 +_ISGE EQU $D048 +_ISLE EQU $D04A +_SKPFLS EQU $D04C +_SKPTRU EQU $D04E + +_SKIP EQU $D050 +_ISKIP EQU $D052 +_CALL EQU $D054 +_ICAL EQU $D056 +_ENTER EQU $D058 +_LEAVE EQU $D05A +_RET EQU $D05C +_INT EQU $D05E + +_LB EQU $D060 +_LW EQU $D062 +_LLB EQU $D064 +_LLW EQU $D066 +_LAB EQU $D068 +_LAW EQU $D06A +_DLB EQU $D06C +_DLW EQU $D06E + +_SB EQU $D070 +_SW EQU $D072 +_SLB EQU $D074 +_SLW EQU $D076 +_SAB EQU $D078 +_SAW EQU $D07A +_DAB EQU $D07C +_DAW EQU $D07E + + JMP _ENTRY + DB $EE,$EE + DB 65,00 + DS 64 +NOPLASMA: DB 39, " PLASMA VM NOT LOADED. PRESS ANY KEY..." + +_ENTRY: BIT LCBNK2 + LDA $D101 + CMP #$B8 ; CLV + BEQ _JMPSTART + BIT ROMIN + LDY #$00 +: INY + LDA NOPLASMA,Y + ORA #$80 + JSR $FDED + CPY NOPLASMA + BNE :- + JSR $FD0C + JMP _EXIT +_JMPSTART: LDX #$FE ; LEAVE $1FF AVAIL FOR RDSTR() + TXS + LDX #$00 + LDA #$BF + STX FRMPL + STA FRMPH + LDY #>START + LDA # 127 +END + +DEF GETKEY + BYTE KEY + + REPEAT + KEY = ^KEYBOARD + UNTIL KEY > 127 + DROP ^KEYSTROBE + RETURN KEY +END + +DEF TEXTMODE + DROP ROMCALL(0, 0, 0, 0, $FB39) +END + +DEF HOME + DROP ROMCALL(0, 0, 0, 0, $FC58) +END + +DEF GOTOXY(X, Y) + ^($24) = X + DROP ROMCALL(Y, 0, 0, 0, $FB5B) +END + +DEF PRSTRXY(X, Y, STRPTR) + GOTOXY(X, Y) + PRSTR(STRPTR) +END + +DEF GRMODE + DROP ROMCALL(0, 0, 0, 0, $FB40) + DROP ^SHOWLORES +END + +DEF COLOR(CLR) + DROP ROMCALL(CLR, 0, 0, 0, $F864) +END + +DEF PLOT(X, Y) + DROP ROMCALL(Y, 0, X, 0, $F800) +END + +DEF HLIN(LEFT, RIGHT, VERT) + ^($2C) = RIGHT + DROP ROMCALL(VERT, 0, LEFT, 0, $F819) +END + +DEF VLIN(TOP, BOTTOM, HORZ) + ^($2D) = BOTTOM + DROP ROMCALL(TOP, 0, HORZ, 0, $F828) +END + +DEF PADDLE(NUM) + RETURN ROMCALL(0, NUM, 0, 0, $FB1E).2 +END + +DEF BUTTON(NUM) + RETURN ^($C060 + NUM) > 127 +END + +DEF UPDTPDL + IF AUTOPLAY + IF PDLPOS + PDLMID > XSCRN + IF PDLPOS > 0 + PDLPOS = PDLPOS - 1 + FIN + ELSIF PDLPOS + PDLMID + 1 < XSCRN + IF PDLPOS + PDLSIZE < 39 + PDLPOS = PDLPOS + 1 + FIN + FIN + ELSE + PDLPOS = PADDLE(0) / 5 + FIN + IF PDLPOS + PDLSIZE > 39 + PDLPOS = 39 - PDLSIZE + FIN + IF PDLPOS + COLOR(0) + HLIN(0, PDLPOS - 1, 39) + FIN + COLOR(1) + HLIN(PDLPOS, PDLPOS + PDLSIZE, 39) + IF PDLPOS + PDLSIZE < 38 + COLOR(0) + HLIN(PDLPOS + PDLSIZE + 1, 39, 39) + FIN +END + +DEF UPDTBALL + BYTE XNEW, YNEW + + ; + ; UPDATE HORIZONTAL POSITION + ; + XBALL = XBALL + XSPEED + IF XBALL > 623 + XBALL = 623 + XSPEED = -XSPEED + BEEP(4, 10) + ELSIF XBALL < 16 + XBALL = 16 + XSPEED = -XSPEED + BEEP(4, 10) + FIN + XNEW = XBALL >> 4 + ; + ; UPDATE VERTICAL POSITION + ; + YBALL = YBALL + YSPEED + IF YBALL > 623 + ; + ; CHECK FOR PADDLE HIT + ; + IF XNEW >= PDLPOS AND XNEW <= PDLPOS + PDLSIZE + YBALL = 623 + YSPEED = -YSPEED - 2 + XSPEED = XSPEED + (XNEW - (PDLPOS + PDLMID - 1)) + IF XSPEED == 0 + IF PDLPOS + PDLMID > 19 + XSPEED = 1 + ELSE + XSPEED = -1 + FIN + FIN + INCSCORE + BEEP(4, 10) + ELSE + MISS = 1 + BEEP(14, 40) + FIN + ELSIF YBALL < 16 + YBALL = 16 + YSPEED = -YSPEED + BEEP(4, 10) + FIN + YNEW = YBALL >> 4 + ; + ; UPDATE ON-SCREEN BALL + ; + IF XNEW <> XSCRN OR YNEW <> YSCRN + COLOR(8) + PLOT(XNEW, YNEW) + COLOR(0) + PLOT(XSCRN, YSCRN) + XSCRN = XNEW + YSCRN = YNEW + FIN +END + +DEF PRSCORE + COUT(SCORE[2]) + COUT(SCORE[1]) + COUT(SCORE[0]) +END + +DEF INCSCORE + SCORE[0] = SCORE[0] + 1 + IF SCORE[0] > '9' + SCORE[0] = '0' + SCORE[1] = SCORE[1] + 1 + IF SCORE[1] > '9' + SCORE[1] = '0' + SCORE[2] = SCORE[2] + 1 + FIN + FIN + GOTOXY(17, 22) + PRSCORE +END + +DEF INITSCORE + SCORE[0] = '0' + SCORE[1] = '0' + SCORE[2] = '0' + GOTOXY(17, 22) + PRSCORE +END + +PRSTR(@LEVEL) +PDLSIZE = (GETKEY - $B0) * 3 +PDLMID = PDLSIZE >> 1 +GRMODE +COLOR(15) +HLIN(0, 39, 0) +VLIN(1, 38, 0) +VLIN(1, 38, 39) +XBALL = PADDLE(0) + 16 +YBALL = PADDLE(1) + 16 +XSCRN = XBALL >> 4 +YSCRN = YBALL >> 4 +XSPEED = 1 +YSPEED = 1 +MISS = 0 +INITSCORE +REPEAT + UPDTPDL + UPDTBALL +UNTIL KEYPRESSED OR MISS +TEXTMODE +HOME +PRSTR(@YOURSCORE) +PRSCORE +COUT($0D) +PRSTR(@GOODBYE) +DONE diff --git a/plasma2/radar.pla b/plasma2/radar.pla new file mode 100755 index 0000000..8004055 --- /dev/null +++ b/plasma2/radar.pla @@ -0,0 +1,162 @@ +CONST SHOWGR = $C050 +CONST SHOWFULL = $C052 +CONST SHOWPG1 = $C054 +CONST SHOWPG2 = $C055 +CONST SHOWLORES = $C056 + +DEF TEXTMODE + DROP ^SHOWPG1 + DROP ROMCALL(0, 0, 0, 0, $FB39) +END + +DEF CPYBUF +; MEMCPY($0400, $0800, 1016) +END + +DEF GRMODE + DROP ROMCALL(0, 0, 0, 0, $F832) + DROP ^SHOWGR + DROP ^SHOWFULL + CPYBUF +; DROP ^SHOWPG2 + DROP ^SHOWLORES +END + +DEF COLOR(CLR) + DROP ROMCALL(CLR, 0, 0, 0, $F864) +END + +DEF PLOT(X, Y) + DROP ROMCALL(Y, 0, X, 0, $F800) +END + +DEF HLIN(LEFT, RIGHT, VERT) + ^$2C = RIGHT + DROP ROMCALL(VERT, 0, LEFT, 0, $F819) +END + +DEF VLIN(TOP, BOTTOM, HORZ) + ^$2D = BOTTOM + DROP ROMCALL(TOP, 0, HORZ, 0, $F828) +END + +DEF LINE(X1, Y1, X2, Y2) + BYTE DX, DY, DX2, DY2, PP, S + WORD SX, SY, ERR, DXDY2 + + IF X1 < X2 + SX = 1 + DX = X2 - X1 + ELSE + SX = -1 + DX = X1 - X2 + FIN + IF Y1 < Y2 + SY = 1 + DY = Y2 - Y1 + ELSE + SY = -1 + DY = Y1 - Y2 + FIN + DX2 = DX << 1 + DY2 = DY << 1 + DXDY2 = DX2 - DY2 + IF DX > DY + ERR = DX + PP = X1 + IF SX < 0 + FOR S = PP DOWNTO X2 + IF ERR < 0 + HLIN(S + 1, PP, Y1) + PP = S + ERR = ERR + DXDY2 + Y1 = Y1 + SY + ELSE + ERR = ERR - DY2 + FIN + NEXT + HLIN(X2, PP, Y2) + ELSE + FOR S = PP TO X2 + IF ERR < 0 + HLIN(PP, S - 1, Y1) + PP = S + ERR = ERR + DXDY2 + Y1 = Y1 + SY + ELSE + ERR = ERR - DY2 + FIN + NEXT + HLIN(PP, X2, Y2) + FIN + ELSE + ERR = -DY + PP = Y1 + IF SY < 0 + FOR S = PP DOWNTO Y2 + IF ERR >= 0 + VLIN(S + 1, PP, X1) + PP = S + ERR = ERR + DXDY2 + X1 = X1 + SX + ELSE + ERR = ERR + DX2 + FIN + NEXT + VLIN(Y2, PP, X2) + ELSE + FOR S = PP TO Y2 + IF ERR >= 0 + VLIN(PP, S - 1, X1) + PP = S + ERR = ERR + DXDY2 + X1 = X1 + SX + ELSE + ERR = ERR + DX2 + FIN + NEXT + VLIN(PP, Y2, X2) + FIN + FIN +END + +DEF RADAR(C) + BYTE I + + FOR I = 0 TO 38 + COLOR(C) + LINE(20, 24, I, 0) + CPYBUF + COLOR(0) + LINE(20, 24, I, 0) + NEXT + FOR I = 0 TO 46 + COLOR(C) + LINE(20, 24, 39, I) + CPYBUF + COLOR(0) + LINE(20, 24, 39, I) + NEXT + FOR I = 39 DOWNTO 1 + COLOR(C) + LINE(20, 24, I, 47) + CPYBUF + COLOR(0) + LINE(20, 24, I, 47) + NEXT + FOR I = 47 DOWNTO 1 + COLOR(C) + LINE(20, 24, 0, I) + CPYBUF + COLOR(0) + LINE(20, 24, 0, I) + NEXT +END + +GRMODE +REPEAT + RADAR(15) +UNTIL ^$C000 > 127 +DROP ^$C010 +TEXTMODE +DONE diff --git a/plasma2/read.me#040000 b/plasma2/read.me#040000 new file mode 100755 index 0000000..01b587a --- /dev/null +++ b/plasma2/read.me#040000 @@ -0,0 +1,267 @@ + WELCOME TO PLASMA ][! + +FIRST THINGS FIRST: + + YOU ARE INSIDE THE PLASMA TEXT EDITOR. +TO NAVIGATE, USE THE ARROW KEYS. ON THE +APPLE ][: CTRL-K = UP, CTRL-J = DOWN. + +TO JUMP AROUND THE TEXT FILE USE: + + CTRL-W = JUMP UP + CTRL-Z = JUMP DOWN + CTRL-A = JUMP LEFT + CTRL-S = JUMP RIGHT + + CTRL-Q = JUMP BEGINNING + CTRL-E = JUMP END + +THE 'ESCAPE' KEY WILL PUT YOU IN COMMAND +MODE. FROM THERE YOU CAN EXIT BY +ENTERING 'Q' AND 'RETURN'. + + NOW THAT YOU CAN MOVE AROUND, LET'S +DESCRIBE WHAT PLASMA IS: PLASMA IS A +RUNTIME ENVIRONMENT AND TOOLSET USED TO +BUILD AND RUN A NEW CLASS OF PROGRAM ON +THE APPLE II SERIES OF COMPUTERS. +PLASMA ][ STANDS FOR PROTO LANGUAGE +ASSEMBLER FOR APPLE ][S. + +PLASMA IS SIMILAR IN CONCEPT TO THE +APPLE PASCAL SYSTEM THAT WAS RELEASED +IN 1979. A VIRTUAL COMPUTER INSTRUCTION +SET WAS CREATED, DESIGNED SPECIFICALLY +FOR THE APPLE II AND 6502 PROCESSOR. +WITH A COMPILER CLOSELY MATCHED TO THE +VIRTUAL INSTRUCTION SET, FAST, EFFICIENT +AND COMPACT PROGRAMS CAN BE WRITTEN AND +RUN ON THE APPLE II. THE VIRTUAL +INSTRUCTIONS ARE EFFICIENTLY INTERPRETED +BY THE 6502 FROM CODE THAT RESIDES IN +THE LANGUAGE CARD. THE STANDARD PRODOS +'BYE' PROGRAM LAUNCHER HAS BEEN REPLACED +BY A COMMAND LINE LAUNCHER WRITTEN IN +PLASMA ITSELF. THIS LAUNCHER HAS A FEW +SIMPLE COMMANDS: + + V = LIST ON-LINE VOLUMES + P = SET PREFIX + C = CATALOG + Q = QUIT (REBOOT) + - = LAUNCH PROGRAM NAME FOLLOWING '-' + +THE LAUNCHER HAS THE ABILITY TO PASS +PARAMETERS TO A PROGRAM. FOR INSTANCE, +TYPING "-PLED READ.ME" WOULD TELL THE +PLASMA EDITOR, "PLED", TO READ THE FILE +"READ.ME" AT STARTUP. WHEN LISTING THE +CATALOG OF A DIRECTORY, FILES MARKED +WITH '*' ARE EXECUTABLE, '/' ARE +DIRECTORIES. + +WHEN THE LAUNCHER IS FIRST LOADED, IT +LOOKS FOR A FILE CALLED AUTORUN. IF +IT EXISTS, THE FIRST LINE IN THE FILE IS +READ IN AND USED AS A COMMAND TO RUN. + +FILES ON THIS DISK +================== + +PLASMA.SYSTEM (PLASMA VM CORE, LAUNCHER) +PLED (PLASMA EDITOR, CURRENTLY RUNNING) +PLEX (PLASMA EXECUTIVE) +PLIDE (PLASMA IDE) +FIRE (FOREST FIRE SIMULATION) +ROD (ROD'S COLOR DEMO) +*.PLA (PLASMA SOURCE FILES) + +PLED +---- + + THE PLASMA EDITOR IS A SIMPLE TEXT +EDITOR FOR ENTERING AND MANIPULATING +TEXT AND SOURCE CODE FILES. THE EDITOR +ONLY SUPPORTS 40 COLUMN TEXT ALTHOUGH +LINES CAN BE UP TO 79 CHARACTERS LONG. +THE SCREEN WILL SCROLL HORIZONTALLY +AS THE CURSOR + +IT HAS TWO MODES, COMMAND AND EDIT. + + EDIT COMMANDS: + + LEFT ARROW = MOVE CHAR LEFT + RIGHT ARROW = MOVE CHAR RIGHT + UP ARROW = MOVE LINE UP + DOWN ARROW = MOVE LINE DOWN + CTRL-K = MOVE LINE UP + CTRL-J = MOVE LINE DOWN + CTRL-A = JUMP LEFT + CTRL-S = JUMP RIGHT + CTRL-W = JUMP UP + CTRL-Z = JUMP DOWN + CTRL-Q = JUMP BEGIN + CTRL-E = JUMP END + CTRL-D = DELETE CHAR + CTRL-X = DELETE LINE + CTRL-V = COPY DELETED LINE + CTRL-O = OPEN NEW LINE + CTRL-T = JOIN LINES + CTRL-I = TOGGLE INSERT/OVERWRITE + ESCAPE = SWITCH TO COMMAND MODE + + APPLE ][ FEATURES: + + SHIFT-M = ] + CTRL-N = [ + CTRL-P = _ + CTRL-B = \ + CTRL-L = SHIFT LOCK + SHIFT-LEFT ARROW = DELETE (SHIFT-MOD) + + WITH THE SHIFT-KEY MOD ON AN + APPLE ][, UPPER AND LOWER CASE + ENTRY WORKS AS EXPECTED. + + CTRL-C = FORCE LOWER-CASE CHARS + + IF YOU HAVE A LOWER-CASE CHARACTER + GENERATOR INSTALLED, YOU CAN FORCE + LOWER-CASE DISPLAY. OTHERWISE, + UPPER CASE WILL BE DISPLAYED NORMALLY + BUT lower-case will be displayed in + inverse. this is the default. + + COMMAND MODE: + + + [OPTIONAL PARAMETER] + + Q = QUIT + R = READ FILE + W [FILENAME] = WRITE FILE (OPTIONAL FILEADANAME) + A [FILENAME] = APPEND FILE + C = CATALOG FILES + P [PREFIX] = SET PREFIX + H [SLOT] = HARDCOPY TO DEVICE IN SLOT (DEFAULT 1) + N = CLEAR TEXT IN MEMORY + E = EDIT MODE + 'RETURN' = EDIT MODE + +PLEX +---- + + THE PLASMA EXECUTIVE WILL LOAD A +PLASMA SOURCE FILE AND COMPILE IT INTO +A 16K BUFFER AND RUN THE PROGRAM IF +SUCCESSFULLY COMPILED. THE PROGRAM +WILL PREMATURELY END IF THERE IS A +PROGRAM BUG THAT CAUSES A STACK OVERFLOW +OR CTRL-C IS PRESSED. PLASMA PROGRAMS +THAT RUN IN THE EXECUTIVE ARE LIMITED +IN THEIR FEATURES OVER THOSE CROSS- +COMPILED. NO ASM DEFINED FUNCTIONS ARE +COMPILED BUT THERE ARE SOME BUILT-IN +ROUTINES FOR CALLING ROM ROUTINES AND +PRODOS. + +PLIDE +----- + + THE PLASMA INTEGRATED DEVELOPMENT +ENVIRONMENT COMBINES THE EDITOR AND +EXECUTIVE INTO ONE. AN ADDITIONAL +COMMAND IN COMMAND MODE IS ADDED: + + X = EXECUTE PROGRAM IN MEMORY + +PLIDE HAS A SMALLER EXECUTION BUFFER +THAN PLEX; ONLY 4K. THE SAMPLE PROGRAMS +ON THE DISK CAN BELOADED INTO PLIDE AND +RUN WITH THE EXCEPTION OF "FIRE.PLA" +WHICH IS TOO BIG FOR PLIDE AND MUST BE +RUN FROM PLEX. + + +THE PLASMA ][ LANGUAGE +====================== + + THE PLASMA LANGUAGE HAS EVOLVED A BIT +SINCE THE INITIAL PREVIEW. IN THE FIRST +ITERATION, PLASMA WAS STRUCTURED TO +KEEP THE CALLS TO FUNCTIONS, PARAMETERS +AND RESULTS, STRICTLY DEFINED AND NOT +VERY FLEXIBLE. EXPRESSIONS HAD TO MATCH +UP WITH RESULTS. THIS, VERY TRADITIONAL, +APPROACH, KEPT VALUES ON THE EXECUTION +STACK FROM GETTING LOST AND OVERFLOWING +THE STACK. BUT PLASMA HAS MUCH IN +COMMON WITH THE LANGUAGE 'FORTH' AND +WASN'T EFFECTIVELY USING THE POWER OF +THE STACK IN IT'S OPERATIONS. SO, THE +STRICT CONTROL OVER THE STACK WAS LOOSEND +TO ALLOW MULTIPLE VALUES TO BE SAVED, +STORED, AND MANIPULATED ON THE STACK. +THE COMMA OPERATOR SIMPLY LEAVES THE +CURRENTLY EVALUATED EXPRESSION ON THE +STACK AND MOVES TO THE NEXT ONE. +FUNCTIONS CAN RETURN MULTIPLE VALUES ON +THE STACK. AS AN EXAMPLE, HERE IS A +SIMPLE FUNCTION TO SWAP TO VALUES AROUND + + DEF SWAP(A, B) + RETURN B, A + END + +A NEW OPERATER, EQUAL LIST (=,), CAN BE +USED TO SET A LIST OF VARIABLES FROM THE +STACK. FUNCTIONS THAT RETURN MULTIPLE +VALUES CAN BE SET AS SUCH: + + A =, B = SWAP(A, B) + +COMBINING THESE CONCEPTS, YOU COULD USE: + + A =, B = B, A + +TO SWAP TWO VARIABLES WITH EACH OTHER. +THE DOWNSIDE OF SUCH FLEXIBILITY IS THE +EVALUATION STACK MUST BE TRACKED +CAREFULLY. ANY MISMATCH IN LOADING +OR SAVING VALUES FROM THE STACK WILL +RESULT IN AN OVERFLOW OR UNDERFLOW +CONDITION. ONE HUERISTIC TO HELP IS TO +APPEND A COUNT OF PARAMTERS AND RETURN +VALUES TO THE FUNCTION NAME. USING SUCH +NOMENCLATURE WOULD RESULT IN THE +DEFINITION OF SWAP AS SUCH: + + DEF SWAP22(A, B) + RETURN B, A) + END + +SOMETIMES THERE IS A NEED TO SIMPLY GET +RID OF THE VALUE ON THE STACK. 'DROP' +WILL DO THAT. IT CAN BE USED ALONG WITH +AN EXPRESSION OR BY ITSELF. TO READ A +SOFTSWITCH AND DISCARD THE VALUE WOULD +BE WRITTEN AS: + + DROP ^$C010 ; CLEAR KEYBOARD STROBE + +BY ALLOWING MULTIPLE VALUES TO BE LOADED +FROM THE EVALUATION STACK, THE MOD +OPERATOR (%) HAS BEEN MODIFIED INTO A +DIV-MOD OPERATOR. BOTH THE DIVIDE AND +REMAINDER RESULT ARE PRESENT ON THE +STACK AFTERWARD. OFTEN BOTH RESULTS ARE +USEFUL, BUT ONE OR THE OTHER CAN BE +EASILY DISCARDED WITH THE DROP KEYWORD. + + DIV10 =, REM10 = I % 10 + +OTHER THAN THESE SMALL CHANGES, PLASMA +IS PRETTY MUCH THE SAME AS BEFORE. +MORE LANGUAGE SPECIFICATION WILL BE +WRITTEN IN THE FUTURE. diff --git a/plasma2/rod#ff0000 b/plasma2/rod#ff0000 new file mode 100755 index 0000000..01aed08 Binary files /dev/null and b/plasma2/rod#ff0000 differ diff --git a/plasma2/rod.pla b/plasma2/rod.pla new file mode 100755 index 0000000..48351a1 --- /dev/null +++ b/plasma2/rod.pla @@ -0,0 +1,182 @@ +const speaker=$C030 +const showgraphics=$C050 +const showtext=$C051 +const showfull=$C052 +const showmix=$C053 +const TRUE=$FFFF +const FALSE=$0000 +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 +byte exitmsg[] = "PRESS ANY KEY TO EXIT." +byte goodbye[] = "THAT'S ALL FOLKS!" +byte rebootmsg[] = "PRESS ANY KEY TO REBOOT..." +byte i, j, k, w, fmi, fmk, color +; +; CALL 6502 ROUTINE +; ROMCALL(AREG, XREG, YREG, STATUS, ADDR) +; +asm romcall +TMP EQU $06 + + PHP + LDA ESTKL,X + STA TMP + LDA ESTKH,X + STA TMP+1 + INX + LDA ESTKL,X + PHA + INX + LDA ESTKL,X + TAY + INX + LDA ESTKL+1,X + PHA + LDA ESTKL,X + INX + STX TMP+2 + TAX + PLA + BIT ROMIN + PLP + JSR JMPTMP + PHP + BIT LCBNK2 + STA REGVALS+0 + STX REGVALS+1 + STY REGVALS+2 + PLA + STA REGVALS+3 + LDX TMP+2 + LDA #REGVALS + STA ESTKL,X + STY ESTKH,X + PLP + RTS +JMPTMP: JMP (TMP) +REGVALS: DS 4 +end +; +; CHAR OUT +; COUT(CHAR) +; +asm cout + LDA ESTKL,X + INX + ORA #$80 + BIT ROMIN + JSR $FDED + BIT LCBNK2 +end +; +; PRINT STRING +; PRSTR(STR) +; +asm prstr + LDY #$00 + LDA ESTKL,X + STA TMP + LDA ESTKH,X + STA TMP+1 + BIT ROMIN + LDA (TMP),Y + STA ESTKL,X + BEQ :+ +_PRS1: INY + LDA (TMP),Y + ORA #$80 + JSR $FDED + TYA + CMP ESTKL,X + BNE _PRS1 +: INX + BIT LCBNK2 +end +def textmode + drop romcall(0, 0, 0, 0, $FB39) +end +def home + drop romcall(0, 0, 0, 0, $FC58) +end +def gotoxy(x, y) + ^($24) = x + drop romcall(y, 0, 0, 0, $FB5B) +end +def crout + cout($0D) +end +def grmode + drop romcall(0, 0, 0, 0, $FB40) + drop ^showlores +end +; grcolor(color) +asm grcolor + LDA ESTKL,X + INX + STX TMP+2 + BIT $C081 + JSR $F864 + BIT $C080 + LDX TMP+2 +end +; grplot(x, y) +asm grplot + LDA ESTKL,X + INX + LDY ESTKL,X + INX + STX TMP+2 + BIT $C081 + JSR $F800 + BIT $C080 + LDX TMP+2 +end +defopt colors + while TRUE + for w = 3 to 50 + for i = 1 to 19 + for j = 0 to 19 + k = i + j + color = (j * 3) / (i + 3) + i * w / 12 + fmi = 40 - i + fmk = 40 - k + grcolor(color); + grplot(i, k); + grplot(k, i); + grplot(fmi, fmk); + grplot(fmk, fmi); + grplot(k, fmi); + grplot(fmi, k); + grplot(i, fmk); + grplot(fmk, i); + if ^keyboard >= 128 + drop ^keystrobe + return + fin + next + next + next + loop +end + +grmode() +home() +gotoxy(10,22) +prstr(@exitmsg) +colors() +textmode() +home() +prstr(@goodbye) +while ^keyboard < 128 +loop +drop ^keystrobe +done diff --git a/plasma2/rod.pla#040000 b/plasma2/rod.pla#040000 new file mode 100755 index 0000000..e404ddf --- /dev/null +++ b/plasma2/rod.pla#040000 @@ -0,0 +1,63 @@ +const showlores = $C056 +const keyboard = $C000 +const keystrobe = $C010 +byte exitmsg[] = "PRESS ANY KEY TO EXIT." +byte goodbye[] = "THAT'S ALL FOLKS!" +byte i, j, k, w, fmi, fmk, color + +def textmode + drop romcall(0, 0, 0, 0, $FB39) +end + +def home + drop romcall(0, 0, 0, 0, $FC58) +end + +def gotoxy(x, y) + ^($24) = x + drop romcall(y, 0, 0, 0, $FB5B) +end + +def grmode + drop romcall(0, 0, 0, 0, $FB40) + ^showlores +end + +def colors + while 1 + for w = 3 to 50 + for i = 1 to 19 + for j = 0 to 19 + k = i + j + color = (j * 3) / (i + 3) + i * w / 12 + fmi = 40 - i + fmk = 40 - k + drop romcall(color, 0, 0, 0, $F864) ;grcolor(color); + drop romcall(k, 0, i, 0, $F800) ;grplot(i, k); + drop romcall(i, 0, k, 0, $F800) ;grplot(k, i); + drop romcall(fmk, 0, fmi, 0, $F800) ;grplot(fmi, fmk); + drop romcall(fmi, 0, fmk, 0, $F800) ;grplot(fmk, fmi); + drop romcall(fmi, 0, k, 0, $F800) ;grplot(k, fmi); + drop romcall(k, 0, fmi, 0, $F800) ;grplot(fmi, k); + drop romcall(fmk, 0, i, 0, $F800) ;grplot(i, fmk); + drop romcall(i, 0, fmk, 0, $F800) ;grplot(fmk, i); + if ^keyboard >= 128 + drop ^keystrobe + return + fin + next + next + next + loop +end + + +grmode +home +gotoxy(10,22) +prstr(@exitmsg) +colors +textmode +home +prstr(@goodbye) +done diff --git a/plasma2/rod.s b/plasma2/rod.s new file mode 100755 index 0000000..0c7be38 --- /dev/null +++ b/plasma2/rod.s @@ -0,0 +1,670 @@ + .INCLUDE "plstub.s" +; 1: const speaker=$C030 + ; speaker = 49200 +; 2: const showgraphics=$C050 + ; showgraphics = 49232 +; 3: const showtext=$C051 + ; showtext = 49233 +; 4: const showfull=$C052 + ; showfull = 49234 +; 5: const showmix=$C053 + ; showmix = 49235 +; 6: const TRUE=$FFFF + ; TRUE = 65535 +; 7: const FALSE=$0000 + ; FALSE = 0 +; 8: const showpage1=$C054 + ; showpage1 = 49236 +; 9: const showpage2=$C055 + ; showpage2 = 49237 +; 10: const showlores=$C056 + ; showlores = 49238 +; 11: const showhires=$C057 + ; showhires = 49239 +; 12: const keyboard=$C000 + ; keyboard = 49152 +; 13: const keystrobe=$C010 + ; keystrobe = 49168 +; 14: const hgr1=$2000 + ; hgr1 = 8192 +; 15: const hgr2=$4000 + ; hgr2 = 16384 +; 16: const page1=0 + ; page1 = 0 +; 17: const page2=1 + ; page2 = 1 +; 18: byte exitmsg[] = "PRESS ANY KEY TO EXIT." +D0000: ; exitmsg + DB $16 + DB $50,$52,$45,$53,$53,$20,$41,$4E + DB $59,$20,$4B,$45,$59,$20,$54,$4F + DB $20,$45,$58,$49,$54,$2E +; 19: byte goodbye[] = "THAT'S ALL FOLKS!" +D0023: ; goodbye + DB $11 + DB $54,$48,$41,$54,$27,$53,$20,$41 + DB $4C,$4C,$20,$46,$4F,$4C,$4B,$53 + DB $21 +; 20: byte rebootmsg[] = "PRESS ANY KEY TO REBOOT..." +D0041: ; rebootmsg + DB $1A + DB $50,$52,$45,$53,$53,$20,$41,$4E + DB $59,$20,$4B,$45,$59,$20,$54,$4F + DB $20,$52,$45,$42,$4F,$4F,$54,$2E + DB $2E,$2E +; 21: byte i, j, k, w, fmi, fmk, color +D0068: DS 1 ; i +D0069: DS 1 ; j +D0070: DS 1 ; k +D0071: DS 1 ; w +D0072: DS 1 ; fmi +D0073: DS 1 ; fmk +D0074: DS 1 ; color +; 22: ; +; 23: ; CALL 6502 ROUTINE +; 24: ; ROMCALL(AREG, XREG, YREG, STATUS, ADDR) +; 25: ; +; 26: asm romcall +C0000: ; romcall() +; 27: TMP EQU $06 +TMP EQU $06 +; 28: +; 29: PHP + PHP +; 30: LDA ESTKL,X + LDA ESTKL,X +; 31: STA TMP + STA TMP +; 32: LDA ESTKH,X + LDA ESTKH,X +; 33: STA TMP+1 + STA TMP+1 +; 34: INX + INX +; 35: LDA ESTKL,X + LDA ESTKL,X +; 36: PHA + PHA +; 37: INX + INX +; 38: LDA ESTKL,X + LDA ESTKL,X +; 39: TAY + TAY +; 40: INX + INX +; 41: LDA ESTKL+1,X + LDA ESTKL+1,X +; 42: PHA + PHA +; 43: LDA ESTKL,X + LDA ESTKL,X +; 44: INX + INX +; 45: STX TMP+2 + STX TMP+2 +; 46: TAX + TAX +; 47: PLA + PLA +; 48: BIT ROMIN + BIT ROMIN +; 49: PLP + PLP +; 50: JSR JMPTMP + JSR JMPTMP +; 51: PHP + PHP +; 52: BIT LCBNK2 + BIT LCBNK2 +; 53: STA REGVALS+0 + STA REGVALS+0 +; 54: STX REGVALS+1 + STX REGVALS+1 +; 55: STY REGVALS+2 + STY REGVALS+2 +; 56: PLA + PLA +; 57: STA REGVALS+3 + STA REGVALS+3 +; 58: LDX TMP+2 + LDX TMP+2 +; 59: LDA #REGVALS + LDY #>REGVALS +; 61: STA ESTKL,X + STA ESTKL,X +; 62: STY ESTKH,X + STY ESTKH,X +; 63: PLP + PLP +; 64: RTS + RTS +; 65: JMPTMP: JMP (TMP) +JMPTMP: JMP (TMP) +; 66: REGVALS: DS 4 +REGVALS: DS 4 +; 67: end + RTS +; 68: ; +; 69: ; CHAR OUT +; 70: ; COUT(CHAR) +; 71: ; +; 72: asm cout +C0002: ; cout() +; 73: LDA ESTKL,X + LDA ESTKL,X +; 74: INX + INX +; 75: ORA #$80 + ORA #$80 +; 76: BIT ROMIN + BIT ROMIN +; 77: JSR $FDED + JSR $FDED +; 78: BIT LCBNK2 + BIT LCBNK2 +; 79: end + RTS +; 80: ; +; 81: ; PRINT STRING +; 82: ; PRSTR(STR) +; 83: ; +; 84: asm prstr +C0004: ; prstr() +; 85: LDY #$00 + LDY #$00 +; 86: LDA ESTKL,X + LDA ESTKL,X +; 87: STA TMP + STA TMP +; 88: LDA ESTKH,X + LDA ESTKH,X +; 89: STA TMP+1 + STA TMP+1 +; 90: BIT ROMIN + BIT ROMIN +; 91: LDA (TMP),Y + LDA (TMP),Y +; 92: STA ESTKL,X + STA ESTKL,X +; 93: BEQ :+ + BEQ :+ +; 94: _PRS1: INY +_PRS1: INY +; 95: LDA (TMP),Y + LDA (TMP),Y +; 96: ORA #$80 + ORA #$80 +; 97: JSR $FDED + JSR $FDED +; 98: TYA + TYA +; 99: CMP ESTKL,X + CMP ESTKL,X +; 100: BNE _PRS1 + BNE _PRS1 +; 101: : INX +: INX +; 102: BIT LCBNK2 + BIT LCBNK2 +; 103: end + RTS +; 104: def textmode +C0006: ; textmode() +; 105: drop romcall(0, 0, 0, 0, $FB39) + JSR _INTERP + DB $00 ; ZERO + DB $00 ; ZERO + DB $00 ; ZERO + DB $00 ; ZERO + DB $2C,$39,$FB ; CW 64313 + DB $54,C0000 ; CALL C0000 + DB $30 ; DROP +; 106: end + DB $5C ; RET +; 107: def home +C0008: ; home() +; 108: drop romcall(0, 0, 0, 0, $FC58) + JSR _INTERP + DB $00 ; ZERO + DB $00 ; ZERO + DB $00 ; ZERO + DB $00 ; ZERO + DB $2C,$58,$FC ; CW 64600 + DB $54,C0000 ; CALL C0000 + DB $30 ; DROP +; 109: end + DB $5C ; RET +; 110: def gotoxy(x, y) +C0010: ; gotoxy() + ; x = 2 + ; y = 4 +; 111: ^($24) = x + JSR _INTERP + DB $58,$06,$02 ; ENTER 6,2 + DB $2A,$24 ; CB 36 + DB $66,$02 ; LLW 2 + DB $70 ; SB +; 112: drop romcall(y, 0, 0, 0, $FB5B) + DB $66,$04 ; LLW 4 + DB $00 ; ZERO + DB $00 ; ZERO + DB $00 ; ZERO + DB $2C,$5B,$FB ; CW 64347 + DB $54,C0000 ; CALL C0000 + DB $30 ; DROP +; 113: end + DB $5A ; LEAVE +; 114: def crout +C0012: ; crout() +; 115: cout($0D) + JSR _INTERP + DB $2A,$0D ; CB 13 + DB $54,C0002 ; CALL C0002 +; 116: end + DB $5C ; RET +; 117: def grmode +C0014: ; grmode() +; 118: drop romcall(0, 0, 0, 0, $FB40) + JSR _INTERP + DB $00 ; ZERO + DB $00 ; ZERO + DB $00 ; ZERO + DB $00 ; ZERO + DB $2C,$40,$FB ; CW 64320 + DB $54,C0000 ; CALL C0000 + DB $30 ; DROP +; 119: drop ^showlores + DB $2C,$56,$C0 ; CW 49238 + DB $60 ; LB + DB $30 ; DROP +; 120: end + DB $5C ; RET +; 121: ; grcolor(color) +; 122: asm grcolor +C0016: ; grcolor() +; 123: LDA ESTKL,X + LDA ESTKL,X +; 124: INX + INX +; 125: STX TMP+2 + STX TMP+2 +; 126: BIT $C081 + BIT $C081 +; 127: JSR $F864 + JSR $F864 +; 128: BIT $C080 + BIT $C080 +; 129: LDX TMP+2 + LDX TMP+2 +; 130: end + RTS +; 131: ; grplot(x, y) +; 132: asm grplot +C0018: ; grplot() +; 133: LDA ESTKL,X + LDA ESTKL,X +; 134: INX + INX +; 135: LDY ESTKL,X + LDY ESTKL,X +; 136: INX + INX +; 137: STX TMP+2 + STX TMP+2 +; 138: BIT $C081 + BIT $C081 +; 139: JSR $F800 + JSR $F800 +; 140: BIT $C080 + BIT $C080 +; 141: LDX TMP+2 + LDX TMP+2 +; 142: end + RTS +; 143: defopt colors +C0020: ; colors() +; 144: while TRUE +C0022: + DEX + LDA #$FF + STA ESTKL,X + STA ESTKH,X + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0023 +: +; 145: for w = 3 to 50 + DEX + LDA #$03 + STA ESTKL,X + LDY #$00 + STY ESTKH,X +C0025: + LDA ESTKL,X + STA D0071 + DEX + LDA #$32 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + LDA ESTKH-1,X + SBC ESTKH,X + BPL :+ + JMP C0024 +: + INC ESTKL,X + BNE :+ + INC ESTKH,X +: +; 146: for i = 1 to 19 + DEX + LDA #$01 + STA ESTKL,X + STY ESTKH,X +C0027: + LDA ESTKL,X + STA D0068 + DEX + LDA #$13 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + LDA ESTKH-1,X + SBC ESTKH,X + BPL :+ + JMP C0026 +: + INC ESTKL,X + BNE :+ + INC ESTKH,X +: +; 147: for j = 0 to 19 + DEX + STY ESTKL,X + STY ESTKH,X +C0029: + LDA ESTKL,X + STA D0069 + DEX + LDA #$13 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + INX + LDA ESTKL-1,X + CMP ESTKL,X + LDA ESTKH-1,X + SBC ESTKH,X + BPL :+ + JMP C0028 +: + INC ESTKL,X + BNE :+ + INC ESTKH,X +: +; 148: k = i + j + DEX + LDA D0068 + STA ESTKL,X + STY ESTKH,X + DEX + LDA D0069 + STA ESTKL,X + STY ESTKH,X + JSR ADD + LDA ESTKL,X + STA D0070 +; 149: color = (j * 3) / (i + 3) + i * w / 12 + LDA D0069 + STA ESTKL,X + STY ESTKH,X + DEX + LDA #$03 + STA ESTKL,X + STY ESTKH,X + JSR MUL + DEX + LDA D0068 + STA ESTKL,X + STY ESTKH,X + DEX + LDA #$03 + STA ESTKL,X + STY ESTKH,X + JSR ADD + JSR DIV + DEX + LDA D0068 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA D0071 + STA ESTKL,X + STY ESTKH,X + JSR MUL + DEX + LDA #$0C + STA ESTKL,X + STY ESTKH,X + JSR DIV + JSR ADD + LDA ESTKL,X + STA D0074 +; 150: fmi = 40 - i + LDA #$28 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA D0068 + STA ESTKL,X + STY ESTKH,X + JSR SUB + LDA ESTKL,X + STA D0072 +; 151: fmk = 40 - k + LDA #$28 + STA ESTKL,X + STY ESTKH,X + DEX + LDA D0070 + STA ESTKL,X + STY ESTKH,X + JSR SUB + LDA ESTKL,X + STA D0073 +; 152: grcolor(color); + LDA D0074 + STA ESTKL,X + STY ESTKH,X + JSR C0016 +; 153: grplot(i, k); + DEX + LDA D0068 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA D0070 + STA ESTKL,X + STY ESTKH,X + JSR C0018 +; 154: grplot(k, i); + DEX + LDA D0070 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA D0068 + STA ESTKL,X + STY ESTKH,X + JSR C0018 +; 155: grplot(fmi, fmk); + DEX + LDA D0072 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA D0073 + STA ESTKL,X + STY ESTKH,X + JSR C0018 +; 156: grplot(fmk, fmi); + DEX + LDA D0073 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA D0072 + STA ESTKL,X + STY ESTKH,X + JSR C0018 +; 157: grplot(k, fmi); + DEX + LDA D0070 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA D0072 + STA ESTKL,X + STY ESTKH,X + JSR C0018 +; 158: grplot(fmi, k); + DEX + LDA D0072 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA D0070 + STA ESTKL,X + STY ESTKH,X + JSR C0018 +; 159: grplot(i, fmk); + DEX + LDA D0068 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA D0073 + STA ESTKL,X + STY ESTKH,X + JSR C0018 +; 160: grplot(fmk, i); + DEX + LDA D0073 + STA ESTKL,X + LDY #$00 + STY ESTKH,X + DEX + LDA D0068 + STA ESTKL,X + STY ESTKH,X + JSR C0018 +; 161: if ^keyboard >= 128 + DEX + LDY #$00 + STY ESTKL,X + LDA #$C0 + STA ESTKH,X + JSR LB + DEX + LDA #$80 + STA ESTKL,X + STY ESTKH,X + JSR ISGE + INX + LDA ESTKL-1,X + ORA ESTKH-1,X + BNE :+ + JMP C0030 +: +; 162: drop ^keystrobe + DEX + LDA #$10 + STA ESTKL,X + LDA #$C0 + STA ESTKH,X + LDY #$00 + JSR LB +; 163: return + INX + INX + RTS +; 164: fin + INX + INX +C0030: +C0031: +; 165: next + JMP C0029 +C0028: +; 166: next + INX + JMP C0027 +C0026: +; 167: next + INX + JMP C0025 +C0024: +; 168: loop + INX + JMP C0022 +C0023: +; 169: end + RTS +; 170: +; 171: grmode() +START: ; JSR INTERP + DB $54,C0014 ; CALL C0014 +; 172: home() + DB $54,C0008 ; CALL C0008 +; 173: gotoxy(10,22) + DB $2A,$0A ; CB 10 + DB $2A,$16 ; CB 22 + DB $54,C0010 ; CALL C0010 +; 174: prstr(@exitmsg) + DB $26,D0000 ; LA D0000 + DB $54,C0004 ; CALL C0004 +; 175: colors() + DB $54,C0020 ; CALL C0020 +; 176: textmode() + DB $54,C0006 ; CALL C0006 +; 177: home() + DB $54,C0008 ; CALL C0008 +; 178: prstr(@goodbye) + DB $26,D0023 ; LA D0023 + DB $54,C0004 ; CALL C0004 +; 179: while ^keyboard < 128 +C0032: + DB $2C,$00,$C0 ; CW 49152 + DB $60 ; LB + DB $2A,$80 ; CB 128 + DB $46 ; ISLT + DB $4C,C0033 ; SKPFLS C0033 +; 180: loop + DB $50,C0032 ; SKIP C0032 +C0033: +; 181: drop ^keystrobe + DB $2C,$10,$C0 ; CW 49168 + DB $60 ; LB + DB $30 ; DROP +; 182: done + DB $5C ; RET diff --git a/plasma2/rod.sys b/plasma2/rod.sys new file mode 100755 index 0000000..01aed08 Binary files /dev/null and b/plasma2/rod.sys differ diff --git a/plasma2/teststack.pla b/plasma2/teststack.pla new file mode 100755 index 0000000..f2e17a4 --- /dev/null +++ b/plasma2/teststack.pla @@ -0,0 +1,7 @@ +word a, b + +defn test(parm1, parm2) + return 100 * parm1, 200 + parm2 +end +a =, b = test(1, 2) +done \ No newline at end of file diff --git a/plasma2/tokens.h b/plasma2/tokens.h new file mode 100755 index 0000000..ad4e022 --- /dev/null +++ b/plasma2/tokens.h @@ -0,0 +1,119 @@ + +#define TOKEN(c) (0x80|(c)) +#define IS_TOKEN(c) (0x80&(c)) +/* + * Identifier and constant tokens. + */ +#define ID_TOKEN TOKEN('V') +#define CHAR_TOKEN TOKEN('Y') +#define INT_TOKEN TOKEN('Z') +#define FLOAT_TOKEN TOKEN('F') +#define STRING_TOKEN TOKEN('S') +/* + * Keyword tokens. + */ +#define CONST_TOKEN TOKEN(1) +#define BYTE_TOKEN TOKEN(2) +#define WORD_TOKEN TOKEN(3) +#define IF_TOKEN TOKEN(4) +#define ELSEIF_TOKEN TOKEN(5) +#define ELSE_TOKEN TOKEN(6) +#define FIN_TOKEN TOKEN(7) +#define END_TOKEN TOKEN(8) +#define WHILE_TOKEN TOKEN(9) +#define LOOP_TOKEN TOKEN(10) +#define CASE_TOKEN TOKEN(11) +#define OF_TOKEN TOKEN(12) +#define DEFAULT_TOKEN TOKEN(13) +#define ENDCASE_TOKEN TOKEN(14) +#define FOR_TOKEN TOKEN(15) +#define TO_TOKEN TOKEN(16) +#define DOWNTO_TOKEN TOKEN(17) +#define STEP_TOKEN TOKEN(18) +#define NEXT_TOKEN TOKEN(19) +#define REPEAT_TOKEN TOKEN(20) +#define UNTIL_TOKEN TOKEN(21) +#define IFUNC_TOKEN TOKEN(22) +#define NFUNC_TOKEN TOKEN(23) +#define DROP_TOKEN TOKEN(24) +#define DONE_TOKEN TOKEN(25) +#define RETURN_TOKEN TOKEN(26) +#define BREAK_TOKEN TOKEN(27) +#define START_TOKEN TOKEN(28) +#define EXIT_TOKEN TOKEN(29) +#define EVAL_TOKEN TOKEN(30) +#define FUNC_TOKEN TOKEN(31) +#define ASM_TOKEN TOKEN(32) +/* + * Double operand operators. + */ +#define SET_TOKEN TOKEN('=') +#define ADD_TOKEN TOKEN('+') +#define ADD_SELF_TOKEN TOKEN('a') +#define SUB_TOKEN TOKEN('-') +#define SUB_SELF_TOKEN TOKEN('u') +#define MUL_TOKEN TOKEN('*') +#define MUL_SELF_TOKEN TOKEN('m') +#define DIV_TOKEN TOKEN('/') +#define DIV_SELF_TOKEN TOKEN('d') +#define DIVMOD_TOKEN TOKEN('%') +#define OR_TOKEN TOKEN('?') +#define OR_SELF_TOKEN TOKEN('o') +#define EOR_TOKEN TOKEN('^') +#define EOR_SELF_TOKEN TOKEN('x') +#define AND_TOKEN TOKEN('&') +#define AND_SELF_TOKEN TOKEN('n') +#define SHR_TOKEN TOKEN('R') +#define SHR_SELF_TOKEN TOKEN('r') +#define SHL_TOKEN TOKEN('L') +#define SHL_SELF_TOKEN TOKEN('l') +#define GT_TOKEN TOKEN('>') +#define GE_TOKEN TOKEN('H') +#define LT_TOKEN TOKEN('<') +#define LE_TOKEN TOKEN('B') +#define NE_TOKEN TOKEN('U') +#define EQ_TOKEN TOKEN('E') +#define LOGIC_AND_TOKEN TOKEN('N') +#define LOGIC_OR_TOKEN TOKEN('O') +/* + * Single operand operators. + */ +#define NEG_TOKEN TOKEN('-') +#define COMP_TOKEN TOKEN('#') +#define LOGIC_NOT_TOKEN TOKEN('!') +#define INC_TOKEN TOKEN('P') +#define DEC_TOKEN TOKEN('K') +#define BPTR_TOKEN TOKEN('^') +#define WPTR_TOKEN TOKEN('*') +#define POST_INC_TOKEN TOKEN('p') +#define POST_DEC_TOKEN TOKEN('k') +#define OPEN_PAREN_TOKEN TOKEN('(') +#define CLOSE_PAREN_TOKEN TOKEN(')') +#define OPEN_BRACKET_TOKEN TOKEN('[') +#define CLOSE_BRACKET_TOKEN TOKEN(']') +/* + * Misc. tokens. + */ +#define AT_TOKEN TOKEN('@') +#define DOT_TOKEN TOKEN('.') +#define COLON_TOKEN TOKEN(':') +#define COMMA_TOKEN TOKEN(',') +#define COMMENT_TOKEN TOKEN(';') +#define SETLIST_TOKEN TOKEN('i') +#define EOL_TOKEN TOKEN(0) +#define EOF_TOKEN TOKEN(0x7F) + +typedef unsigned char t_token; + +#define CONST_TYPE (1 << 0) +#define WORD_TYPE (1 << 1) +#define BYTE_TYPE (1 << 2) +#define VAR_TYPE (WORD_TYPE | BYTE_TYPE) +#define FUNC_TYPE (1 << 3) +#define LOCAL_TYPE (1 << 4) +#define ADDR_TYPE (VAR_TYPE | FUNC_TYPE) +#define BPTR_TYPE (1 << 5) +#define WPTR_TYPE (1 << 6) +#define PTR_TYPE (BPTR_TYPE | WPTR_TYPE) +#define STRING_TYPE (1 << 7) +#define TAG_TYPE (1 << 8) diff --git a/plasma2/vmcore.s b/plasma2/vmcore.s new file mode 100755 index 0000000..a101f24 --- /dev/null +++ b/plasma2/vmcore.s @@ -0,0 +1,1612 @@ +.PC02 +.DEFINE EQU = +.DEFINE DB .BYTE +.DEFINE DW .WORD +.DEFINE DS .RES +.DEFINE ORG .ORG +.DEFINE STKCHK 1 +.DEFINE TMRCHK 1 +;********************************************************** +;* +;* SYSTEM ROUTINES AND LOCATIONS +;* +;********************************************************** +;* +;* MONITOR SPECIAL LOCATIONS AND PRODOS MLI +;* +CSWL EQU $36 +CSWH EQU $37 +PROMPTCHAR EQU $33 +PRODOS EQU $BF00 +MACHID EQU $BF98 +;* +;* HARDWARE ADDRESSES +;* +KEYBD EQU $C000 +CLRKBD EQU $C010 +SPKR EQU $C030 +ROMIN EQU $C081 +LCBNK2 EQU $C083 +LCBNK1 EQU $C08B +ALTZPOFF EQU $C008 +ALTZPON EQU $C009 +ALTRAMRDOFF EQU $C002 +ALTRAMRDON EQU $C003 +ALTRAMWROFF EQU $C004 +ALTRAMWRON EQU $C005 +;* +;* AUXMEM ACCESS MACROS +;* +.IF IS65C02 +.MACRO AUXZP_ACCESS_ON + STA ALTZPON ; TURN ON ALT ZP AND LC +.ENDMACRO +.MACRO AUXZP_ACCESS_OFF + STA ALTZPOFF ; TURN OFF ALT ZP AND LC +.ENDMACRO +.MACRO AUXMEM_RDACCESS_ON + STA ALTRAMRDON +.ENDMACRO +.MACRO AUXMEM_RDACCESS_OFF + STA ALTRAMRDOFF +.ENDMACRO +.MACRO AUXMEM_WRACCESS_ON + STA ALTRAMWRON +.ENDMACRO +.MACRO AUXMEM_WRACCESS_OFF + STA ALTRAMWROFF +.ENDMACRO +.ELSE +.MACRO AUXZP_ACCESS_ON + SEI ; TURN INTERRUPTS OFF + STA ALTZPON ; TURN ON ALT ZP AND LC +.ENDMACRO +.MACRO AUXZP_ACCESS_OFF + STA ALTZPOFF ; TURN OFF ALT ZP AND LC + CLI ; TURN INTERRUPTS BACK ON +.ENDMACRO +.MACRO AUXMEM_RDACCESS_ON + SEI + STA ALTRAMRDON +.ENDMACRO +.MACRO AUXMEM_RDACCESS_OFF + STA ALTRAMRDOFF + CLI +.ENDMACRO +.MACRO AUXMEM_WRACCESS_ON + SEI + STA ALTRAMWRON +.ENDMACRO +.MACRO AUXMEM_WRACCESS_OFF + STA ALTRAMWROFF + CLI +.ENDMACRO +.ENDIF +;* +;* SIMPLIFUED ACCESS MACROS +;* +.IF IS65C02 +.MACRO LDA_IPC + LDA (PC) +.ENDMACRO +.MACRO LDA_ITMPL + LDA (TMP) +.ENDMACRO +.MACRO LDA_ITMPH + LDY #$01 + LDA (TMP),Y +.ENDMACRO +.MACRO LDA0 + LDA #$00 +.ENDMACRO +.MACRO STA_ITMPL + STA (TMP) +.ENDMACRO +.MACRO STA_ITMPH + LDY #$01 + STA (TMP),Y +.ENDMACRO +.MACRO ST0 ADDR + STZ ADDR +.ENDMACRO +.MACRO CLRY +.ENDMACRO +.ELSE +.MACRO LDA_IPC + LDA (PC),Y +.ENDMACRO +.MACRO LDA_ITMPL + LDA (TMP),Y +.ENDMACRO +.MACRO LDA_ITMPH + INY + LDA (TMP),Y + DEY +.ENDMACRO +.MACRO LDA0 + TYA +.ENDMACRO +.MACRO STA_ITMPL + STA (TMP),Y +.ENDMACRO +.MACRO STA_ITMPH + INY + STA (TMP),Y + DEY +.ENDMACRO +.MACRO ST0 ADDR + STY ADDR +.ENDMACRO +.MACRO CLRY + LDY #$00 +.ENDMACRO +.ENDIF + +;********************************************************** +;* +;* VM ZERO PAGE LOCATIONS +;* +;********************************************************** +ESTKSZ EQU $20 +ESTK EQU $C0 +ESTKL EQU ESTK +ESTKH EQU ESTK+ESTKSZ/2 +VMZP EQU ESTK+ESTKSZ +FRMP EQU VMZP+$00 +FRMPL EQU FRMP +FRMPH EQU FRMP+1 +PC EQU VMZP+$02 +PCL EQU PC +PCH EQU PC+1 +TICK EQU VMZP+$04 +ESP EQU VMZP+$05 + +TMP EQU VMZP+$0A +TMPL EQU TMP +TMPH EQU TMP+1 +TMPX EQU TMP+2 +NPARMS EQU TMPL +FRMSZ EQU TMPH +DVSIGN EQU TMPX +JSROP EQU VMZP+$0D + + ORG $D000 +;* +;* OPCODE TABLE +;* +OPTBL: DW ZERO,ADD,SUB,MUL,DIV,DIVMOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E + DW NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E + DW NOT,LOR,LAND,LA,LLA,CB,CW,SWAP ; 20 22 24 26 28 2A 2C 2E + DW DROP,DUP,PUSH,PULL,SKPLT,SKPGT,SKPEQ,SKPNE ; 30 32 34 36 38 3A 3C 3E + DW ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,SKPFLS,SKPTRU ; 40 42 44 46 48 4A 4C 4E + DW SKIP,ISKIP,CALL,ICAL,ENTER,LEAVE,RET,INT ; 50 52 54 56 58 5A 5C 5E + DW LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E + DW SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E +;* +;* OPXCODE TABLE +;* +OPXTBL: DW ZERO,ADD,SUB,MUL,DIV,DIVMOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E + DW NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E + DW NOT,LOR,LAND,LAX,LLAX,CBX,CWX,SWAP ; 20 22 24 26 28 2A 2C 2E + DW DROP,DUP,PUSH,PULL,SKPLTX,SKPGTX,SKPEQX,SKPNEX ; 30 32 34 36 38 3A 3C 3E + DW ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,SKPFLSX,SKPTRUX ; 40 42 44 46 48 4A 4C 4E + DW SKIPX,ISKIPX,CALLX,ICAL,ENTER,LEAVE,RET,INTX ; 50 52 54 56 58 5A 5C 5E + DW LB,LW,LLBX,LLWX,LABX,LAWX,DLBX,DLWX ; 60 62 64 66 68 6A 6C 6E + DW SB,SW,SLBX,SLWX,SABX,SAWX,DABX,DAWX ; 70 72 74 76 78 7A 7C 7E +;* +;* COMMAND LOADER CODE +;* + CLD + CLV + BVC :+ + JMP PLASMA +: + .INCLUDE "cmd.byte" + +;*********************************************** +;* +;* INTERPRETER INITIALIZATION +;* +;*********************************************** +;* +;* INIT AND ENTER INTO PLASMA BYTECODE INTERPRETER +;* X:Y:A = ADDRESS OF INITAL ENTRYPOINT +;* +PLASMA: STA PCL + STY PCH + STX TMP + CLD + LDY #$20 +: LDA PAGE3,Y + STA $03D0,Y + DEY + BPL :- + LDX #ESTKSZ/2 + INY ; LDY #$00 + STY TICK + LDA #$6C + STA JSROP + LDA #>OPTBL + STA JSROP+2 + LDA TMP + BEQ FETCHOP + LDA MACHID + AND #$30 + CMP #$30 + BEQ FETCHOPX +_RTS: RTS +_BRK: BRK +;* +;* PAGE 3 VECTORS INTO INTERPRETER +;* +PAGE3: BIT $C080 ; $03D0 - INTERP ENTRY + JMP _INTERP + BIT $C080 ; $03D6 - INTERPX ENTRY + JMP _INTERPX + BIT $C080 ; $03DC - LEAVE ENTRY + JMP _LEAVE + BIT $C080 ; $03E2 - ENTER ENTRY + JMP _ENTER + DW _RTS ; $03E8 - PERIODIC VECTOR + DW _BRK ; $03EA - INT VECTOR +TMRVEC EQU $03E8 +INTVEC EQU $03EA +;* +;* ENTER INTO INLINE BYTECODE +;* +_INTERP: PLA + STA PCL + PLA + STA PCH + LDY #$00 + BEQ NEXTOP +TOCKOP: JSR TICKTOCK +FETCHOP: +.IF TMRCHK + DEC TICK + BEQ TOCKOP +.ENDIF + LDA_IPC + STA JSROP+1 + JSR JSROP +.IF STKCHK + CPX #ESTKSZ/2+1 + BCS STKINT +.ENDIF +NEXTOP: INC PCL + BNE FETCHOP + INC PCH + BNE FETCHOP +STKINT: LDA #$FF +INTJMP: JMP (INTVEC) +TICKTOCK: JMP (TMRVEC) +TMPJMP: JMP (TMP) +;* +;* ENTER INTO EXTERNAL BYTECODE +;* +_INTERPX: PLA + STA TMPL + PLA + STA TMPH + LDY #$01 + LDA (TMP),Y + STA PCL + INY + LDA (TMP),Y + STA PCH + INY + LDA (TMP),Y + TAY + BNE FETCHOPX + BEQ FETCHOP +TOCKOPX: JSR TICKTOCK +FETCHOPX: +.IF TMRCHK + DEC TICK + BEQ TOCKOPX +.ENDIF + AUXMEM_RDACCESS_ON + LDA_IPC + AUXMEM_RDACCESS_OFF + ORA #$80 ; SELECT OPX CODES + STA JSROP+1 + JSR JSROP +.IF STKCHK + CPX #ESTKSZ/2+1 + BCS STKINT +.ENDIF +NEXTOPX: INC PCL + BNE FETCHOPX + INC PCH + BNE FETCHOPX +;* +;* 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 + RTS +;* +;* 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 + RTS +;* +;* SHIFT TOS-1 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 + RTS +;* +;* MUL TOS-1 BY TOS +;* +MUL: ST0 TMPL ; PRODL + ST0 TMPH ; PRODH + LDY #$10 +MUL1: LSR ESTKH,X ; MULTPLRH + ROR ESTKL,X ; MULTPLRL + BCC MUL2 + LDA ESTKL+1,X ; MULTPLNDL + CLC + ADC TMPL ; PRODL + STA TMPL + LDA ESTKH+1,X ; MULTPLNDH + ADC TMPH ; PRODH + STA TMPH +MUL2: ASL ESTKL+1,X ; MULTPLNDL + ROL ESTKH+1,X ; MULTPLNDH + DEY + BNE MUL1 + INX + LDA TMPL ; PRODL + STA ESTKL,X + LDA TMPH ; PRODH + STA ESTKH,X + RTS +;* +;* INTERNAL DIVIDE ALGORITHM +;* +_DIV: LDA ESTKH,X + AND #$80 + STA DVSIGN + BPL _DIV1 + JSR NEG + INC DVSIGN +_DIV1: LDA ESTKH+1,X + BPL _DIV2 + INX + JSR NEG + DEX + INC DVSIGN + BNE _DIV3 +_DIV2: ORA ESTKL+1,X ; DVDNDL + BNE _DIV3 + STA TMPL + STA TMPH + RTS +_DIV3: LDY #$11 ; #BITS+1 + LDA #$00 + STA TMPL ; REMNDRL + STA TMPH ; REMNDRH +_DIV4: ASL ESTKL+1,X ; DVDNDL + ROL ESTKH+1,X ; DVDNDH + DEY + BCC _DIV4 + STY ESTKL-1,X +_DIV5: ROL TMPL ; REMNDRL + ROL TMPH ; REMNDRH + LDA TMPL ; REMNDRL + SEC + SBC ESTKL,X ; DVSRL + TAY + LDA TMPH ; REMNDRH + SBC ESTKH,X ; DVSRH + BCC _DIV6 + STA TMPH ; REMNDRH + STY TMPL ; REMNDRL +_DIV6: ROL ESTKL+1,X ; DVDNDL + ROL ESTKH+1,X ; DVDNDH + DEC ESTKL-1,X + BNE _DIV5 + CLRY + RTS +;* +;* DIV TOS-1 BY TOS +;* +DIV: JSR _DIV + INX + LSR DVSIGN ; SIGN(RESULT) = (SIGN(DIVIDEND) + SIGN(DIVISOR)) & 1 + BCS NEG + RTS +;* +;* NEGATE TOS +;* +NEG: LDA0 + SEC + SBC ESTKL,X + STA ESTKL,X + LDA0 + SBC ESTKH,X + STA ESTKH,X + RTS +;* +;* DIV,MOD TOS-1 BY TOS +;* +DIVMOD: JSR _DIV + LDA TMPL ; REMNDRL + STA ESTKL,X + LDA TMPH ; REMNDRH + STA ESTKH,X + LDA DVSIGN ; REMAINDER IS SIGN OF DIVIDEND + BPL DIVMOD1 + JSR NEG +DIVMOD1: LSR DVSIGN + BCC DIVMOD2 ; DIV RESULT TOS-1 + INX + JSR NEG + DEX +DIVMOD2: RTS +;* +;* INCREMENT TOS +;* +INCR: INC ESTKL,X + BNE INCR1 + INC ESTKH,X +INCR1: RTS +;* +;* DECREMENT TOS +;* +DECR: LDA ESTKL,X + BNE DECR1 + DEC ESTKH,X +DECR1: DEC ESTKL,X + RTS +;* +;* BITWISE COMPLIMENT TOS +;* +COMP: LDA #$FF + EOR ESTKL,X + STA ESTKL,X + LDA #$FF + EOR ESTKH,X + STA ESTKH,X + RTS +;* +;* 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 + RTS +;* +;* 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 + RTS +;* +;* 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 + RTS +;* +;* SHIFT TOS-1 LEFT BY TOS +;* +SHL: 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: INX + RTS +;* +;* SHIFT TOS-1 RIGHT BY TOS +;* +SHR: 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: INX + RTS +;* +;* LOGICAL NOT +;* +NOT: LDA ESTKL,X + ORA ESTKH,X + BNE NOT1 + LDA #$FF + STA ESTKL,X + STA ESTKH,X + RTS +NOT1: ST0 {ESTKL,X} + ST0 {ESTKH,X} + RTS +;* +;* LOGICAL AND +;* +LAND: LDA ESTKL,X + ORA ESTKH,X + BEQ LAND1 + LDA ESTKL+1,X + ORA ESTKH+1,X + BEQ LAND1 + LDA #$FF +LAND1: STA ESTKL+1,X + STA ESTKH+1,X + INX + RTS +;* +;* LOGICAL OR +;* +LOR: LDA ESTKL,X + ORA ESTKH,X + ORA ESTKL+1,X + ORA ESTKH+1,X + BEQ LOR1 + LDA #$FF +LOR1: STA ESTKL+1,X + STA ESTKH+1,X +;* +;* DROP TOS +;* +DROP: INX + RTS +;* +;* SWAP TOS WITH TOS-1 +;* +SWAP: LDA ESTKL,X + LDY ESTKL+1,X + STA ESTKL+1,X + STY ESTKL,X + LDA ESTKH,X + LDY ESTKH+1,X + STA ESTKH+1,X + STY ESTKH,X + CLRY + RTS +;* +;* DUPLICATE TOS +;* +DUP: DEX + LDA ESTKL+1,X + STA ESTKL,X + LDA ESTKH+1,X + STA ESTKH,X + RTS +;* +;* PUSH FROM EVAL STACK TO CALL STACK +;* +PUSH: PLA + STA TMPH + PLA + STA TMPL + LDA ESTKL,X + PHA + LDA ESTKH,X + PHA + INX + LDA TMPL + PHA + LDA TMPH + PHA + RTS +;* +;* PULL FROM CALL STACK TO EVAL STACK +;* +PULL: PLA + STA TMPH + PLA + STA TMPL + DEX + PLA + STA ESTKH,X + PLA + STA ESTKL,X + LDA TMPL + PHA + LDA TMPH + PHA + RTS +;* +;* CONSTANT +;* +ZERO: DEX + ST0 {ESTKL,X} + ST0 {ESTKH,X} + RTS +CB: DEX + INC PCL + BNE CB1 + INC PCH +CB1: LDA_IPC + STA ESTKL,X + ST0 {ESTKH,X} + RTS +;* +;* LOAD ADDRESS - CHECK FOR DATA OR CODE SPACE +;* +LA: +CW: DEX + INC PCL + BNE CW1 + INC PCH +CW1: LDA_IPC + STA ESTKL,X + INC PCL + BNE CW2 + INC PCH +CW2: LDA_IPC + STA ESTKH,X + RTS +;* +;* LOAD VALUE FROM ADDRESS TAG +;* +LB: LDA ESTKL,X + STA TMPL + LDA ESTKH,X + STA TMPH + LDA_ITMPL + STA ESTKL,X + ST0 {ESTKH,X} + RTS +LW: LDA ESTKL,X + STA TMPL + LDA ESTKH,X + STA TMPH + LDA_ITMPL + STA ESTKL,X + LDA_ITMPH + STA ESTKH,X + RTS +;* +;* LOAD ADDRESS OF LOCAL FRAME OFFSET +;* +LLA: INC PCL + BNE LLA1 + INC PCH +LLA1: LDA_IPC + DEX + CLC + ADC FRMPL + STA ESTKL,X + LDA0 + ADC FRMPH + STA ESTKH,X + RTS +;* +;* LOAD VALUE FROM LOCAL FRAME OFFSET +;* +LLB: INC PCL + BNE LLB1 + INC PCH +LLB1: LDA_IPC + TAY + DEX + LDA (FRMP),Y + STA ESTKL,X + CLRY + ST0 {ESTKH,X} + RTS +LLW: INC PCL + BNE LLW1 + INC PCH +LLW1: LDA_IPC + TAY + DEX + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + CLRY + RTS +;* +;* LOAD VALUE FROM ABSOLUTE ADDRESS +;* +LAB: INC PCL + BNE LAB1 + INC PCH +LAB1: LDA_IPC + STA TMPL + INC PCL + BNE LAB2 + INC PCH +LAB2: LDA_IPC + STA TMPH + LDA_ITMPL + DEX + STA ESTKL,X + ST0 {ESTKH,X} + RTS +LAW: INC PCL + BNE LAW1 + INC PCH +LAW1: LDA_IPC + STA TMPL + INC PCL + BNE LAW2 + INC PCH +LAW2: LDA_IPC + STA TMPH + LDA_ITMPL + DEX + STA ESTKL,X + LDA_ITMPH + STA ESTKH,X + RTS +;* +;* STORE VALUE TO ADDRESS +;* +SB: LDA ESTKL+1,X + STA TMPL + LDA ESTKH+1,X + STA TMPH + LDA ESTKL,X + STA_ITMPL + INX + INX + RTS +SW: LDA ESTKL+1,X + STA TMPL + LDA ESTKH+1,X + STA TMPH + LDA ESTKL,X + STA_ITMPL + LDA ESTKH,X + STA_ITMPH + INX + INX + RTS +;* +;* STORE VALUE TO LOCAL FRAME OFFSET +;* +SLB: INC PCL + BNE SLB1 + INC PCH +SLB1: LDA_IPC + TAY + LDA ESTKL,X + STA (FRMP),Y + INX + CLRY + RTS +SLW: INC PCL + BNE SLW1 + INC PCH +SLW1: LDA_IPC + TAY + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y + INX + CLRY + RTS +;* +;* STORE VALUE TO LOCAL FRAME OFFSET WITHOUT POPPING STACK +;* +DLB: INC PCL + BNE DLB1 + INC PCH +DLB1: LDA_IPC + TAY + LDA ESTKL,X + STA (FRMP),Y + CLRY + RTS +DLW: INC PCL + BNE DLW1 + INC PCH +DLW1: LDA_IPC + TAY + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y + CLRY + RTS +;* +;* STORE VALUE TO ABSOLUTE ADDRESS +;* +SAB: INC PCL + BNE SAB1 + INC PCH +SAB1: LDA_IPC + STA TMPL + INC PCL + BNE SAB2 + INC PCH +SAB2: LDA_IPC + STA TMPH + LDA ESTKL,X + STA_ITMPL + INX + RTS +SAW: INC PCL + BNE SAW1 + INC PCH +SAW1: LDA_IPC + STA TMPL + INC PCL + BNE SAW2 + INC PCH +SAW2: LDA_IPC + STA TMPH + LDA ESTKL,X + STA_ITMPL + LDA ESTKH,X + STA_ITMPH + INX + RTS +;* +;* STORE VALUE TO ABSOLUTE ADDRESS WITHOUT POPPING STACK +;* +DAB: INC PCL + BNE DAB1 + INC PCH +DAB1: LDA_IPC + STA TMPL + INC PCL + BNE DAB2 + INC PCH +DAB2: LDA_IPC + STA TMPH + LDA ESTKL,X + STA_ITMPL + RTS +DAW: INC PCL + BNE DAW1 + INC PCH +DAW1: LDA_IPC + STA TMPL + INC PCL + BNE DAW2 + INC PCH +DAW2: LDA_IPC + STA TMPH + LDA ESTKL,X + STA_ITMPL + LDA ESTKH,X + STA_ITMPH + RTS +;* +;* COMPARES +;* +ISEQ: +.IF IS65C02 + LDY #$00 +.ENDIF + LDA ESTKL,X + CMP ESTKL+1,X + BNE ISEQ1 + LDA ESTKH,X + CMP ESTKH+1,X + BNE ISEQ1 + DEY +ISEQ1: STY ESTKL+1,X + STY ESTKH+1,X + INX + CLRY + RTS +ISNE: +.IF IS65C02 + LDY #$FF +.ELSE + DEY ; LDY #$FF +.ENDIF + LDA ESTKL,X + CMP ESTKL+1,X + BNE ISNE1 + LDA ESTKH,X + CMP ESTKH+1,X + BNE ISNE1 + INY +ISNE1: STY ESTKL+1,X + STY ESTKH+1,X + INX + CLRY + RTS +ISGE: +.IF IS65C02 + LDY #$00 +.ELSE + ; LDY #$00 +.ENDIF + LDA ESTKL+1,X + CMP ESTKL,X + LDA ESTKH+1,X + SBC ESTKH,X + BVC ISGE1 + EOR #$80 +ISGE1: BMI ISGE2 + DEY +ISGE2: STY ESTKL+1,X + STY ESTKH+1,X + INX + CLRY + RTS +ISGT: +.IF IS65C02 + LDY #$00 +.ELSE + ; LDY #$00 +.ENDIF + LDA ESTKL,X + CMP ESTKL+1,X + LDA ESTKH,X + SBC ESTKH+1,X + BVC ISGT1 + EOR #$80 +ISGT1: BPL ISGT2 + DEY +ISGT2: STY ESTKL+1,X + STY ESTKH+1,X + INX + CLRY + RTS +ISLE: +.IF IS65C02 + LDY #$00 +.ELSE + ; LDY #$00 +.ENDIF + LDA ESTKL,X + CMP ESTKL+1,X + LDA ESTKH,X + SBC ESTKH+1,X + BVC ISLE1 + EOR #$80 +ISLE1: BMI ISLE2 + DEY +ISLE2: STY ESTKL+1,X + STY ESTKH+1,X + INX + CLRY + RTS +ISLT: +.IF IS65C02 + LDY #$00 +.ELSE + ; LDY #$00 +.ENDIF + LDA ESTKL+1,X + CMP ESTKL,X + LDA ESTKH+1,X + SBC ESTKH,X + BVC ISLT1 + EOR #$80 +ISLT1: BPL ISLT2 + DEY +ISLT2: STY ESTKL+1,X + STY ESTKH+1,X + INX + CLRY + RTS +;* +;* SKIPS +;* +SKPTRU: INX + LDA ESTKH-1,X + ORA ESTKL-1,X + BEQ NOSKIP +SKIP: +.IF IS65C02 + LDY #$01 +.ELSE + INY ; LDY #$01 +.ENDIF + LDA (PC),Y + PHA + INY + LDA (PC),Y + STA PCH + PLA + STA PCL + PLA + PLA + CLRY + JMP FETCHOP +SKPFLS: INX + LDA ESTKH-1,X + ORA ESTKL-1,X + BEQ SKIP +NOSKIP: LDA #$02 + CLC + ADC PCL + STA PCL + BCC NOSK1 + INC PCH +NOSK1: RTS +SKPEQ: INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE NOSKIP + LDA ESTKL-1,X + CMP ESTKL,X + BEQ SKIP + BNE NOSKIP +SKPNE: INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE SKIP + LDA ESTKL-1,X + CMP ESTKL,X + BEQ NOSKIP + BNE SKIP +SKPGT: INX + LDA ESTKL-1,X + CMP ESTKL,X + LDA ESTKH-1,X + SBC ESTKH,X + BMI SKIP + BPL NOSKIP +SKPLT: INX + LDA ESTKL,X + CMP ESTKL-1,X + LDA ESTKH,X + SBC ESTKH-1,X + BMI SKIP + BPL NOSKIP +;* +;* INDIRECT SKIP TO ADDRESS +;* +ISKIP: PLA + PLA + LDA ESTKL,X + STA PCL + LDA ESTKH,X + STA PCH + INX + JMP FETCHOP +;* +;* EXTERNAL SYS CALL +;* +INT: INC PCL + BNE INT1 + INC PCH +INT1: LDA_IPC + JSR INTJMP + CLRY + RTS +;* +;* CALL INTO ABSOLUTE ADDRESS (NATIVE CODE) +;* +CALL: INC PCL + BNE CALL1 + INC PCH +CALL1: LDA_IPC + STA TMPL + INC PCL + BNE CALL2 + INC PCH +CALL2: LDA_IPC + STA TMPH + LDA PCH + PHA + LDA PCL + PHA + JSR TMPJMP + PLA + STA PCL + PLA + STA PCH + CLRY + RTS +;* +;* INDIRECT CALL TO ADDRESS (NATIVE CODE) +;* +ICAL: LDA ESTKL,X + STA TMPL + LDA ESTKH,X + STA TMPH + INX + LDA PCH + PHA + LDA PCL + PHA + JSR TMPJMP + PLA + STA PCL + PLA + STA PCH + CLRY + RTS +;* +;* ENTER FUNCTION WITH FRAME SIZE AND PARAM COUNT +;* +_ENTER: STY FRMSZ + JMP ENTER3 +ENTER: INC PCL + BNE ENTER1 + INC PCH +ENTER1: LDA_IPC + STA FRMSZ + INC PCL + BNE ENTER2 + INC PCH +ENTER2: LDA_IPC +ENTER3: STA NPARMS + LDA FRMPL + PHA + SEC + SBC FRMSZ + STA FRMPL + LDA FRMPH + PHA + SBC #$00 + STA FRMPH + LDY #$01 + PLA + STA (FRMP),Y + DEY + PLA + STA (FRMP),Y + LDA NPARMS + BEQ ENTER5 + ASL + TAY + INY +ENTER4: LDA ESTKH,X + STA (FRMP),Y + DEY + LDA ESTKL,X + STA (FRMP),Y + DEY + INX + DEC TMPL + BNE ENTER4 +ENTER5: LDY #$00 + RTS +;* +;* LEAVE FUNCTION +;* +LEAVE: PLA + PLA +_LEAVE: LDY #$01 + LDA (FRMP),Y + DEY + PHA + LDA (FRMP),Y + STA FRMPL + PLA + STA FRMPH + RTS +RET: PLA + PLA + RTS +;*********************************************** +;* +;* XMOD VERSIONS OF BYTECODE OPS +;* +;*********************************************** +;* +;* CONSTANT +;* +CBX: DEX + INC PCL + BNE CBX1 + INC PCH +CBX1: AUXMEM_RDACCESS_ON + LDA_IPC + AUXMEM_RDACCESS_OFF + STA ESTKL,X + STY ESTKH,X + RTS +;* +;* LOAD ADDRESS +;* +LAX: +CWX: DEX + INC PCL + BNE CWX1 + INC PCH +CWX1: AUXMEM_RDACCESS_ON + LDA_IPC + STA ESTKL,X + INC PCL + BNE CWX2 + INC PCH +CWX2: LDA_IPC + AUXMEM_RDACCESS_OFF + STA ESTKH,X + RTS +;* +;* LOAD ADDRESS OF LOCAL FRAME OFFSET +;* +LLAX: INC PCL + BNE LLAX1 + INC PCH +LLAX1: AUXMEM_RDACCESS_ON + LDA_IPC + AUXMEM_RDACCESS_OFF + DEX + CLC + ADC FRMPL + STA ESTKL,X + LDA0 + ADC FRMPH + STA ESTKH,X + RTS +;* +;* LOAD VALUE FROM LOCAL FRAME OFFSET +;* +LLBX: INC PCL + BNE LLBX1 + INC PCH +LLBX1: AUXMEM_RDACCESS_ON + LDA_IPC + AUXMEM_RDACCESS_OFF + TAY + DEX + LDA (FRMP),Y + STA ESTKL,X + CLRY + ST0 {ESTKH,X} + RTS +LLWX: INC PCL + BNE LLWX1 + INC PCH +LLWX1: AUXMEM_RDACCESS_ON + LDA_IPC + AUXMEM_RDACCESS_OFF + TAY + DEX + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + CLRY + RTS +;* +;* LOAD VALUE FROM ABSOLUTE ADDRESS +;* +LABX: INC PCL + BNE LABX1 + INC PCH +LABX1: AUXMEM_RDACCESS_ON + LDA_IPC + STA TMPL + INC PCL + BNE LABX2 + INC PCH +LABX2: LDA_IPC + AUXMEM_RDACCESS_OFF + STA TMPH + DEX + LDA_ITMPL + STA ESTKL,X + ST0 {ESTKH,X} + RTS +LAWX: INC PC + BNE LAWX1 + INC PCH +LAWX1: AUXMEM_RDACCESS_ON + LDA_IPC + STA TMPL + INC PCL + BNE LAWX2 + INC PCH + DEX +LAWX2: LDA_IPC + STA TMPH + LDA_ITMPL + STA ESTKL,X + LDA_ITMPH + AUXMEM_RDACCESS_OFF + STA ESTKH,X + RTS +;* +;* STORE VALUE TO LOCAL FRAME OFFSET +;* +SLBX: INC PCL + BNE SLBX1 + INC PCH +SLBX1: AUXMEM_RDACCESS_ON + LDA_IPC + AUXMEM_RDACCESS_OFF + TAY + LDA ESTKL,X + STA (FRMP),Y + INX + CLRY + RTS +SLWX: INC PCL + BNE SLWX1 + INC PCH +SLWX1: AUXMEM_RDACCESS_ON + LDA_IPC + AUXMEM_RDACCESS_OFF + TAY + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y + INX + CLRY + RTS +;* +;* STORE VALUE TO LOCAL FRAME OFFSET WITHOUT POPPING STACK +;* +DLBX: INC PCL + BNE DLBX1 + INC PCH +DLBX1: AUXMEM_RDACCESS_ON + LDA_IPC + AUXMEM_RDACCESS_OFF + TAY + LDA ESTKL,X + STA (FRMP),Y + CLRY + RTS +DLWX: INC PCL + BNE DLWX1 + INC PCH +DLWX1: AUXMEM_RDACCESS_ON + LDA_IPC + AUXMEM_RDACCESS_OFF + TAY + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y + CLRY + RTS +;* +;* STORE VALUE TO ABSOLUTE ADDRESS +;* +SABX: INC PCL + BNE SABX1 + INC PCH +SABX1: AUXMEM_RDACCESS_ON + LDA_IPC + STA TMPL + INC PCL + BNE SABX2 + INC PCH +SABX2: LDA_IPC + AUXMEM_RDACCESS_OFF + STA TMPH + LDA ESTKL,X + STA_ITMPL + INX + RTS +SAWX: INC PCL + BNE SAWX1 + INC PCH +SAWX1: AUXMEM_RDACCESS_ON + LDA_IPC + STA TMPL + INC PCL + BNE SAWX2 + INC PCH +SAWX2: LDA_IPC + AUXMEM_RDACCESS_OFF + STA TMPH + LDA ESTKL,X + STA_ITMPL + LDA ESTKH,X + STA_ITMPH + INX + RTS +;* +;* STORE VALUE TO ABSOLUTE ADDRESS WITHOUT POPPING STACK +;* +DABX: INC PCL + BNE DABX1 + INC PCH +DABX1: AUXMEM_RDACCESS_ON + LDA_IPC + STA TMPL + INC PCL + BNE DABX2 + INC PCH +DABX2: LDA_IPC + AUXMEM_RDACCESS_OFF + STA TMPH + LDA ESTKL,X + STA_ITMPL + RTS +DAWX: INC PCL + BNE DAWX1 + INC PCH +DAWX1: AUXMEM_RDACCESS_ON + LDA_IPC + STA TMPL + INC PCL + BNE DAWX2 + INC PCH +DAWX2: LDA_IPC + AUXMEM_RDACCESS_OFF + STA TMPH + LDA ESTKL,X + STA_ITMPL + LDA ESTKH,X + STA_ITMPH + RTS +;* +;* SKIPS +;* +SKPTRUX: INX + LDA ESTKH-1,X + ORA ESTKL-1,X + BEQ NOSKIPX +SKIPX: +.IF IS65C02 + LDY #$01 +.ELSE + INY ; LDY #$01 +.ENDIF + AUXMEM_RDACCESS_ON + LDA_IPC + PHA + INY + LDA_IPC + AUXMEM_RDACCESS_OFF + STA PCH + PLA + STA PCL + PLA + PLA + CLRY + CLRY + JMP FETCHOPX +SKPFLSX: INX + LDA ESTKH-1,X + ORA ESTKL-1,X + BEQ SKIPX +NOSKIPX: LDA #$02 + CLC + ADC PCL + STA PCL + BCC NOSKX1 + INC PCH +NOSKX1: RTS +SKPEQX: INX + ; INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE NOSKIPX + LDA ESTKL-1,X + CMP ESTKL,X + BEQ SKIPX + BNE NOSKIPX +SKPNEX: INX + ; INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE SKIPX + LDA ESTKL-1,X + CMP ESTKL,X + BEQ NOSKIPX + BNE SKIPX +SKPGTX: INX + ; INX + LDA ESTKL-1,X + CMP ESTKL,X + LDA ESTKH-1,X + SBC ESTKH,X + BMI SKIPX + BPL NOSKIPX +SKPLTX: INX + ; INX + LDA ESTKL,X + CMP ESTKL-1,X + LDA ESTKH,X + SBC ESTKH-1,X + BMI SKIPX + BPL NOSKIPX +;* +;* INDIRECT SKIP TO ADDRESS +;* +ISKIPX: PLA + PLA + LDA ESTKL,X + STA PCL + LDA ESTKH,X + STA PCH + INX + JMP FETCHOPX +;* +;* EXTERNAL SYS CALL +;* +INTX: INC PCL + BNE INTX1 + INC PCH +INTX1: AUXMEM_RDACCESS_ON + LDA_IPC + AUXMEM_RDACCESS_OFF + JSR INTJMP + CLRY + RTS +;* +;* CALL TO ABSOLUTE ADDRESS (NATIVE CODE) +;* +CALLX: INC PCL + BNE CALLX1 + INC PCH +CALLX1: AUXMEM_RDACCESS_ON + LDA_IPC + STA TMPL + INC PCL + BNE CALLX2 + INC PCH +CALLX2: LDA_IPC + AUXMEM_RDACCESS_OFF + STA TMPH + LDA PCH + PHA + LDA PCL + PHA + JSR TMPJMP + PLA + STA PCL + PLA + STA PCH + CLRY + RTS diff --git a/plasma3/a.out b/plasma3/a.out new file mode 100755 index 0000000..d8e59eb Binary files /dev/null and b/plasma3/a.out differ diff --git a/plasma3/acme b/plasma3/acme new file mode 100755 index 0000000..30a4cf9 --- /dev/null +++ b/plasma3/acme @@ -0,0 +1,16 @@ +; ACME COMPATIBLE OUTPUT +; 1: byte a +D0000 !FILL 1 ; a +; 2: +; 3: def add(b) +C0000 ; add() + ; b = 2 +; 4: return a + b + DB $58,$04,$01 ; ENTER 4,1 + DB $68,>D0000, +#include "tokens.h" +#include "symbols.h" +#include "codegen.h" +/* + * Symbol table and fixup information. + */ +static int consts = 0; +static int externs = 0; +static int globals = 0; +static int locals = 0; +static int defs = 0; +static int codetags = 0; +static int fixups = 0; +static char idconst_name[1024][17]; +static int idconst_value[1024]; +static char idglobal_name[1024][17]; +static int idglobal_type[1024]; +static int idglobal_tag[1024]; +static int localsize = 0; +static char idlocal_name[128][17]; +static int idlocal_type[128]; +static int idlocal_offset[128]; +static char fixup_size[255]; +static int fixup_type[255]; +static int fixup_tag[255]; +#define FIXUP_BYTE 0x00 +#define FIXUP_WORD 0x80 +int id_match(char *name, int len, char *id) +{ + if (len == id[0]) + { + if (len > 16) len = 16; + while (len--) + { + if (name[len] != id[1 + len]) + return (0); + } + return (1); + } + return (0); +} +int idconst_lookup(char *name, int len) +{ + int i; + for (i = 0; i < consts; i++) + if (id_match(name, len, &(idconst_name[i][0]))) + return (i); + return (-1); +} +int idlocal_lookup(char *name, int len) +{ + int i; + for (i = 0; i < locals; i++) + if (id_match(name, len, &(idlocal_name[i][0]))) + return (i); + return (-1); +} +int idglobal_lookup(char *name, int len) +{ + int i; + for (i = 0; i < globals; i++) + if (id_match(name, len, &(idglobal_name[i][0]))) + return (i); + return (-1); +} +int idconst_add(char *name, int len, int value) +{ + if (consts > 1024) + { + printf("Constant count overflow\n"); + return (0); + } + char c = name[len]; + name[len] = '\0'; + emit_idconst(name, value); + name[len] = c; + idconst_name[consts][0] = len; + if (len > 16) len = 16; + while (len--) + idconst_name[consts][1 + len] = name[len]; + idconst_value[consts] = value; + consts++; + return (1); +} +int idlocal_add(char *name, int len, int type, int size) +{ + if (localsize > 255) + { + printf("Local variable size overflow\n"); + return (0); + } + char c = name[len]; + name[len] = '\0'; + emit_idlocal(name, localsize); + name[len] = c; + idlocal_name[locals][0] = len; + if (len > 16) len = 16; + while (len--) + idlocal_name[locals][1 + len] = name[len]; + idlocal_type[locals] = type | LOCAL_TYPE; + idlocal_offset[locals] = localsize; + localsize += size; + locals++; + return (1); +} +int idglobal_add(char *name, int len, int type, int size) +{ + if (globals > 1024) + { + printf("Global variable count overflow\n"); + return (0); + } + char c = name[len]; + name[len] = '\0'; + name[len] = c; + idglobal_name[globals][0] = len; + if (len > 16) len = 16; + while (len--) + idglobal_name[globals][1 + len] = name[len]; + idglobal_type[globals] = type; + if (!(type & EXTERN_TYPE)) + { + emit_idglobal(globals, size, name); + idglobal_tag[globals] = globals++; + } + else + { + printf("\t\t\t\t\t; %s -> X%03d\n", &idglobal_name[globals][1], externs); + idglobal_tag[globals++] = externs++; + } + return (1); +} +int id_add(char *name, int len, int type, int size) +{ + return ((type & LOCAL_TYPE) ? idlocal_add(name, len, type, size) : idglobal_add(name, len, type, size)); +} +int idfunc_add(char *name, int len, int type, int tag) +{ + if (globals > 1024) + { + printf("Global variable count overflow\n"); + return (0); + } + idglobal_name[globals][0] = len; + if (len > 16) len = 16; + while (len--) + idglobal_name[globals][1 + len] = name[len]; + idglobal_type[globals] = type; + idglobal_tag[globals++] = tag; + if (type & EXTERN_TYPE) + printf("\t\t\t\t\t; %s -> X%03d\n", &idglobal_name[globals - 1][1], tag); + return (1); +} +int idfunc_set(char *name, int len, int type) +{ + int i; + if (((i = idglobal_lookup(name, len)) >= 0) && (idglobal_type[i] & FUNC_TYPE)) + { + idglobal_type[i] = type; + return (idglobal_type[i]); + } + parse_error("Undeclared identifier"); + return (0); +} +void idglobal_size(int type, int size, int constsize) +{ + if (size > constsize) + emit_data(0, 0, 0, size - constsize); + else if (size) + emit_data(0, 0, 0, size); +} +int idlocal_size(void) +{ + return (localsize); +} +void idlocal_reset(void) +{ + locals = 0; + localsize = 2; +} +int id_tag(char *name, int len) +{ + int i; + if ((i = idlocal_lookup(name, len)) >= 0) + return (idlocal_offset[i]); + if ((i = idglobal_lookup(name, len)) >= 0) + return (idglobal_tag[i]); + parse_error("Undeclared identifier"); + return (-1); +} +int id_const(char *name, int len) +{ + int i; + if ((i = idconst_lookup(name, len)) >= 0) + return (idconst_value[i]); + parse_error("Undeclared constant"); + return (0); +} +int id_type(char *name, int len) +{ + int i; + if ((i = idconst_lookup(name, len)) >= 0) + return (CONST_TYPE); + if ((i = idlocal_lookup(name, len)) >= 0) + return (idlocal_type[i] | LOCAL_TYPE); + if ((i = idglobal_lookup(name, len)) >= 0) + return (idglobal_type[i]); + parse_error("Undeclared identifier"); + return (0); +} +int tag_new(int type) +{ + if (type & EXTERN_TYPE) + return (externs++); + if (type & ASM_TYPE) + return (globals); + if (type & DEF_TYPE) + return (defs++); + if (type & BRANCH_TYPE) + return (codetags++); + return globals++; +} +int fixup_new(int tag, int type, int size) +{ + if (fixups > 255) + { + printf("External variable count overflow\n"); + return (0); + } + fixup_tag[fixups] = tag; + fixup_type[fixups] = type; + fixup_size[fixups] = size; + return (fixups++); +} +/* + * Emit assembly code. + */ +#define BYTECODE_SEG 2 +static int outflags = 0; +static char *DB = ".BYTE"; +static char *DW = ".WORD"; +static char *DS = ".RES"; +static char LBL = ':'; +char *tag_string(int tag, int type) +{ + static char str[16]; + char t; + + if (type & EXTERN_TYPE) + t = 'X'; + else if (type & DEF_TYPE) + t = 'C'; + else if (type & ASM_TYPE) + t = 'A'; + else if (type & BRANCH_TYPE) + t = 'B'; + else + t = 'D'; + sprintf(str, "_%c%03d", t, tag); + return str; +} +void emit_flags(int flags) +{ + outflags = flags; + if (outflags & ACME) + { + DB = "!BYTE"; + DW = "!WORD"; + DS = "!FILL"; + LBL = ' '; + } +} +void emit_header(void) +{ + if (outflags & ACME) + printf("; ACME COMPATIBLE OUTPUT\n"); + else + printf("; CA65 COMPATIBLE OUTPUT\n"); + printf("_SEGBEGIN%c\n", LBL); + printf("\t%s\t_SEGEND-_SEGBEGIN\t; LENGTH OF HEADER + CODE/DATA + BYTECODE SEGMENT\n", DW); + printf("\t%s\t$DA7E\t\t\t; MAGIC #\n", DW); + printf("\t%s\t_SUBSEG\t\t\t; BYTECODE SUB-SEGMENT\n", DW); +} +void emit_trailer(void) +{ + if (!(outflags & BYTECODE_SEG)) + emit_bytecode_seg(); + printf("_SEGEND%c\n", LBL); +} +char *supper(char *s) +{ + static char su[80]; + int i; + for (i = 0; s[i]; i++) + su[i] = toupper(s[i]); + su[i] = '\0'; + return su; +} +void emit_dci(char *str, int len) +{ + if (len--) + { + printf("\t; DCI STRING: %s\n", supper(str)); + printf("\t%s\t$%02X", DB, toupper(*str++) | (len ? 0x80 : 0x00)); + while (len--) + printf(",$%02X", toupper(*str++) | (len ? 0x80 : 0x00)); + printf("\n"); + } +} +void emit_moddep(char *name, int len) +{ + if (name) + emit_dci(name, len); + else + printf("\t%s\t$00\t\t\t; END OF MODULE DEPENDENCIES\n", DB); +} +void emit_bytecode_seg(void) +{ + if (!(outflags & BYTECODE_SEG)) + printf("_SUBSEG%c\t\t\t\t; BYTECODE STARTS\n", LBL); + outflags |= BYTECODE_SEG; +} +void emit_comment(char *s) +{ + printf("\t\t\t\t\t; %s\n", s); +} +void emit_asm(char *s) +{ + printf("%s\n", s); +} +void emit_idlocal(char *name, int value) +{ + printf("\t\t\t\t\t; %s -> [%d]\n", name, value); +} +void emit_idglobal(int tag, int size, char *name) +{ + if (size == 0) + printf("_D%03d%c\t\t\t\t\t; %s\n", tag, LBL, name); + else + printf("_D%03d%c\t%s\t%d\t\t\t; %s\n", tag, LBL, DS, size, name); +} +void emit_idfunc(int tag, int type, char *name) +{ + printf("%s%c\t\t\t\t\t; %s()\n", tag_string(tag, type), LBL, name); +} +void emit_idconst(char *name, int value) +{ + printf("\t\t\t\t\t; %s = %d\n", name, value); +} +int emit_data(int vartype, int consttype, long constval, int constsize) +{ + int datasize, i; + char *str; + if (consttype == 0) + { + datasize = constsize; + printf("\t%s\t$%02X\n", DS, constsize); + } + else if (consttype & STRING_TYPE) + { + datasize = constsize; + str = (char *)constval; + printf("\t%s\t$%02X\n", DB, --constsize); + while (constsize-- > 0) + { + printf("\t%s\t$%02X", DB, *str++); + for (i = 0; i < 7; i++) + { + if (constsize-- > 0) + printf(",$%02X", *str++); + else + break; + } + printf("\n"); + } + } + else if (consttype & ADDR_TYPE) + { + if (vartype == WORD_TYPE) + { + int fixup = fixup_new(constval, consttype, FIXUP_WORD); + datasize = 2; + if (consttype & EXTERN_TYPE) + printf("_F%03d%c\t%s\t0\t\t\t; %s\n", fixup, LBL, DW, tag_string(constval, consttype)); + else + printf("_F%03d%c\t%s\t%s\n", fixup, LBL, DW, tag_string(constval, consttype)); + } + else + { + int fixup = fixup_new(constval, consttype, FIXUP_BYTE); + datasize = 1; + if (consttype & EXTERN_TYPE) + printf("_F%03d%c\t%s\t0\t\t\t; %s\n", fixup, LBL, DB, tag_string(constval, consttype)); + else + printf("_F%03d%c\t%s\t%s\n", fixup, LBL, DB, tag_string(constval, consttype)); + } + } + else + { + if (vartype == WORD_TYPE) + { + datasize = 2; + printf("\t%s\t$%04lX\n", DW, constval & 0xFFFF); + } + else + { + datasize = 1; + printf("\t%s\t$%02lX\n", DB, constval & 0xFF); + } + } + return (datasize); +} +void emit_codetag(int tag) +{ + printf("_B%03d%c\n", tag, LBL); +} +void emit_const(int cval) +{ + if (cval == 0) + printf("\t%s\t$00\t\t\t; ZERO\n", DB); + else if (cval > 0 && cval < 256) + printf("\t%s\t$2A,$%02X\t\t\t; CB\t%d\n", DB, cval, cval); + else + printf("\t%s\t$2C,$%02X,$%02X\t\t; CW\t%d\n", DB, cval&0xFF,(cval>>8)&0xFF, cval); +} +void emit_lb(void) +{ + printf("\t%s\t$60\t\t\t; LB\n", DB); +} +void emit_lw(void) +{ + printf("\t%s\t$62\t\t\t; LW\n", DB); +} +void emit_llb(int index) +{ + printf("\t%s\t$64,$%02X\t\t\t; LLB\t[%d]\n", DB, index, index); +} +void emit_llw(int index) +{ + printf("\t%s\t$66,$%02X\t\t\t; LLW\t[%d]\n", DB, index, index); +} +void emit_lab(int tag, int type) +{ + int fixup = fixup_new(tag, type, FIXUP_WORD); + char *taglbl = tag_string(tag, type); + printf("\t%s\t$68\t\t\t; LAB\t%s\n", DB, taglbl); + printf("_F%03d%c\t%s\t%s\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl); +} +void emit_law(int tag, int type) +{ + int fixup = fixup_new(tag, type, FIXUP_WORD); + char *taglbl = tag_string(tag, type); + printf("\t%s\t$6A\t\t\t; LAW\t%s\n", DB, taglbl); + printf("_F%03d%c\t%s\t%s\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl); +} +void emit_sb(void) +{ + printf("\t%s\t$70\t\t\t; SB\n", DB); +} +void emit_sw(void) +{ + printf("\t%s\t$72\t\t\t; SW\n", DB); +} +void emit_slb(int index) +{ + printf("\t%s\t$74,$%02X\t\t\t; SLB\t[%d]\n", DB, index, index); +} +void emit_slw(int index) +{ + printf("\t%s\t$76,$%02X\t\t\t; SLW\t[%d]\n", DB, index, index); +} +void emit_dlb(int index) +{ + printf("\t%s\t$6C,$%02X\t\t\t; DLB\t[%d]\n", DB, index, index); +} +void emit_dlw(int index) +{ + printf("\t%s\t$6E,$%02X\t\t\t; DLW\t[%d]\n", DB, index, index); +} +void emit_sab(int tag, int type) +{ + int fixup = fixup_new(tag, type, FIXUP_WORD); + char *taglbl = tag_string(tag, type); + printf("\t%s\t$78\t\t\t; SAB\t%s\n", DB, taglbl); + printf("_F%03d%c\t%s\t%s\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl); +} +void emit_saw(int tag, int type) +{ + int fixup = fixup_new(tag, type, FIXUP_WORD); + char *taglbl = tag_string(tag, type); + printf("\t%s\t$7A\t\t\t; SAW\t%s\n", DB, taglbl); + printf("_F%03d%c\t%s\t%s\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl); +} +void emit_dab(int tag, int type) +{ + int fixup = fixup_new(tag, type, FIXUP_WORD); + char *taglbl = tag_string(tag, type); + printf("\t%s\t$7C\t\t\t; DAB\t%s\n", DB, taglbl); + printf("_F%03d%c\t%s\t%s\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl); +} +void emit_daw(int tag, int type) +{ + int fixup = fixup_new(tag, type, FIXUP_WORD); + char *taglbl = tag_string(tag, type); + printf("\t%s\t$7E\t\t\t; DAW\t%s\n", DB, taglbl); + printf("_F%03d%c\t%s\t%s\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl); +} +void emit_localaddr(int index) +{ + printf("\t%s\t$28,$%02X\t\t\t; LLA\t[%d]\n", DB, index, index); +} +void emit_globaladdr(int tag, int type) +{ + int fixup = fixup_new(tag, type, FIXUP_WORD); + char *taglbl = tag_string(tag, type); + printf("\t%s\t$26\t\t\t; LA\t%s\n", DB, taglbl); + printf("_F%03d%c\t%s\t%s\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl); +} +void emit_globaladdrofst(int tag, int ofst, int type) +{ + int fixup = fixup_new(tag, type, FIXUP_WORD); + char *taglbl = tag_string(tag, type); + printf("\t%s\t$26\t\t\t; LA\t%s+%d\n", DB, taglbl, ofst); + printf("_F%03d%c\t%s\t%s+%d\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "" : taglbl, ofst); +} +void emit_indexbyte(void) +{ + printf("\t%s\t$02\t\t\t; IDXB\n", DB); +} +void emit_indexword(void) +{ + printf("\t%s\t$1E\t\t\t; IDXW\n", DB); +} +void emit_brfls(int tag) +{ + printf("\t%s\t$4C\t\t\t; BRFLS\t_B%03d\n", DB, tag); + printf("\t%s\t_B%03d-*\n", DW, tag); +} +void emit_brtru(int tag) +{ + printf("\t%s\t$4E\t\t\t; BRTRU\t_B%03d\n", DB, tag); + printf("\t%s\t_B%03d-*\n", DW, tag); +} +void emit_brnch(int tag) +{ + printf("\t%s\t$50\t\t\t; BRNCH\t_B%03d\n", DB, tag); + printf("\t%s\t_B%03d-*\n", DW, tag); +} +void emit_breq(int tag) +{ + printf("\t%s\t$3C\t\t\t; BREQ\t_B%03d\n", DB, tag); + printf("\t%s\t_B%03d-*\n", DW, tag); +} +void emit_brne(int tag) +{ + printf("\t%s\t$3E\t\t\t; BRNE\t_B%03d\n", DB, tag); + printf("\t%s\t_B%03d-*\n", DW, tag); +} +void emit_brlt(int tag) +{ + printf("\t%s\t$38\t\t\t; BRLT\t_B%03d\n", DB, tag); + printf("\t%s\t_B%03d-*\n", DW, tag); +} +void emit_brgt(int tag) +{ + printf("\t%s\t$3A\t\t\t; BRGT\t_B%03d\n", DB, tag); + printf("\t%s\t_B%03d-*\n", DW, tag); +} +void emit_call(int tag, int type) +{ + int fixup = fixup_new(tag, type, FIXUP_WORD); + char *taglbl = tag_string(tag, type); + printf("\t%s\t$54\t\t\t; CALL\t%s\n", DB, taglbl); + printf("_F%03d%c\t%s\t%s\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl); +} +void emit_ical(void) +{ + printf("\t%s\t$56\t\t\t; ICAL\n", DB); +} +void emit_leave(int framesize) +{ + if (framesize > 2) + printf("\t%s\t$5A\t\t\t; LEAVE\n", DB); + else + printf("\t%s\t$5C\t\t\t; RET\n", DB); +} +void emit_ret(void) +{ + printf("\t%s\t$5C\t\t\t; RET\n", DB); +} +void emit_def(int defopt) +{ +} +void emit_enter(int framesize, int cparams) +{ + if (framesize > 2) + printf("\t%s\t$58,$%02X,$%02X\t\t; ENTER\t%d,%d\n", DB, framesize, cparams, framesize, cparams); +} +void emit_start(void) +{ +} +void emit_dup(void) +{ + printf("\t%s\t$32\t\t\t; DUP\n", DB); +} +void emit_push(void) +{ + printf("\t%s\t$34\t\t\t; PUSH\n", DB); +} +void emit_pull(void) +{ + printf("\t%s\t$36\t\t\t; PULL\n", DB); +} +void emit_swap(void) +{ + printf("\t%s\t$2E\t\t\t; SWAP\n", DB); +} +void emit_drop(void) +{ + printf("\t%s\t$30\t\t\t; DROP\n", DB); +} +int emit_unaryop(int op) +{ + switch (op) + { + case NEG_TOKEN: + printf("\t%s\t$10\t\t\t; NEG\n", DB); + break; + case COMP_TOKEN: + printf("\t%s\t$12\t\t\t; COMP\n", DB); + break; + case LOGIC_NOT_TOKEN: + printf("\t%s\t$20\t\t\t; NOT\n", DB); + break; + case INC_TOKEN: + printf("\t%s\t$0C\t\t\t; INCR\n", DB); + break; + case DEC_TOKEN: + printf("\t%s\t$0E\t\t\t; DECR\n", DB); + break; + case BPTR_TOKEN: + emit_lb(); + break; + case WPTR_TOKEN: + emit_lw(); + break; + default: + printf("emit_unaryop(%c) ???\n", op & 0x7F); + return (0); + } + return (1); +} +int emit_op(t_token op) +{ + switch (op) + { + case MUL_TOKEN: + printf("\t%s\t$06\t\t\t; MUL\n", DB); + break; + case DIV_TOKEN: + printf("\t%s\t$08\t\t\t; DIV\n", DB); + break; + case MOD_TOKEN: + printf("\t%s\t$0A\t\t\t; MOD\n", DB); + break; + case ADD_TOKEN: + printf("\t%s\t$02\t\t\t; ADD\n", DB); + break; + case SUB_TOKEN: + printf("\t%s\t$04\t\t\t; SUB\n", DB); + break; + case SHL_TOKEN: + printf("\t%s\t$1A\t\t\t; SHL\n", DB); + break; + case SHR_TOKEN: + printf("\t%s\t$1C\t\t\t; SHR\n", DB); + break; + case AND_TOKEN: + printf("\t%s\t$14\t\t\t; AND\n", DB); + break; + case OR_TOKEN: + printf("\t%s\t$16\t\t\t; IOR\n", DB); + break; + case EOR_TOKEN: + printf("\t%s\t$18\t\t\t; XOR\n", DB); + break; + case EQ_TOKEN: + printf("\t%s\t$40\t\t\t; ISEQ\n", DB); + break; + case NE_TOKEN: + printf("\t%s\t$42\t\t\t; ISNE\n", DB); + break; + case GE_TOKEN: + printf("\t%s\t$48\t\t\t; ISGE\n", DB); + break; + case LT_TOKEN: + printf("\t%s\t$46\t\t\t; ISLT\n", DB); + break; + case GT_TOKEN: + printf("\t%s\t$44\t\t\t; ISGT\n", DB); + break; + case LE_TOKEN: + printf("\t%s\t$4A\t\t\t; ISLE\n", DB); + break; + case LOGIC_OR_TOKEN: + printf("\t%s\t$22\t\t\t; LOR\n", DB); + break; + case LOGIC_AND_TOKEN: + printf("\t%s\t$24\t\t\t; LAND\n", DB); + break; + case COMMA_TOKEN: + break; + default: + return (0); + } + return (1); +} +void emit_rld(void) +{ + int i; + + printf(";\n; RE-LOCATEABLE DICTIONARY\n;\n"); + /* + * First emit the bytecode definition entrypoint information. + */ + for (i = 0; i < globals; i++) + if (!(idglobal_type[i] & EXTERN_TYPE) && (idglobal_type[i] & DEF_TYPE)) + { + printf("\t%s\t$02\t\t\t; CODE TABLE FIXUP\n", DB); + printf("\t%s\t_C%03d\t\t\n", DW, idglobal_tag[i]); + printf("\t%s\t$00\n", DB); + } + /* + * Now emit the fixup table. + */ + for (i = 0; i < fixups; i++) + { + if (fixup_type[i] & EXTERN_TYPE) + { + printf("\t%s\t$%02X\t\t\t; EXTERNAL FIXUP\n", DB, 0x11 + fixup_size[i]); + printf("\t%s\t_F%03d\t\t\n", DW, i); + printf("\t%s\t%d\t\t\t; ESD INDEX\n", DB, fixup_tag[i]); + } + else + { + printf("\t%s\t$%02X\t\t\t; INTERNAL FIXUP\n", DB, 0x01 + fixup_size[i]); + printf("\t%s\t_F%03d\t\t\n", DW, i); + printf("\t%s\t$00\n", DB); + } + } + printf("\t%s\t$00\t\t\t; END OF RLD\n", DB); +} +void emit_esd(void) +{ + int i; + + printf(";\n; EXTERNAL/ENTRY SYMBOL DICTIONARY\n;\n"); + for (i = 0; i < globals; i++) + { + if (idglobal_type[i] & EXTERN_TYPE) + { + emit_dci(&idglobal_name[i][1], idglobal_name[i][0]); + printf("\t%s\t$10\t\t\t; EXTERNAL SYMBOL FLAG\n", DB); + printf("\t%s\t%d\t\t\t; ESD INDEX\n", DW, idglobal_tag[i]); + } + else if (idglobal_type[i] & EXPORT_TYPE) + { + emit_dci(&idglobal_name[i][1], idglobal_name[i][0]); + printf("\t%s\t$08\t\t\t; ENTRY SYMBOL FLAG\n", DB); + printf("\t%s\t%s\t\t\n", DW, tag_string(idglobal_tag[i], idglobal_type[i])); + } + } + printf("\t%s\t$00\t\t\t; END OF ESD\n", DB); +} \ No newline at end of file diff --git a/plasma3/codegen.c~ b/plasma3/codegen.c~ new file mode 100755 index 0000000..e0c2835 --- /dev/null +++ b/plasma3/codegen.c~ @@ -0,0 +1,775 @@ +#include +#include "tokens.h" +#include "symbols.h" +#include "codegen.h" +/* + * Symbol table and fixup information. + */ +static int consts = 0; +static int externs = 0; +static int globals = 0; +static int locals = 0; +static int defs = 0; +static int codetags = 0; +static int fixups = 0; +static char idconst_name[1024][17]; +static int idconst_value[1024]; +static char idglobal_name[1024][17]; +static int idglobal_type[1024]; +static int idglobal_tag[1024]; +static int localsize = 0; +static char idlocal_name[128][17]; +static int idlocal_type[128]; +static int idlocal_offset[128]; +static char fixup_size[255]; +static int fixup_type[255]; +static int fixup_tag[255]; +#define FIXUP_BYTE 0x00 +#define FIXUP_WORD 0x80 +int id_match(char *name, int len, char *id) +{ + if (len == id[0]) + { + if (len > 16) len = 16; + while (len--) + { + if (name[len] != id[1 + len]) + return (0); + } + return (1); + } + return (0); +} +int idconst_lookup(char *name, int len) +{ + int i; + for (i = 0; i < consts; i++) + if (id_match(name, len, &(idconst_name[i][0]))) + return (i); + return (-1); +} +int idlocal_lookup(char *name, int len) +{ + int i; + for (i = 0; i < locals; i++) + if (id_match(name, len, &(idlocal_name[i][0]))) + return (i); + return (-1); +} +int idglobal_lookup(char *name, int len) +{ + int i; + for (i = 0; i < globals; i++) + if (id_match(name, len, &(idglobal_name[i][0]))) + return (i); + return (-1); +} +int idconst_add(char *name, int len, int value) +{ + if (consts > 1024) + { + printf("Constant count overflow\n"); + return (0); + } + char c = name[len]; + name[len] = '\0'; + emit_idconst(name, value); + name[len] = c; + idconst_name[consts][0] = len; + if (len > 16) len = 16; + while (len--) + idconst_name[consts][1 + len] = name[len]; + idconst_value[consts] = value; + consts++; + return (1); +} +int idlocal_add(char *name, int len, int type, int size) +{ + if (localsize > 255) + { + printf("Local variable size overflow\n"); + return (0); + } + char c = name[len]; + name[len] = '\0'; + emit_idlocal(name, localsize); + name[len] = c; + idlocal_name[locals][0] = len; + if (len > 16) len = 16; + while (len--) + idlocal_name[locals][1 + len] = name[len]; + idlocal_type[locals] = type | LOCAL_TYPE; + idlocal_offset[locals] = localsize; + localsize += size; + locals++; + return (1); +} +int idglobal_add(char *name, int len, int type, int size) +{ + if (globals > 1024) + { + printf("Global variable count overflow\n"); + return (0); + } + char c = name[len]; + name[len] = '\0'; + name[len] = c; + idglobal_name[globals][0] = len; + if (len > 16) len = 16; + while (len--) + idglobal_name[globals][1 + len] = name[len]; + idglobal_type[globals] = type; + if (!(type & EXTERN_TYPE)) + { + emit_idglobal(globals, size, name); + idglobal_tag[globals] = globals++; + } + else + { + printf("\t\t\t\t\t; %s -> X%03d\n", &idglobal_name[globals][1], externs); + idglobal_tag[globals++] = externs++; + } + return (1); +} +int id_add(char *name, int len, int type, int size) +{ + return ((type & LOCAL_TYPE) ? idlocal_add(name, len, type, size) : idglobal_add(name, len, type, size)); +} +int idfunc_add(char *name, int len, int type, int tag) +{ + if (globals > 1024) + { + printf("Global variable count overflow\n"); + return (0); + } + idglobal_name[globals][0] = len; + if (len > 16) len = 16; + while (len--) + idglobal_name[globals][1 + len] = name[len]; + idglobal_type[globals] = type; + idglobal_tag[globals++] = tag; + if (type & EXTERN_TYPE) + printf("\t\t\t\t\t; %s -> X%03d\n", &idglobal_name[globals - 1][1], tag); + return (1); +} +int idfunc_extern(char *name, int len) +{ + int i; + if (((i = idglobal_lookup(name, len)) >= 0) && (idglobal_type[i] & FUNC_TYPE)) + { + idglobal_type[i] |= EXTERN_TYPE; + return (idglobal_type[i]); + } + parse_error("Undeclared identifier"); + return (0); +} +void idglobal_size(int type, int size, int constsize) +{ + if (size > constsize) + emit_data(0, 0, 0, size - constsize); + else if (size) + emit_data(0, 0, 0, size); +} +int idlocal_size(void) +{ + return (localsize); +} +void idlocal_reset(void) +{ + locals = 0; + localsize = 2; +} +int id_tag(char *name, int len) +{ + int i; + if ((i = idlocal_lookup(name, len)) >= 0) + return (idlocal_offset[i]); + if ((i = idglobal_lookup(name, len)) >= 0) + return (idglobal_tag[i]); + parse_error("Undeclared identifier"); + return (-1); +} +int id_const(char *name, int len) +{ + int i; + if ((i = idconst_lookup(name, len)) >= 0) + return (idconst_value[i]); + parse_error("Undeclared constant"); + return (0); +} +int id_type(char *name, int len) +{ + int i; + if ((i = idconst_lookup(name, len)) >= 0) + return (CONST_TYPE); + if ((i = idlocal_lookup(name, len)) >= 0) + return (idlocal_type[i] | LOCAL_TYPE); + if ((i = idglobal_lookup(name, len)) >= 0) + return (idglobal_type[i]); + parse_error("Undeclared identifier"); + return (0); +} +int tag_new(int type) +{ + if (type & EXTERN_TYPE) + return (externs++); + if (type & ASM_TYPE) + return (globals); + if (type & DEF_TYPE) + return (defs++); + if (type & BRANCH_TYPE) + return (codetags++); + return globals++; +} +int fixup_new(int tag, int type, int size) +{ + if (fixups > 255) + { + printf("External variable count overflow\n"); + return (0); + } + fixup_tag[fixups] = tag; + fixup_type[fixups] = type; + fixup_size[fixups] = size; + return (fixups++); +} +/* + * Emit assembly code. + */ +#define BYTECODE_SEG 2 +static int outflags = 0; +static char *DB = ".BYTE"; +static char *DW = ".WORD"; +static char *DS = ".RES"; +static char LBL = ':'; +char *tag_string(int tag, int type) +{ + static char str[16]; + char t; + + if (type & EXTERN_TYPE) + t = 'X'; + else if (type & DEF_TYPE) + t = 'C'; + else if (type & ASM_TYPE) + t = 'A'; + else if (type & BRANCH_TYPE) + t = 'B'; + else + t = 'D'; + sprintf(str, "_%c%03d", t, tag); + return str; +} +void emit_flags(int flags) +{ + outflags = flags; + if (outflags & ACME) + { + DB = "!BYTE"; + DW = "!WORD"; + DS = "!FILL"; + LBL = ' '; + } +} +void emit_header(void) +{ + if (outflags & ACME) + printf("; ACME COMPATIBLE OUTPUT\n"); + else + printf("; CA65 COMPATIBLE OUTPUT\n"); + printf("_SEGBEGIN%c\n", LBL); + printf("\t%s\t_SEGEND-_SEGBEGIN\t; LENGTH OF HEADER + CODE/DATA + BYTECODE SEGMENT\n", DW); + printf("\t%s\t$DA7E\t\t\t; MAGIC #\n", DW); + printf("\t%s\t_SUBSEG\t\t\t; BYTECODE SUB-SEGMENT\n", DW); +} +void emit_trailer(void) +{ + if (!(outflags & BYTECODE_SEG)) + emit_bytecode_seg(); + printf("_SEGEND%c\n", LBL); +} +char *supper(char *s) +{ + static char su[80]; + int i; + for (i = 0; s[i]; i++) + su[i] = toupper(s[i]); + su[i] = '\0'; + return su; +} +void emit_dci(char *str, int len) +{ + if (len--) + { + printf("\t; DCI STRING: %s\n", supper(str)); + printf("\t%s\t$%02X", DB, toupper(*str++) | (len ? 0x80 : 0x00)); + while (len--) + printf(",$%02X", toupper(*str++) | (len ? 0x80 : 0x00)); + printf("\n"); + } +} +void emit_moddep(char *name, int len) +{ + if (name) + emit_dci(name, len); + else + printf("\t%s\t$00\t\t\t; END OF MODULE DEPENDENCIES\n", DB); +} +void emit_bytecode_seg(void) +{ + if (!(outflags & BYTECODE_SEG)) + printf("_SUBSEG%c\t\t\t\t; BYTECODE STARTS\n", LBL); + outflags |= BYTECODE_SEG; +} +void emit_comment(char *s) +{ + printf("\t\t\t\t\t; %s\n", s); +} +void emit_asm(char *s) +{ + printf("%s\n", s); +} +void emit_idlocal(char *name, int value) +{ + printf("\t\t\t\t\t; %s -> [%d]\n", name, value); +} +void emit_idglobal(int tag, int size, char *name) +{ + if (size == 0) + printf("_D%03d%c\t\t\t\t\t; %s\n", tag, LBL, name); + else + printf("_D%03d%c\t%s\t%d\t\t\t; %s\n", tag, LBL, DS, size, name); +} +void emit_idfunc(int tag, int type, char *name) +{ + printf("%s%c\t\t\t\t\t; %s()\n", tag_string(tag, type), LBL, name); +} +void emit_idconst(char *name, int value) +{ + printf("\t\t\t\t\t; %s = %d\n", name, value); +} +int emit_data(int vartype, int consttype, long constval, int constsize) +{ + int datasize, i; + char *str; + if (consttype == 0) + { + datasize = constsize; + printf("\t%s\t$%02X\n", DS, constsize); + } + else if (consttype & STRING_TYPE) + { + datasize = constsize; + str = (char *)constval; + printf("\t%s\t$%02X\n", DB, --constsize); + while (constsize-- > 0) + { + printf("\t%s\t$%02X", DB, *str++); + for (i = 0; i < 7; i++) + { + if (constsize-- > 0) + printf(",$%02X", *str++); + else + break; + } + printf("\n"); + } + } + else if (consttype & ADDR_TYPE) + { + if (vartype == WORD_TYPE) + { + int fixup = fixup_new(constval, consttype, FIXUP_WORD); + datasize = 2; + if (consttype & EXTERN_TYPE) + printf("_F%03d%c\t%s\t0\t\t\t; %s\n", fixup, LBL, DW, tag_string(constval, consttype)); + else + printf("_F%03d%c\t%s\t%s\n", fixup, LBL, DW, tag_string(constval, consttype)); + } + else + { + int fixup = fixup_new(constval, consttype, FIXUP_BYTE); + datasize = 1; + if (consttype & EXTERN_TYPE) + printf("_F%03d%c\t%s\t0\t\t\t; %s\n", fixup, LBL, DB, tag_string(constval, consttype)); + else + printf("_F%03d%c\t%s\t%s\n", fixup, LBL, DB, tag_string(constval, consttype)); + } + } + else + { + if (vartype == WORD_TYPE) + { + datasize = 2; + printf("\t%s\t$%04lX\n", DW, constval & 0xFFFF); + } + else + { + datasize = 1; + printf("\t%s\t$%02lX\n", DB, constval & 0xFF); + } + } + return (datasize); +} +void emit_codetag(int tag) +{ + printf("_B%03d%c\n", tag, LBL); +} +void emit_const(int cval) +{ + if (cval == 0) + printf("\t%s\t$00\t\t\t; ZERO\n", DB); + else if (cval > 0 && cval < 256) + printf("\t%s\t$2A,$%02X\t\t\t; CB\t%d\n", DB, cval, cval); + else + printf("\t%s\t$2C,$%02X,$%02X\t\t; CW\t%d\n", DB, cval&0xFF,(cval>>8)&0xFF, cval); +} +void emit_lb(void) +{ + printf("\t%s\t$60\t\t\t; LB\n", DB); +} +void emit_lw(void) +{ + printf("\t%s\t$62\t\t\t; LW\n", DB); +} +void emit_llb(int index) +{ + printf("\t%s\t$64,$%02X\t\t\t; LLB\t[%d]\n", DB, index, index); +} +void emit_llw(int index) +{ + printf("\t%s\t$66,$%02X\t\t\t; LLW\t[%d]\n", DB, index, index); +} +void emit_lab(int tag, int type) +{ + int fixup = fixup_new(tag, type, FIXUP_WORD); + char *taglbl = tag_string(tag, type); + printf("\t%s\t$68\t\t\t; LAB\t%s\n", DB, taglbl); + printf("_F%03d%c\t%s\t%s\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl); +} +void emit_law(int tag, int type) +{ + int fixup = fixup_new(tag, type, FIXUP_WORD); + char *taglbl = tag_string(tag, type); + printf("\t%s\t$6A\t\t\t; LAW\t%s\n", DB, taglbl); + printf("_F%03d%c\t%s\t%s\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl); +} +void emit_sb(void) +{ + printf("\t%s\t$70\t\t\t; SB\n", DB); +} +void emit_sw(void) +{ + printf("\t%s\t$72\t\t\t; SW\n", DB); +} +void emit_slb(int index) +{ + printf("\t%s\t$74,$%02X\t\t\t; SLB\t[%d]\n", DB, index, index); +} +void emit_slw(int index) +{ + printf("\t%s\t$76,$%02X\t\t\t; SLW\t[%d]\n", DB, index, index); +} +void emit_dlb(int index) +{ + printf("\t%s\t$6C,$%02X\t\t\t; DLB\t[%d]\n", DB, index, index); +} +void emit_dlw(int index) +{ + printf("\t%s\t$6E,$%02X\t\t\t; DLW\t[%d]\n", DB, index, index); +} +void emit_sab(int tag, int type) +{ + int fixup = fixup_new(tag, type, FIXUP_WORD); + char *taglbl = tag_string(tag, type); + printf("\t%s\t$78\t\t\t; SAB\t%s\n", DB, taglbl); + printf("_F%03d%c\t%s\t%s\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl); +} +void emit_saw(int tag, int type) +{ + int fixup = fixup_new(tag, type, FIXUP_WORD); + char *taglbl = tag_string(tag, type); + printf("\t%s\t$7A\t\t\t; SAW\t%s\n", DB, taglbl); + printf("_F%03d%c\t%s\t%s\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl); +} +void emit_dab(int tag, int type) +{ + int fixup = fixup_new(tag, type, FIXUP_WORD); + char *taglbl = tag_string(tag, type); + printf("\t%s\t$7C\t\t\t; DAB\t%s\n", DB, taglbl); + printf("_F%03d%c\t%s\t%s\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl); +} +void emit_daw(int tag, int type) +{ + int fixup = fixup_new(tag, type, FIXUP_WORD); + char *taglbl = tag_string(tag, type); + printf("\t%s\t$7E\t\t\t; DAW\t%s\n", DB, taglbl); + printf("_F%03d%c\t%s\t%s\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl); +} +void emit_localaddr(int index) +{ + printf("\t%s\t$28,$%02X\t\t\t; LLA\t[%d]\n", DB, index, index); +} +void emit_globaladdr(int tag, int type) +{ + int fixup = fixup_new(tag, type, FIXUP_WORD); + char *taglbl = tag_string(tag, type); + printf("\t%s\t$26\t\t\t; LA\t%s\n", DB, taglbl); + printf("_F%03d%c\t%s\t%s\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl); +} +void emit_globaladdrofst(int tag, int ofst, int type) +{ + int fixup = fixup_new(tag, type, FIXUP_WORD); + char *taglbl = tag_string(tag, type); + printf("\t%s\t$26\t\t\t; LA\t%s+%d\n", DB, taglbl, ofst); + printf("_F%03d%c\t%s\t%s+%d\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "" : taglbl, ofst); +} +void emit_indexbyte(void) +{ + printf("\t%s\t$02\t\t\t; IDXB\n", DB); +} +void emit_indexword(void) +{ + printf("\t%s\t$1E\t\t\t; IDXW\n", DB); +} +void emit_brfls(int tag) +{ + printf("\t%s\t$4C\t\t\t; BRFLS\t_B%03d\n", DB, tag); + printf("\t%s\t_B%03d-*\n", DW, tag); +} +void emit_brtru(int tag) +{ + printf("\t%s\t$4E\t\t\t; BRTRU\t_B%03d\n", DB, tag); + printf("\t%s\t_B%03d-*\n", DW, tag); +} +void emit_brnch(int tag) +{ + printf("\t%s\t$50\t\t\t; BRNCH\t_B%03d\n", DB, tag); + printf("\t%s\t_B%03d-*\n", DW, tag); +} +void emit_breq(int tag) +{ + printf("\t%s\t$3C\t\t\t; BREQ\t_B%03d\n", DB, tag); + printf("\t%s\t_B%03d-*\n", DW, tag); +} +void emit_brne(int tag) +{ + printf("\t%s\t$3E\t\t\t; BRNE\t_B%03d\n", DB, tag); + printf("\t%s\t_B%03d-*\n", DW, tag); +} +void emit_brlt(int tag) +{ + printf("\t%s\t$38\t\t\t; BRLT\t_B%03d\n", DB, tag); + printf("\t%s\t_B%03d-*\n", DW, tag); +} +void emit_brgt(int tag) +{ + printf("\t%s\t$3A\t\t\t; BRGT\t_B%03d\n", DB, tag); + printf("\t%s\t_B%03d-*\n", DW, tag); +} +void emit_call(int tag, int type) +{ + int fixup = fixup_new(tag, type, FIXUP_WORD); + char *taglbl = tag_string(tag, type); + printf("\t%s\t$54\t\t\t; CALL\t%s\n", DB, taglbl); + printf("_F%03d%c\t%s\t%s\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl); +} +void emit_ical(void) +{ + printf("\t%s\t$56\t\t\t; ICAL\n", DB); +} +void emit_leave(int framesize) +{ + if (framesize > 2) + printf("\t%s\t$5A\t\t\t; LEAVE\n", DB); + else + printf("\t%s\t$5C\t\t\t; RET\n", DB); +} +void emit_ret(void) +{ + printf("\t%s\t$5C\t\t\t; RET\n", DB); +} +void emit_def(int defopt) +{ +} +void emit_enter(int framesize, int cparams) +{ + if (framesize > 2) + printf("\t%s\t$58,$%02X,$%02X\t\t; ENTER\t%d,%d\n", DB, framesize, cparams, framesize, cparams); +} +void emit_start(void) +{ +} +void emit_dup(void) +{ + printf("\t%s\t$32\t\t\t; DUP\n", DB); +} +void emit_push(void) +{ + printf("\t%s\t$34\t\t\t; PUSH\n", DB); +} +void emit_pull(void) +{ + printf("\t%s\t$36\t\t\t; PULL\n", DB); +} +void emit_swap(void) +{ + printf("\t%s\t$2E\t\t\t; SWAP\n", DB); +} +void emit_drop(void) +{ + printf("\t%s\t$30\t\t\t; DROP\n", DB); +} +int emit_unaryop(int op) +{ + switch (op) + { + case NEG_TOKEN: + printf("\t%s\t$10\t\t\t; NEG\n", DB); + break; + case COMP_TOKEN: + printf("\t%s\t$12\t\t\t; COMP\n", DB); + break; + case LOGIC_NOT_TOKEN: + printf("\t%s\t$20\t\t\t; NOT\n", DB); + break; + case INC_TOKEN: + printf("\t%s\t$0C\t\t\t; INCR\n", DB); + break; + case DEC_TOKEN: + printf("\t%s\t$0E\t\t\t; DECR\n", DB); + break; + case BPTR_TOKEN: + emit_lb(); + break; + case WPTR_TOKEN: + emit_lw(); + break; + default: + printf("emit_unaryop(%c) ???\n", op & 0x7F); + return (0); + } + return (1); +} +int emit_op(t_token op) +{ + switch (op) + { + case MUL_TOKEN: + printf("\t%s\t$06\t\t\t; MUL\n", DB); + break; + case DIV_TOKEN: + printf("\t%s\t$08\t\t\t; DIV\n", DB); + break; + case MOD_TOKEN: + printf("\t%s\t$0A\t\t\t; MOD\n", DB); + break; + case ADD_TOKEN: + printf("\t%s\t$02\t\t\t; ADD\n", DB); + break; + case SUB_TOKEN: + printf("\t%s\t$04\t\t\t; SUB\n", DB); + break; + case SHL_TOKEN: + printf("\t%s\t$1A\t\t\t; SHL\n", DB); + break; + case SHR_TOKEN: + printf("\t%s\t$1C\t\t\t; SHR\n", DB); + break; + case AND_TOKEN: + printf("\t%s\t$14\t\t\t; AND\n", DB); + break; + case OR_TOKEN: + printf("\t%s\t$16\t\t\t; IOR\n", DB); + break; + case EOR_TOKEN: + printf("\t%s\t$18\t\t\t; XOR\n", DB); + break; + case EQ_TOKEN: + printf("\t%s\t$40\t\t\t; ISEQ\n", DB); + break; + case NE_TOKEN: + printf("\t%s\t$42\t\t\t; ISNE\n", DB); + break; + case GE_TOKEN: + printf("\t%s\t$48\t\t\t; ISGE\n", DB); + break; + case LT_TOKEN: + printf("\t%s\t$46\t\t\t; ISLT\n", DB); + break; + case GT_TOKEN: + printf("\t%s\t$44\t\t\t; ISGT\n", DB); + break; + case LE_TOKEN: + printf("\t%s\t$4A\t\t\t; ISLE\n", DB); + break; + case LOGIC_OR_TOKEN: + printf("\t%s\t$22\t\t\t; LOR\n", DB); + break; + case LOGIC_AND_TOKEN: + printf("\t%s\t$24\t\t\t; LAND\n", DB); + break; + case COMMA_TOKEN: + break; + default: + return (0); + } + return (1); +} +void emit_rld(void) +{ + int i; + + printf(";\n; RE-LOCATEABLE DICTIONARY\n;\n"); + /* + * First emit the bytecode definition entrypoint information. + */ + for (i = 0; i < globals; i++) + if (!(idglobal_type[i] & EXTERN_TYPE) && (idglobal_type[i] & DEF_TYPE)) + { + printf("\t%s\t$02\t\t\t; CODE TABLE FIXUP\n", DB); + printf("\t%s\t_C%03d\t\t\n", DW, idglobal_tag[i]); + printf("\t%s\t$00\n", DB); + } + /* + * Now emit the fixup table. + */ + for (i = 0; i < fixups; i++) + { + if (fixup_type[i] & EXTERN_TYPE) + { + printf("\t%s\t$%02X\t\t\t; EXTERNAL FIXUP\n", DB, 0x11 + fixup_size[i]); + printf("\t%s\t_F%03d\t\t\n", DW, i); + printf("\t%s\t%d\t\t\t; ESD INDEX\n", DB, fixup_tag[i]); + } + else + { + printf("\t%s\t$%02X\t\t\t; INTERNAL FIXUP\n", DB, 0x01 + fixup_size[i]); + printf("\t%s\t_F%03d\t\t\n", DW, i); + printf("\t%s\t$00\n", DB); + } + } + printf("\t%s\t$00\t\t\t; END OF RLD\n", DB); +} +void emit_esd(void) +{ + int i; + + printf(";\n; EXTERNAL/ENTRY SYMBOL DICTIONARY\n;\n"); + for (i = 0; i < globals; i++) + { + if (idglobal_type[i] & EXTERN_TYPE) + { + emit_dci(&idglobal_name[i][1], idglobal_name[i][0]); + printf("\t%s\t$10\t\t\t; EXTERNAL SYMBOL FLAG\n", DB); + printf("\t%s\t%d\t\t\t; ESD INDEX\n", DW, idglobal_tag[i]); + } + else if (idglobal_type[i] & EXPORT_TYPE) + { + emit_dci(&idglobal_name[i][1], idglobal_name[i][0]); + printf("\t%s\t$08\t\t\t; ENTRY SYMBOL FLAG\n", DB); + printf("\t%s\t%s\t\t\n", DW, tag_string(idglobal_tag[i], idglobal_type[i])); + } + } + printf("\t%s\t$00\t\t\t; END OF ESD\n", DB); +} \ No newline at end of file diff --git a/plasma3/codegen.h b/plasma3/codegen.h new file mode 100755 index 0000000..667edee --- /dev/null +++ b/plasma3/codegen.h @@ -0,0 +1,58 @@ +#define ACME 1 +void emit_flags(int flags); +void emit_header(void); +void emit_trailer(void); +void emit_moddep(char *name, int len); +void emit_bytecode_seg(void); +void emit_comment(char *s); +void emit_asm(char *s); +void emit_idlocal(char *name, int value); +void emit_idglobal(int value, int size, char *name); +void emit_idfunc(int tag, int type, char *name); +void emit_idconst(char *name, int value); +int emit_data(int vartype, int consttype, long constval, int constsize); +void emit_codetag(int tag); +void emit_const(int cval); +void emit_lb(void); +void emit_lw(void); +void emit_llb(int index); +void emit_llw(int index); +void emit_lab(int tag, int type); +void emit_law(int tag, int type); +void emit_sb(void); +void emit_sw(void); +void emit_slb(int index); +void emit_slw(int index); +void emit_dlb(int index); +void emit_dlw(int index); +void emit_sab(int tag, int type); +void emit_saw(int tag, int type); +void emit_dab(int tag, int type); +void emit_daw(int tag, int type); +void emit_call(int tag, int type); +void emit_ical(void); +void emit_localaddr(int index); +void emit_globaladdr(int tag, int type); +void emit_globaladdrofst(int tag, int offset, int type); +void emit_indexbyte(void); +void emit_indexword(void); +int emit_unaryop(int op); +int emit_op(t_token op); +void emit_brtru(int tag); +void emit_brfls(int tag); +void emit_brgt(int tag); +void emit_brlt(int tag); +void emit_brne(int tag); +void emit_brnch(int tag); +void emit_swap(void); +void emit_dup(void); +void emit_push(void); +void emit_pull(void); +void emit_drop(void); +void emit_leave(int framesize); +void emit_ret(void); +void emit_def(int defopt); +void emit_enter(int framesize, int cparams); +void emit_start(void); +void emit_rld(void); +void emit_esd(void); diff --git a/plasma3/codegen.o b/plasma3/codegen.o new file mode 100755 index 0000000..74e65ad Binary files /dev/null and b/plasma3/codegen.o differ diff --git a/plasma3/dict.c b/plasma3/dict.c new file mode 100755 index 0000000..ad2490f --- /dev/null +++ b/plasma3/dict.c @@ -0,0 +1,182 @@ +/* + * Symbol table and fixup information. + */ +static int consts = 0; +static char idconst_name[1024][17]; +static int idconst_value[1024]; +static int globals = 0; +static int globalsize = 0; +static char idglobal_name[1024][17]; +static int idglobal_type[1024]; +static int idglobal_tag[1024]; +static int locals = 0; +static int localsize = 0; +static char idlocal_name[128][17]; +static int idlocal_type[128]; +static int idlocal_offset[128]; +static int codetag = 0; +static int fixup = 0; +int id_match(char *name, int len, char *id) +{ + if (len == id[0]) + { + if (len > 16) len = 16; + while (len--) + { + if (name[len] != id[1 + len]) + return (0); + } + return (1); + } + return (0); +} +int idlocal_lookup(char *name, int len) +{ + int i; + for (i = 0; i < locals; i++) + if (id_match(name, len, &(idlocal_name[i][0]))) + return (i); + return (-1); +} +int idglobal_lookup(char *name, int len) +{ + int i; + for (i = 0; i < globals; i++) + if (id_match(name, len, &(idglobal_name[i][0]))) + return (i); + return (-1); +} +int idconst_lookup(char *name, int len) +{ + int i; + for (i = 0; i < consts; i++) + if (id_match(name, len, &(idconst_name[i][0]))) + return (i); + return (-1); +} +int idlocal_add(char *name, int len, int type, int size) +{ + if (localsize > 255) + { + printf("Local variable size overflow\n"); + return (0); + } + char c = name[len]; + name[len] = '\0'; + emit_idlocal(name, localsize); + name[len] = c; + idlocal_name[locals][0] = len; + if (len > 16) len = 16; + while (len--) + idlocal_name[locals][1 + len] = name[len]; + idlocal_type[locals] = type; + idlocal_offset[locals] = localsize; + localsize += size; + locals++; + return (1); +} +int idglobal_add(char *name, int len, int type, int size) +{ + if (globals > 1024) + { + printf("Global variable count overflow\n"); + return (0); + } + char c = name[len]; + name[len] = '\0'; + emit_idglobal(globalsize, size, name); + name[len] = c; + idglobal_name[globals][0] = len; + if (len > 16) len = 16; + while (len--) + idglobal_name[globals][1 + len] = name[len]; + idglobal_type[globals] = type; + idglobal_tag[globals] = globalsize; + globalsize += size; + globals++; + return (1); +} +void idglobal_size(int type, int size, int constsize) +{ + if (size > constsize) + globalsize += emit_data(0, 0, 0, size - constsize); + else + globalsize += constsize; +} +int idfunc_add(char *name, int len, int tag) +{ + if (globals > 1024) + { + printf("Global variable count overflow\n"); + return (0); + } + idglobal_name[globals][0] = len; + if (len > 16) len = 16; + while (len--) + idglobal_name[globals][1 + len] = name[len]; + idglobal_type[globals] = FUNC_TYPE; + idglobal_tag[globals] = tag; + globals++; + return (1); +} +int idconst_add(char *name, int len, int value) +{ + if (consts > 1024) + { + printf("Constant count overflow\n"); + return (0); + } + char c = name[len]; + name[len] = '\0'; + emit_idconst(name, value); + name[len] = c; + idconst_name[consts][0] = len; + if (len > 16) len = 16; + while (len--) + idconst_name[consts][1 + len] = name[len]; + idconst_value[consts] = value; + consts++; + return (1); +} +int id_addr(char *name, int len) +{ + int i; + if ((i = idlocal_lookup(name, len)) >= 0) + return (idlocal_offset[i]); + if ((i = idglobal_lookup(name, len)) >= 0) + return (idglobal_tag[i]); + parse_error("Undeclared identifier"); + return (-1); +} +int id_const(char *name, int len) +{ + int i; + if ((i = idconst_lookup(name, len)) >= 0) + return (idconst_value[i]); + parse_error("Undeclared constant"); + return (0); +} +int id_type(char *name, int len) +{ + int i; + if ((i = idconst_lookup(name, len)) >= 0) + return (CONST_TYPE); + if ((i = idlocal_lookup(name, len)) >= 0) + return (idlocal_type[i] | LOCAL_TYPE); + if ((i = idglobal_lookup(name, len)) >= 0) + return (idglobal_type[i]); + parse_error("Undeclared identifier"); + return (0); +} +void idlocal_reset(void) +{ + locals = localsize = 0; +} +int tag_new(void) +{ + return (codetag++); +} +int add_fixup(tag) +{ + return (fixup++); +} diff --git a/plasma3/hi.ascii b/plasma3/hi.ascii new file mode 100755 index 0000000..38dee39 --- /dev/null +++ b/plasma3/hi.ascii @@ -0,0 +1 @@ +€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ \ No newline at end of file diff --git a/plasma3/hi.ascii.a b/plasma3/hi.ascii.a new file mode 100755 index 0000000..fa6cb55 --- /dev/null +++ b/plasma3/hi.ascii.a @@ -0,0 +1,3 @@ +!to "hi.ascii", plain +*=0 +!for i, 256 {!byte i-1 | $80} diff --git a/plasma3/lex.c b/plasma3/lex.c new file mode 100755 index 0000000..6ae5e85 --- /dev/null +++ b/plasma3/lex.c @@ -0,0 +1,363 @@ +#include +#include +#include "tokens.h" +#include "symbols.h" + +char *statement, *scanpos, *tokenstr; +t_token scantoken, prevtoken; +int tokenlen; +long constval; +int lineno = 0; +t_token keywords[] = { + IF_TOKEN, 'I', 'F', + ELSE_TOKEN, 'E', 'L', 'S', 'E', + ELSEIF_TOKEN, 'E', 'L', 'S', 'I', 'F', + FIN_TOKEN, 'F', 'I', 'N', + WHILE_TOKEN, 'W', 'H', 'I', 'L', 'E', + LOOP_TOKEN, 'L', 'O', 'O', 'P', + CASE_TOKEN, 'W', 'H', 'E', 'N', + OF_TOKEN, 'I', 'S', + DEFAULT_TOKEN, 'O', 'T', 'H', 'E', 'R', 'W', 'I', 'S', 'E', + ENDCASE_TOKEN, 'W', 'E', 'N', 'D', + FOR_TOKEN, 'F', 'O', 'R', + TO_TOKEN, 'T', 'O', + DOWNTO_TOKEN, 'D', 'O', 'W', 'N', 'T', 'O', + STEP_TOKEN, 'S', 'T', 'E', 'P', + NEXT_TOKEN, 'N', 'E', 'X', 'T', + REPEAT_TOKEN, 'R', 'E', 'P', 'E', 'A', 'T', + UNTIL_TOKEN, 'U', 'N', 'T', 'I', 'L', + BREAK_TOKEN, 'B', 'R', 'E', 'A', 'K', + ASM_TOKEN, 'A', 'S', 'M', + DEF_TOKEN, 'D', 'E', 'F', + EXPORT_TOKEN, 'E', 'X', 'P', 'O', 'R', 'T', + IMPORT_TOKEN, 'I', 'M', 'P', 'O', 'R', 'T', + RETURN_TOKEN, 'R', 'E', 'T', 'U', 'R', 'N', + END_TOKEN, 'E', 'N', 'D', + START_TOKEN, 'S', 'T', 'A', 'R', 'T', + EXIT_TOKEN, 'E', 'X', 'I', 'T', + DONE_TOKEN, 'D', 'O', 'N', 'E', + LOGIC_NOT_TOKEN, 'N', 'O', 'T', + LOGIC_AND_TOKEN, 'A', 'N', 'D', + LOGIC_OR_TOKEN, 'O', 'R', + BYTE_TOKEN, 'B', 'Y', 'T', 'E', + WORD_TOKEN, 'W', 'O', 'R', 'D', + CONST_TOKEN, 'C', 'O', 'N', 'S', 'T', + PREDEF_TOKEN, 'P', 'R', 'E', 'D', 'E', 'F', + EOL_TOKEN +}; + +void parse_error(char *errormsg) +{ + char *error_carrot = statement; + + fprintf(stderr, "\n%4d: %s\n ", lineno, statement); + for (error_carrot = statement; error_carrot != tokenstr; error_carrot++) + putc(*error_carrot == '\t' ? '\t' : ' ', stderr); + fprintf(stderr, "^\nError: %s\n", errormsg); + exit(1); +} +t_token scan(void) +{ + prevtoken = scantoken; + /* + * Skip whitespace. + */ + while (*scanpos && (*scanpos == ' ' || *scanpos == '\t')) scanpos++; + tokenstr = scanpos; + /* + * Scan for token based on first character. + */ + if (*scanpos == '\0' || *scanpos == '\n' || *scanpos == ';') + scantoken = EOL_TOKEN; + else if ((scanpos[0] >= 'a' && scanpos[0] <= 'z') + || (scanpos[0] >= 'A' && scanpos[0] <= 'Z') + || (scanpos[0] == '_')) + { + /* + * ID, either variable name or reserved word. + */ + int keypos = 0, matchpos = 0; + + do + { + scanpos++; + } + while ((*scanpos >= 'a' && *scanpos <= 'z') + || (*scanpos >= 'A' && *scanpos <= 'Z') + || (*scanpos == '_') + || (*scanpos >= '0' && *scanpos <= '9')); + scantoken = ID_TOKEN; + tokenlen = scanpos - tokenstr; + /* + * Search for matching keyword. + */ + while (keywords[keypos] != EOL_TOKEN) + { + while (keywords[keypos + 1 + matchpos] == toupper(tokenstr[matchpos])) + matchpos++; + if (IS_TOKEN(keywords[keypos + 1 + matchpos]) && (matchpos == tokenlen)) + { + /* + * A match. + */ + scantoken = keywords[keypos]; + break; + } + else + { + /* + * Find next keyword. + */ + keypos += matchpos + 1; + matchpos = 0; + while (!IS_TOKEN(keywords[keypos])) keypos++; + } + } + } + else if (scanpos[0] >= '0' && scanpos[0] <= '9') + { + /* + * Number constant. + */ + for (constval = 0; *scanpos >= '0' && *scanpos <= '9'; scanpos++) + constval = constval * 10 + *scanpos - '0'; + scantoken = INT_TOKEN; + } + else if (scanpos[0] == '$') + { + /* + * Hexadecimal constant. + */ + constval = 0; + while (scanpos++) + { + if (*scanpos >= '0' && *scanpos <= '9') + constval = constval * 16 + *scanpos - '0'; + else if (*scanpos >= 'A' && *scanpos <= 'F') + constval = constval * 16 + *scanpos - 'A' + 10; + else if (*scanpos >= 'a' && *scanpos <= 'f') + constval = constval * 16 + *scanpos - 'a' + 10; + else + break; + } + scantoken = INT_TOKEN; + } + else if (scanpos[0] == '\'') + { + /* + * Character constant. + */ + scantoken = CHAR_TOKEN; + if (scanpos[1] != '\\') + { + constval = scanpos[1]; + if (scanpos[2] != '\'') + { + parse_error("Bad character constant"); + return (-1); + } + scanpos += 3; + } + else + { + switch (scanpos[2]) + { + case 'n': + constval = '\n'; + break; + case 'r': + constval = '\r'; + break; + case 't': + constval = '\t'; + break; + case '\'': + constval = '\''; + break; + case '\\': + constval = '\\'; + break; + case '0': + constval = '\0'; + break; + default: + parse_error("Bad character constant"); + return (-1); + } + if (scanpos[3] != '\'') + { + parse_error("Bad character constant"); + return (-1); + } + scanpos += 4; + } + } + else if (scanpos[0] == '\"') + { + char *scanshift; + /* + * String constant. + */ + scantoken = STRING_TOKEN; + constval = (long)++scanpos; + while (*scanpos && *scanpos != '\"') + { + if (*scanpos == '\\') + { + switch (scanpos[1]) + { + case 'n': + *scanpos = '\n'; + break; + case 'r': + *scanpos = '\r'; + break; + case 't': + *scanpos = '\t'; + break; + case '\'': + *scanpos = '\''; + break; + case '\\': + *scanpos = '\\'; + break; + case '0': + *scanpos = '\0'; + break; + default: + parse_error("Bad string constant"); + return (-1); + } + for (scanshift = scanpos + 1; *scanshift; scanshift++) + scanshift[0] = scanshift[1]; + } + else + scanpos++; + } + if (!*scanpos++) + { + parse_error("Unterminated string"); + return (-1); + } + } + else + { + /* + * Potential two and three character tokens. + */ + switch (scanpos[0]) + { + case '>': + if (scanpos[1] == '>') + { + scantoken = SHR_TOKEN; + scanpos += 2; + } + else if (scanpos[1] == '=') + { + scantoken = GE_TOKEN; + scanpos += 2; + } + else + { + scantoken = GT_TOKEN; + scanpos++; + } + break; + case '<': + if (scanpos[1] == '<') + { + scantoken = SHL_TOKEN; + scanpos += 2; + } + else if (scanpos[1] == '=') + { + scantoken = LE_TOKEN; + scanpos += 2; + } + else if (scanpos[1] == '>') + { + scantoken = NE_TOKEN; + scanpos += 2; + } + else + { + scantoken = LT_TOKEN; + scanpos++; + } + break; + case '=': + if (scanpos[1] == '=') + { + scantoken = EQ_TOKEN; + scanpos += 2; + } + else + { + scantoken = SET_TOKEN; + scanpos++; + } + break; + case '+': + if (scanpos[1] == '+') + { + scantoken = INC_TOKEN; + scanpos += 2; + } + else + { + scantoken = ADD_TOKEN; + scanpos++; + } + break; + case '-': + if (scanpos[1] == '-') + { + scantoken = DEC_TOKEN; + scanpos += 2; + } + else + { + scantoken = SUB_TOKEN; + scanpos++; + } + break; + default: + /* + * Simple single character tokens. + */ + scantoken = TOKEN(*scanpos++); + } + } + tokenlen = scanpos - tokenstr; + return (scantoken); +} +void scan_rewind(char *backptr) +{ + scanpos = backptr; +} +int scan_lookahead(void) +{ + char *backpos = scanpos; + char *backstr = tokenstr; + int prevtoken = scantoken; + int prevlen = tokenlen; + int look = scan(); + scanpos = backpos; + tokenstr = backstr; + scantoken = prevtoken; + tokenlen = prevlen; + return (look); +} +char inputline[512]; +int next_line(void) +{ + gets(inputline); + lineno++; + statement = inputline; + scanpos = inputline; + scantoken = EOL_TOKEN; + scan(); + printf("; %03d: %s\n", lineno, inputline); + return (1); +} diff --git a/plasma3/lex.h b/plasma3/lex.h new file mode 100755 index 0000000..5bfbda7 --- /dev/null +++ b/plasma3/lex.h @@ -0,0 +1,10 @@ +extern char *statement, *scanpos, *tokenstr; +extern t_token scantoken, prevtoken; +extern int tokenlen; +extern long constval; +extern char inputline[]; +void parse_error(char *errormsg); +int next_line(void); +void scan_rewind(char *backptr); +int scan_lookahead(void); +t_token scan(void); diff --git a/plasma3/lex.o b/plasma3/lex.o new file mode 100755 index 0000000..6bbd3d8 Binary files /dev/null and b/plasma3/lex.o differ diff --git a/plasma3/makefile b/plasma3/makefile new file mode 100755 index 0000000..14d303d --- /dev/null +++ b/plasma3/makefile @@ -0,0 +1,39 @@ +.SUFFIXES = +AFLAGS = -o $@ +LFLAGS = -C default.cfg +PLVM = plvm +PLASM = plasm +INCS = tokens.h symbols.h lex.h parse.h codegen.h +OBJS = plasm.c parse.o lex.o codegen.o +# +# Image filetypes for Virtual ][ +# +PLATYPE = .\$$ED +BINTYPE = .BIN +SYSTYPE = .SYS +TXTTYPE = .TXT +# +# Image filetypes for CiderPress +# +#PLATYPE = \#ed0000 +#BINTYPE = \#060000 +#SYSTYPE = \#ff0000 +#TXTTYPE = \#040000 + +all: $(PLASM) $(PLVM) + +$(PLASM): $(OBJS) $(INCS) + cc $(OBJS) -o $(PLASM) + +$(PLVM): plvm.c + cc plvm.c -o $(PLVM) + +test: test.pla $(PLVM) $(PLASM) + ./$(PLASM) -A < test.pla > test.a + acme --setpc 4096 -o TEST.BIN test.a + ./$(PLVM) TEST.BIN MAIN + +debug: test.pla $(PLVM) $(PLASM) + ./$(PLASM) -A < test.pla > test.a + acme --setpc 4096 -o TEST.BIN test.a + ./$(PLVM) -s TEST.BIN MAIN diff --git a/plasma3/parse.c b/plasma3/parse.c new file mode 100755 index 0000000..e49d90d --- /dev/null +++ b/plasma3/parse.c @@ -0,0 +1,1294 @@ +#include +#include "tokens.h" +#include "symbols.h" +#include "lex.h" +#include "codegen.h" +#include "parse.h" + +int infunc = 0, break_tag = 0, stack_loop = 0; +t_token prevstmnt; + +t_token binary_ops_table[] = { + /* Highest precedence */ + MUL_TOKEN, DIV_TOKEN, MOD_TOKEN, + ADD_TOKEN, SUB_TOKEN, + SHR_TOKEN, SHL_TOKEN, + AND_TOKEN, + EOR_TOKEN, + OR_TOKEN, + GT_TOKEN, GE_TOKEN, LT_TOKEN, LE_TOKEN, + EQ_TOKEN, NE_TOKEN, + LOGIC_AND_TOKEN, + LOGIC_OR_TOKEN + /* Lowest precedence */ +}; +t_token binary_ops_precedence[] = { + /* Highest precedence */ + 1, 1, 1, + 2, 2, + 3, 3, + 4, + 5, + 6, + 7, 7, 7, 7, + 8, 8, + 9, + 10 + /* Lowest precedence */ +}; + +t_token opstack[16]; +int precstack[16]; +int opsptr = -1; +void push_op(t_token op, int prec) +{ + if (++opsptr == 16) + { + parse_error("Stack overflow\n"); + return; + } + opstack[opsptr] = op; + precstack[opsptr] = prec; +} +t_token pop_op(void) +{ + if (opsptr < 0) + { + parse_error("Stack underflow\n"); + return (0); + } + return opstack[opsptr--]; +} +t_token tos_op(void) +{ + return opsptr < 0 ? 0 : opstack[opsptr]; +} +int tos_op_prec(int tos) +{ + return opsptr <= tos ? 100 : precstack[opsptr]; +} +int parse_expr(void); +int parse_term(void) +{ + /* + * Parse terminal tokens. + */ + switch (scan()) + { + case CHAR_TOKEN: + case INT_TOKEN: + case FLOAT_TOKEN: + case ID_TOKEN: + case STRING_TOKEN: + break; + case OPEN_PAREN_TOKEN: + if (!parse_expr()) + { + parse_error("Bad expression in parenthesis"); + return (0); + } + if (scantoken != CLOSE_PAREN_TOKEN) + { + parse_error("Missing closing parenthesis"); + return (0); + } + break; + default: + /* + * Non-terminal token. + */ + return (0); + } + return (1); +} +int parse_constval(long *value, int *size) +{ + int mod = 0, type = 0; + *value = 0; + while (!parse_term()) + { + switch (scantoken) + { + case ADD_TOKEN: + /* + * Just ignore unary plus, it is a no-op. + */ + break; + case NEG_TOKEN: + mod |= 1; + break; + case COMP_TOKEN: + mod |= 2; + break; + case LOGIC_NOT_TOKEN: + mod |= 4; + break; + case AT_TOKEN: + mod |= 8; + break; + default: + return (0); + } + } + /* + * Determine which terminal type. + */ + if (scantoken == STRING_TOKEN) + { + *value = constval; + *size = tokenlen - 1; + type = STRING_TYPE; + if (mod) + { + parse_error("Invalid string modifiers"); + return (0); + } + } + else if (scantoken == CHAR_TOKEN) + { + *value = constval; + *size = 1; + type = CONST_TYPE; + } + else if (scantoken == INT_TOKEN) + { + *value = constval; + *size = 2; + type = CONST_TYPE; + } + else if (scantoken == ID_TOKEN) + { + type = id_type(tokenstr, tokenlen); + if (type & CONST_TYPE) + *value = id_const(tokenstr, tokenlen); + else if ((type & (FUNC_TYPE | EXTERN_TYPE)) || ((type & ADDR_TYPE) && (mod & 8))) + *value = id_tag(tokenstr, tokenlen); + else + { + parse_error("Invalid constant"); + return (0); + } + } + else + { + parse_error("Invalid constant"); + return (0); + } + if (mod & 1) + *value = -*value; + if (mod & 2) + *value = ~*value; + if (mod & 4) + *value = *value ? 0 : -1; + return (type); +} +int parse_value(int rvalue) +{ + int cparams; + int deref = rvalue; + int optos = opsptr; + int type = 0, value = 0, emit_value = 0; + /* + * Parse pre operand operators. + */ + while (!parse_term()) + { + switch (scantoken) + { + case ADD_TOKEN: + /* + * Just ignore unary plus, it is a no-op. + */ + break; + case BPTR_TOKEN: + if (deref) + push_op(scantoken, 0); + else + { + type |= BPTR_TYPE; + deref++; + } + break; + case WPTR_TOKEN: + if (deref) + push_op(scantoken, 0); + else + { + type |= WPTR_TYPE; + deref++; + } + break; + case AT_TOKEN: + deref--; + break; + case NEG_TOKEN: + case COMP_TOKEN: + case LOGIC_NOT_TOKEN: + push_op(scantoken, 0); + break; + default: + return (0); + } + } + /* + * Determine which terminal type. + */ + if (scantoken == INT_TOKEN || scantoken == CHAR_TOKEN) + { + value = constval; + type |= CONST_TYPE; + } + else if (scantoken == ID_TOKEN) + { + if ((type |= id_type(tokenstr, tokenlen)) & CONST_TYPE) + value = id_const(tokenstr, tokenlen); + else if (type & VAR_TYPE) + value = id_tag(tokenstr, tokenlen); + else if (type & FUNC_TYPE) + value = id_tag(tokenstr, tokenlen); + else + { + printf("Bad ID type\n"); + return (0); + } + } + else if (scantoken == CLOSE_PAREN_TOKEN) + { + // type |= WORD_TYPE; + emit_value = 1; + } + else + return (0); + if (type & CONST_TYPE) + { + /* + * Quick optimizations + */ + while ((optos < opsptr) + && ((tos_op() == NEG_TOKEN) || (tos_op() == COMP_TOKEN) || (tos_op() == LOGIC_NOT_TOKEN))) + { + switch (pop_op()) + { + case NEG_TOKEN: + value = -value; + break; + case COMP_TOKEN: + value = ~value; + break; + case LOGIC_NOT_TOKEN: + value = value ? 0 : -1; + break; + } + } + } + /* + * Parse post operand operators. + */ + while (scan() == OPEN_PAREN_TOKEN + || scantoken == OPEN_BRACKET_TOKEN + || scantoken == DOT_TOKEN + || scantoken == COLON_TOKEN) + { + if (scantoken == OPEN_BRACKET_TOKEN) + { + /* + * Array + */ + if (!emit_value) + { + if (type & ADDR_TYPE) + { + if (type & LOCAL_TYPE) + emit_localaddr(value); + else + emit_globaladdr(value, type); + } + else if (type & CONST_TYPE) + { + emit_const(value); + } + emit_value = 1; + } + if (type & PTR_TYPE) + emit_lw(); + if (!parse_expr()) + { + parse_error("Bad expression"); + return (0); + } + if (scantoken != CLOSE_BRACKET_TOKEN) + { + parse_error("Missing closing bracket"); + return (0); + } + if (type & WORD_TYPE) + { + //type |= WPTR_TYPE; + type = WPTR_TYPE; + emit_indexword(); + } + else + { + //type |= BPTR_TYPE; + type = BPTR_TYPE; + emit_indexbyte(); + } + //type &= ~(ADDR_TYPE | CONST_TYPE); + } + else if (scantoken == DOT_TOKEN || scantoken == COLON_TOKEN) + { + /* + * Structure member offset or array of arrays + */ + int elem_size; + int elem_type = (scantoken == DOT_TOKEN) ? BPTR_TYPE : WPTR_TYPE; + long elem_offset = 0; + if (parse_constval(&elem_offset, &elem_size)) + { + /* + * Constant member offset + */ + if (!emit_value) + { + if (type & VAR_TYPE) + { + if (type & LOCAL_TYPE) + emit_localaddr(value + elem_offset); + else + emit_globaladdrofst(value, elem_offset, type); + } + else if (type & CONST_TYPE) + { + value += elem_offset; + emit_const(value); + } + else // FUNC_TYPE + { + emit_globaladdr(value, type); + emit_const(elem_offset); + emit_op(ADD_TOKEN); + } + emit_value = 1; + } + else + { + if (elem_offset != 0) + { + emit_const(elem_offset); + emit_op(ADD_TOKEN); + } + } + } + else if (scantoken == OPEN_BRACKET_TOKEN) + { + /* + * Array of arrays + */ + if (!emit_value) + { + if (type & ADDR_TYPE) + { + if (type & LOCAL_TYPE) + emit_localaddr(value); + else + emit_globaladdr(value, type); + } + else if (type & CONST_TYPE) + { + emit_const(value); + } + emit_value = 1; + } + while (parse_expr()) + { + if (scantoken != COMMA_TOKEN) + break; + emit_indexword(); + emit_lw(); + } + if (scantoken != CLOSE_BRACKET_TOKEN) + { + parse_error("Missing closing bracket"); + return (0); + } + if (elem_type & WPTR_TYPE) + emit_indexword(); + else + emit_indexbyte(); + } + else + { + parse_error("Invalid member offset"); + return (0); + } + type = elem_type; //(type & ~(ADDR_TYPE | CONST_TYPE)) | elem_type; + } + else if (scantoken == OPEN_PAREN_TOKEN) + { + /* + * Function call + */ + if (!emit_value && (type & VAR_TYPE)) + { + if (type & LOCAL_TYPE) + emit_localaddr(value); + else + emit_globaladdr(value, type); + } + //if (type & (VAR_TYPE | PTR_TYPE)) + // emit_lw(); + if (!(type & (FUNC_TYPE | CONST_TYPE))) + { + if (scan_lookahead() != CLOSE_PAREN_TOKEN) + emit_push(); + } + cparams = 0; + while (parse_expr()) + { + cparams++; + if (scantoken != COMMA_TOKEN) + break; + } + if (scantoken != CLOSE_PAREN_TOKEN) + { + parse_error("Missing closing parenthesis"); + return (0); + } + if (type & (FUNC_TYPE | CONST_TYPE)) + emit_call(value, type); + else + { + if (cparams) + emit_pull(); + emit_ical(); + } + emit_value = 1; + type = WORD_TYPE; //(type & ~(FUNC_TYPE | CONST_TYPE)) | WORD_TYPE; + } + } + if (emit_value) + { + if (rvalue && deref && (type & PTR_TYPE)) + (type & BPTR_TYPE) ? emit_lb() : emit_lw(); + } + else + { + if (type & CONST_TYPE) + emit_const(value); + else if (deref) + { + if (type & FUNC_TYPE) + emit_call(value, type); + else if (type & VAR_TYPE) + { + if (type & LOCAL_TYPE) + (type & BYTE_TYPE) ? emit_llb(value) : emit_llw(value); + else + (type & BYTE_TYPE) ? emit_lab(value, type) : emit_law(value, type); + } + else if (type & PTR_TYPE) + (type & BPTR_TYPE) ? emit_lb() : emit_lw(); + } + else + { + if (type & LOCAL_TYPE) + emit_localaddr(value); + else + emit_globaladdr(value, type); + } + } + while (optos < opsptr) + { + if (!emit_unaryop(pop_op())) + { + parse_error(": Invalid unary operation"); + return (0); + } + } + return (type ? type : WORD_TYPE); +} +int parse_constexpr(long *value, int *size) +{ + long val1, val2; + int type, size1, size2 = 0; + + if (!(type = parse_constval(&val1, &size1))) + return (0); + if (scan() == ADD_TOKEN) + { + if (!parse_constval(&val2, &size2)) + return (0); + *value = val1 + val2; + } + else if (scantoken == SUB_TOKEN) + { + if (!parse_constval(&val2, &size2)) + return (0); + *value = val1 - val2; + } + else if (scantoken == MUL_TOKEN) + { + if (!parse_constval(&val2, &size2)) + return (0); + *value = val1 * val2; + } + else if (scantoken == DIV_TOKEN) + { + if (!parse_constval(&val2, &size2)) + return (0); + *value = val1 / val2; + } + else if (scantoken == AND_TOKEN) + { + if (!parse_constval(&val2, &size2)) + return (0); + *value = val1 & val2; + } + else if (scantoken == OR_TOKEN) + { + if (!parse_constval(&val2, &size2)) + return (0); + *value = val1 | val2; + } + else if (scantoken == EOR_TOKEN) + { + if (!parse_constval(&val2, &size2)) + return (0); + *value = val1 ^ val2; + } + else + *value = val1; + *size = size1 > size2 ? size1 : size2; + return (type); +} +int parse_expr() +{ + int prevmatch; + int matchop = 0; + int optos = opsptr; + int i; + int prevtype, type = 0; + do + { + /* + * Parse sequence of double operand operations. + */ + prevmatch = matchop; + matchop = 0; + if (parse_value(1)) + { + matchop = 1; + for (i = 0; i < sizeof(binary_ops_table); i++) + if (scantoken == binary_ops_table[i]) + { + matchop = 2; + if (binary_ops_precedence[i] >= tos_op_prec(optos)) + if (!emit_op(pop_op())) + { + parse_error(": Invalid binary operation"); + return (0); + } + push_op(scantoken, binary_ops_precedence[i]); + break; + } + } + } + while (matchop == 2); + if (matchop == 0 && prevmatch == 2) + { + parse_error("Missing operand"); + return (0); + } + while (optos < opsptr) + if (!emit_op(pop_op())) + { + parse_error(": Invalid binary operation"); + return (0); + } + return (matchop || prevmatch); +} +int parse_stmnt(void) +{ + int tag_prevbrk, tag_else, tag_endif, tag_while, tag_wend, tag_repeat, tag_for, tag_choice, type, addr, step; + char *idptr; + + /* + * Optimization for last function LEAVE + */ + if (scantoken != END_TOKEN && scantoken != DONE_TOKEN) + prevstmnt = scantoken; + + switch (scantoken) + { + case IF_TOKEN: + if (!parse_expr()) + { + parse_error("Bad expression"); + return (0); + } + tag_else = tag_new(BRANCH_TYPE); + tag_endif = tag_new(BRANCH_TYPE); + emit_brfls(tag_else); + scan(); + do { + while (parse_stmnt()) next_line(); + if (scantoken != ELSEIF_TOKEN) + break; + emit_brnch(tag_endif); + emit_codetag(tag_else); + if (!parse_expr()) + { + parse_error("Bad expression"); + return (0); + } + tag_else = tag_new(BRANCH_TYPE); + emit_brfls(tag_else); + } + while (1); + if (scantoken == ELSE_TOKEN) + { + emit_brnch(tag_endif); + emit_codetag(tag_else); + scan(); + while (parse_stmnt()) next_line(); + emit_codetag(tag_endif); + } + else + { + emit_codetag(tag_else); + emit_codetag(tag_endif); + } + if (scantoken != FIN_TOKEN) + { + parse_error("Missing IF/FIN"); + return (0); + } + break; + case WHILE_TOKEN: + tag_while = tag_new(BRANCH_TYPE); + tag_wend = tag_new(BRANCH_TYPE); + tag_prevbrk = break_tag; + break_tag = tag_wend; + emit_codetag(tag_while); + if (!parse_expr()) + { + parse_error("Bad expression"); + return (0); + } + emit_brfls(tag_wend); + while (parse_stmnt()) next_line(); + if (scantoken != LOOP_TOKEN) + { + parse_error("Missing WHILE/END"); + return (0); + } + emit_brnch(tag_while); + emit_codetag(tag_wend); + break_tag = tag_prevbrk; + break; + case REPEAT_TOKEN: + tag_prevbrk = break_tag; + break_tag = tag_new(BRANCH_TYPE); + tag_repeat = tag_new(BRANCH_TYPE); + emit_codetag(tag_repeat); + scan(); + while (parse_stmnt()) next_line(); + if (scantoken != UNTIL_TOKEN) + { + parse_error("Missing REPEAT/UNTIL"); + return (0); + } + if (!parse_expr()) + { + parse_error("Bad expression"); + return (0); + } + emit_brfls(tag_repeat); + emit_codetag(break_tag); + break_tag = tag_prevbrk; + break; + case FOR_TOKEN: + stack_loop++; + tag_prevbrk = break_tag; + break_tag = tag_new(BRANCH_TYPE); + tag_for = tag_new(BRANCH_TYPE); + if (scan() != ID_TOKEN) + { + parse_error("Missing FOR variable"); + return (0); + } + type = id_type(tokenstr, tokenlen); + addr = id_tag(tokenstr, tokenlen); + if (scan() != SET_TOKEN) + { + parse_error("Missing FOR ="); + return (0); + } + if (!parse_expr()) + { + parse_error("Bad FOR expression"); + return (0); + } + emit_codetag(tag_for); + if (type & LOCAL_TYPE) + type & BYTE_TYPE ? emit_dlb(addr) : emit_dlw(addr); + else + type & BYTE_TYPE ? emit_dab(addr, type) : emit_daw(addr, type); + if (scantoken == TO_TOKEN) + step = 1; + else if (scantoken == DOWNTO_TOKEN) + step = -1; + else + { + parse_error("Missing FOR TO"); + return (0); + } + if (!parse_expr()) + { + parse_error("Bad FOR TO expression"); + return (0); + } + step > 0 ? emit_brgt(break_tag) : emit_brlt(break_tag); + if (scantoken == STEP_TOKEN) + { + if (!parse_expr()) + { + parse_error("Bad FOR STEP expression"); + return (0); + } + emit_op(step > 0 ? ADD_TOKEN : SUB_TOKEN); + } + else + emit_unaryop(step > 0 ? INC_TOKEN : DEC_TOKEN); + while (parse_stmnt()) next_line(); + if (scantoken != NEXT_TOKEN) + { + parse_error("Missing FOR/NEXT "); + return (0); + } + emit_brnch(tag_for); + emit_codetag(break_tag); + emit_drop(); + break_tag = tag_prevbrk; + stack_loop--; + break; + case CASE_TOKEN: + stack_loop++; + tag_prevbrk = break_tag; + break_tag = tag_new(BRANCH_TYPE); + tag_choice = tag_new(BRANCH_TYPE); + if (!parse_expr()) + { + parse_error("Bad CASE expression"); + return (0); + } + next_line(); + while (scantoken != ENDCASE_TOKEN) + { + if (scantoken == OF_TOKEN) + { + if (!parse_expr()) + { + parse_error("Bad CASE OF expression"); + return (0); + } + emit_brne(tag_choice); + while (parse_stmnt()) next_line(); + emit_brnch(break_tag); + emit_codetag(tag_choice); + tag_choice = tag_new(BRANCH_TYPE); + } + else if (scantoken == DEFAULT_TOKEN) + { + scan(); + while (parse_stmnt()) next_line(); + if (scantoken != ENDCASE_TOKEN) + { + parse_error("Bad CASE DEFAULT clause"); + return (0); + } + } + else + { + parse_error("Bad CASE clause"); + return (0); + } + } + emit_codetag(break_tag); + emit_drop(); + break_tag = tag_prevbrk; + stack_loop--; + break; + case BREAK_TOKEN: + if (break_tag) + emit_brnch(break_tag); + else + { + parse_error("BREAK without loop"); + return (0); + } + break; + case RETURN_TOKEN: + if (infunc) + { + int i; + for (i = 0; i < stack_loop; i++) + emit_drop(); + if (!parse_expr()) + emit_const(0); + emit_leave(idlocal_size()); + } + else + { + parse_error("RETURN outside of function"); + return (0); + } + break; + case EOL_TOKEN: + case COMMENT_TOKEN: + return (1); + case ELSE_TOKEN: + case ELSEIF_TOKEN: + case FIN_TOKEN: + case LOOP_TOKEN: + case UNTIL_TOKEN: + case NEXT_TOKEN: + case OF_TOKEN: + case DEFAULT_TOKEN: + case ENDCASE_TOKEN: + case END_TOKEN: + case DONE_TOKEN: + case DEF_TOKEN: + return (0); + case ID_TOKEN: + idptr = tokenstr; + type = id_type(tokenstr, tokenlen); + if (type & (VAR_TYPE | FUNC_TYPE)) + { + addr = id_tag(tokenstr, tokenlen); + if (scan() == SET_TOKEN) + { + if (type & VAR_TYPE) + { + if (!parse_expr()) + { + parse_error("Bad expression"); + return (0); + } + if (type & LOCAL_TYPE) + (type & BYTE_TYPE) ? emit_slb(addr) : emit_slw(addr); + else + (type & BYTE_TYPE) ? emit_sab(addr, type) : emit_saw(addr, type); + break; + } + } + else if ((scantoken == EOL_TOKEN) && (type & FUNC_TYPE)) + { + emit_call(addr, type); + emit_drop(); + break; + } + } + tokenstr = idptr; + default: + scan_rewind(tokenstr); + if ((type = parse_value(0)) != 0) + { + if (scantoken == SET_TOKEN) + { + if (!parse_expr()) + { + parse_error("Bad expression"); + return (0); + } + if (type & LOCAL_TYPE) + (type & (BYTE_TYPE | BPTR_TYPE)) ? emit_sb() : emit_sw(); + else + (type & (BYTE_TYPE | BPTR_TYPE)) ? emit_sb() : emit_sw(); + } + else + { + if (type & BPTR_TYPE) + emit_lb(); + else if (type & WPTR_TYPE) + emit_lw(); + emit_drop(); + } + } + else + { + parse_error("Syntax error"); + return (0); + } + } + if (scan() != EOL_TOKEN && scantoken != COMMENT_TOKEN) + { + parse_error("Extraneous characters"); + return (0); + } + return (1); +} +int parse_var(int type) +{ + char *idstr; + long constval; + int consttype, constsize, arraysize, idlen = 0; + long size = 1; + + if (scan() == ID_TOKEN) + { + idstr = tokenstr; + idlen = tokenlen; + if (scan() == OPEN_BRACKET_TOKEN) + { + size = 0; + parse_constexpr(&size, &constsize); + if (scantoken != CLOSE_BRACKET_TOKEN) + { + parse_error("Missing closing bracket"); + return (0); + } + scan(); + } + } + if (type & WORD_TYPE) + size *= 2; + if (scantoken == SET_TOKEN) + { + if (type & (EXTERN_TYPE | LOCAL_TYPE)) + { + parse_error("Cannot initiallize local/external variables"); + return (0); + } + if (idlen) + idglobal_add(idstr, idlen, type, 0); + if ((consttype = parse_constexpr(&constval, &constsize))) + { + /* + * Variable initialization. + */ + arraysize = emit_data(type, consttype, constval, constsize); + while (scantoken == COMMA_TOKEN) + { + if ((consttype = parse_constexpr(&constval, &constsize))) + arraysize += emit_data(type, consttype, constval, constsize); + else + { + parse_error("Bad array declaration"); + return (0); + } + } + if (size > arraysize) + idglobal_size(PTR_TYPE, size, arraysize); + } + else + { + parse_error("Bad variable initializer"); + return (0); + } + } + else if (idlen) + id_add(idstr, idlen, type, size); + return (1); +} +int parse_vars(int type) +{ + long value; + int idlen, size; + char *idstr; + + switch (scantoken) + { + case CONST_TOKEN: + if (scan() != ID_TOKEN) + { + parse_error("Missing variable"); + return (0); + } + idstr = tokenstr; + idlen = tokenlen; + if (scan() != SET_TOKEN) + { + parse_error("Bad LValue"); + return (0); + } + if (!parse_constexpr(&value, &size)) + { + parse_error("Bad constant"); + return (0); + } + idconst_add(idstr, idlen, value); + break; + case EXPORT_TOKEN: + if (type & (EXTERN_TYPE | LOCAL_TYPE)) + { + parse_error("Cannot export local/imported variables"); + return (0); + } + type = EXPORT_TYPE; + idstr = tokenstr; + if (scan() != BYTE_TOKEN && scantoken != WORD_TOKEN) + { + /* + * This could be an exported definition. + */ + scan_rewind(idstr); + scan(); + return (0); + } + /* + * Fall through to BYTE or WORD declaration. + */ + case BYTE_TOKEN: + case WORD_TOKEN: + type |= (scantoken == BYTE_TOKEN) ? BYTE_TYPE : WORD_TYPE; + if (!parse_var(type)) + return (0); + while (scantoken == COMMA_TOKEN) + { + if (!parse_var(type)) + return (0); + } + break; + case PREDEF_TOKEN: + /* + * Pre definition. + */ + if (scan() == ID_TOKEN) + { + type |= DEF_TYPE; + idstr = tokenstr; + idlen = tokenlen; + idfunc_add(tokenstr, tokenlen, type, tag_new(type)); + while (scan() == COMMA_TOKEN) + { + if (scan() == ID_TOKEN) + { + idstr = tokenstr; + idlen = tokenlen; + idfunc_add(tokenstr, tokenlen, type, tag_new(type)); + } + else + { + parse_error("Bad function pre-declaration"); + return (0); + } + } + } + else + { + parse_error("Bad function pre-declaration"); + return (0); + } + case EOL_TOKEN: + case COMMENT_TOKEN: + return (1); + default: + return (0); + } + return (1); +} +int parse_imps(void) +{ + if (scantoken == IMPORT_TOKEN) + { + if (scan() != ID_TOKEN) + { + parse_error("Bad import definition"); + return (0); + } + emit_moddep(tokenstr, tokenlen); + scan(); + while (parse_vars(EXTERN_TYPE)) next_line(); + if (scantoken != END_TOKEN) + { + parse_error("Syntax error"); + return (0); + } + if (scan() != EOL_TOKEN && scantoken != COMMENT_TOKEN) + { + parse_error("Extraneous characters"); + return (0); + } + } + if (scantoken == EOL_TOKEN || scantoken == COMMENT_TOKEN) + return (1); + emit_moddep(0, 0); + return (0); +} +int parse_defs(void) +{ + char c; + int func_tag, cfnparms, type = GLOBAL_TYPE; + static char bytecode = 0; + if (scantoken == EXPORT_TOKEN) + { + if (scan() != DEF_TOKEN && scantoken != ASM_TOKEN) + { + parse_error("Bad export definition"); + return 0; + } + type = EXPORT_TYPE; + } + if (scantoken == DEF_TOKEN) + { + if (scan() != ID_TOKEN) + { + parse_error("Missing function name"); + return (0); + } + emit_bytecode_seg(); + bytecode = 1; + cfnparms = 0; + infunc = 1; + type |= DEF_TYPE; + if (idglobal_lookup(tokenstr, tokenlen) >= 0) + { + if (!(id_type(tokenstr, tokenlen) & DEF_TYPE)) + { + parse_error("Mismatch function type"); + return (0); + } + idfunc_set(tokenstr, tokenlen, type); // Override any predef type + func_tag = id_tag(tokenstr, tokenlen); + } + else + { + func_tag = tag_new(type); + idfunc_add(tokenstr, tokenlen, type, func_tag); + } + c = tokenstr[tokenlen]; + tokenstr[tokenlen] = '\0'; + emit_idfunc(func_tag, type, tokenstr); + tokenstr[tokenlen] = c; + idlocal_reset(); + if (scan() == OPEN_PAREN_TOKEN) + { + do + { + if (scan() == ID_TOKEN) + { + cfnparms++; + idlocal_add(tokenstr, tokenlen, WORD_TYPE, 2); + scan(); + } + } while (scantoken == COMMA_TOKEN); + if (scantoken != CLOSE_PAREN_TOKEN) + { + parse_error("Bad function parameter list"); + return (0); + } + scan(); + } + while (parse_vars(LOCAL_TYPE)) next_line(); + emit_enter(idlocal_size(), cfnparms); + prevstmnt = 0; + while (parse_stmnt()) next_line(); + infunc = 0; + if (scantoken != END_TOKEN) + { + parse_error("Syntax error"); + return (0); + } + if (scan() != EOL_TOKEN && scantoken != COMMENT_TOKEN) + { + parse_error("Extraneous characters"); + return (0); + } + if (prevstmnt != RETURN_TOKEN) + { + emit_const(0); + emit_leave(idlocal_size()); + } + return (1); + } + else if (scantoken == ASM_TOKEN) + { + if (scan() != ID_TOKEN) + { + parse_error("Missing function name"); + return (0); + } + if (bytecode) + { + parse_error("ASM code only allowed before DEF code"); + return (0); + } + cfnparms = 0; + infunc = 1; + type |= ASM_TYPE; + if (idglobal_lookup(tokenstr, tokenlen) >= 0) + { + idfunc_set(tokenstr, tokenlen, type); // Override any predef type + func_tag = id_tag(tokenstr, tokenlen); + } + else + { + func_tag = tag_new(type); + idfunc_add(tokenstr, tokenlen, type, func_tag); + } + c = tokenstr[tokenlen]; + tokenstr[tokenlen] = '\0'; + emit_idfunc(func_tag, type, tokenstr); + tokenstr[tokenlen] = c; + if (scan() == OPEN_PAREN_TOKEN) + { + do + { + if (scan() == ID_TOKEN) + { + cfnparms++; + idlocal_add(tokenstr, tokenlen, WORD_TYPE, 2); + scan(); + } + } + while (scantoken == COMMA_TOKEN); + if (scantoken != CLOSE_PAREN_TOKEN) + { + parse_error("Bad function parameter list"); + return (0); + } + scan(); + } + emit_def(1); + do + { + if (scantoken == EOL_TOKEN || scantoken == COMMENT_TOKEN) + next_line(); + else if (scantoken != END_TOKEN) + { + emit_asm(inputline); + next_line(); + } + } + while (scantoken != END_TOKEN); + return (1); + } + if (scantoken == EOL_TOKEN || scantoken == COMMENT_TOKEN) + return (1); + return (0); +} +int parse_module(void) +{ + emit_header(); + if (next_line()) + { + while (parse_imps()) next_line(); + while (parse_vars(GLOBAL_TYPE)) next_line(); + while (parse_defs()) next_line(); + if (scantoken != DONE_TOKEN && scantoken != EOF_TOKEN) + { + emit_start(); + prevstmnt = 0; + while (parse_stmnt()) next_line(); + if (scantoken != DONE_TOKEN) + parse_error("Missing DONE statement"); + emit_const(0); + emit_ret(); + } + } + emit_trailer(); + emit_rld(); + emit_esd(); + return (0); +} diff --git a/plasma3/parse.c~ b/plasma3/parse.c~ new file mode 100755 index 0000000..a156c98 --- /dev/null +++ b/plasma3/parse.c~ @@ -0,0 +1,1296 @@ +#include +#include "tokens.h" +#include "symbols.h" +#include "lex.h" +#include "codegen.h" +#include "parse.h" + +int infunc = 0, break_tag = 0, stack_loop = 0; +t_token prevstmnt; + +t_token binary_ops_table[] = { + /* Highest precedence */ + MUL_TOKEN, DIV_TOKEN, MOD_TOKEN, + ADD_TOKEN, SUB_TOKEN, + SHR_TOKEN, SHL_TOKEN, + AND_TOKEN, + EOR_TOKEN, + OR_TOKEN, + GT_TOKEN, GE_TOKEN, LT_TOKEN, LE_TOKEN, + EQ_TOKEN, NE_TOKEN, + LOGIC_AND_TOKEN, + LOGIC_OR_TOKEN + /* Lowest precedence */ +}; +t_token binary_ops_precedence[] = { + /* Highest precedence */ + 1, 1, 1, + 2, 2, + 3, 3, + 4, + 5, + 6, + 7, 7, 7, 7, + 8, 8, + 9, + 10 + /* Lowest precedence */ +}; + +t_token opstack[16]; +int precstack[16]; +int opsptr = -1; +void push_op(t_token op, int prec) +{ + if (++opsptr == 16) + { + parse_error("Stack overflow\n"); + return; + } + opstack[opsptr] = op; + precstack[opsptr] = prec; +} +t_token pop_op(void) +{ + if (opsptr < 0) + { + parse_error("Stack underflow\n"); + return (0); + } + return opstack[opsptr--]; +} +t_token tos_op(void) +{ + return opsptr < 0 ? 0 : opstack[opsptr]; +} +int tos_op_prec(int tos) +{ + return opsptr <= tos ? 100 : precstack[opsptr]; +} +int parse_expr(void); +int parse_term(void) +{ + /* + * Parse terminal tokens. + */ + switch (scan()) + { + case CHAR_TOKEN: + case INT_TOKEN: + case FLOAT_TOKEN: + case ID_TOKEN: + case STRING_TOKEN: + break; + case OPEN_PAREN_TOKEN: + if (!parse_expr()) + { + parse_error("Bad expression in parenthesis"); + return (0); + } + if (scantoken != CLOSE_PAREN_TOKEN) + { + parse_error("Missing closing parenthesis"); + return (0); + } + break; + default: + /* + * Non-terminal token. + */ + return (0); + } + return (1); +} +int parse_constval(long *value, int *size) +{ + int mod = 0, type = 0; + *value = 0; + while (!parse_term()) + { + switch (scantoken) + { + case ADD_TOKEN: + /* + * Just ignore unary plus, it is a no-op. + */ + break; + case NEG_TOKEN: + mod |= 1; + break; + case COMP_TOKEN: + mod |= 2; + break; + case LOGIC_NOT_TOKEN: + mod |= 4; + break; + case AT_TOKEN: + mod |= 8; + break; + default: + return (0); + } + } + /* + * Determine which terminal type. + */ + if (scantoken == STRING_TOKEN) + { + *value = constval; + *size = tokenlen - 1; + type = STRING_TYPE; + if (mod) + { + parse_error("Invalid string modifiers"); + return (0); + } + } + else if (scantoken == CHAR_TOKEN) + { + *value = constval; + *size = 1; + type = CONST_TYPE; + } + else if (scantoken == INT_TOKEN) + { + *value = constval; + *size = 2; + type = CONST_TYPE; + } + else if (scantoken == ID_TOKEN) + { + type = id_type(tokenstr, tokenlen); + if (type & CONST_TYPE) + *value = id_const(tokenstr, tokenlen); + else if ((type & (FUNC_TYPE | EXTERN_TYPE)) || ((type & ADDR_TYPE) && (mod & 8))) + *value = id_tag(tokenstr, tokenlen); + else + { + parse_error("Invalid constant"); + return (0); + } + } + else + { + parse_error("Invalid constant"); + return (0); + } + if (mod & 1) + *value = -*value; + if (mod & 2) + *value = ~*value; + if (mod & 4) + *value = *value ? 0 : -1; + return (type); +} +int parse_value(int rvalue) +{ + int cparams; + int deref = rvalue; + int optos = opsptr; + int type = 0, value = 0, emit_value = 0; + /* + * Parse pre operand operators. + */ + while (!parse_term()) + { + switch (scantoken) + { + case ADD_TOKEN: + /* + * Just ignore unary plus, it is a no-op. + */ + break; + case BPTR_TOKEN: + if (deref) + push_op(scantoken, 0); + else + { + type |= BPTR_TYPE; + deref++; + } + break; + case WPTR_TOKEN: + if (deref) + push_op(scantoken, 0); + else + { + type |= WPTR_TYPE; + deref++; + } + break; + case AT_TOKEN: + deref--; + break; + case NEG_TOKEN: + case COMP_TOKEN: + case LOGIC_NOT_TOKEN: + push_op(scantoken, 0); + break; + default: + return (0); + } + } + /* + * Determine which terminal type. + */ + if (scantoken == INT_TOKEN || scantoken == CHAR_TOKEN) + { + value = constval; + type |= CONST_TYPE; + } + else if (scantoken == ID_TOKEN) + { + if ((type |= id_type(tokenstr, tokenlen)) & CONST_TYPE) + value = id_const(tokenstr, tokenlen); + else if (type & VAR_TYPE) + value = id_tag(tokenstr, tokenlen); + else if (type & FUNC_TYPE) + value = id_tag(tokenstr, tokenlen); + else + { + printf("Bad ID type\n"); + return (0); + } + } + else if (scantoken == CLOSE_PAREN_TOKEN) + { + // type |= WORD_TYPE; + emit_value = 1; + } + else + return (0); + if (type & CONST_TYPE) + { + /* + * Quick optimizations + */ + while ((optos < opsptr) + && ((tos_op() == NEG_TOKEN) || (tos_op() == COMP_TOKEN) || (tos_op() == LOGIC_NOT_TOKEN))) + { + switch (pop_op()) + { + case NEG_TOKEN: + value = -value; + break; + case COMP_TOKEN: + value = ~value; + break; + case LOGIC_NOT_TOKEN: + value = value ? 0 : -1; + break; + } + } + } + /* + * Parse post operand operators. + */ + while (scan() == OPEN_PAREN_TOKEN + || scantoken == OPEN_BRACKET_TOKEN + || scantoken == DOT_TOKEN + || scantoken == COLON_TOKEN) + { + if (scantoken == OPEN_BRACKET_TOKEN) + { + /* + * Array + */ + if (!emit_value) + { + if (type & ADDR_TYPE) + { + if (type & LOCAL_TYPE) + emit_localaddr(value); + else + emit_globaladdr(value, type); + } + else if (type & CONST_TYPE) + { + emit_const(value); + } + emit_value = 1; + } + if (type & PTR_TYPE) + emit_lw(); + if (!parse_expr()) + { + parse_error("Bad expression"); + return (0); + } + if (scantoken != CLOSE_BRACKET_TOKEN) + { + parse_error("Missing closing bracket"); + return (0); + } + if (type & WORD_TYPE) + { + //type |= WPTR_TYPE; + type = WPTR_TYPE; + emit_indexword(); + } + else + { + //type |= BPTR_TYPE; + type = BPTR_TYPE; + emit_indexbyte(); + } + //type &= ~(ADDR_TYPE | CONST_TYPE); + } + else if (scantoken == DOT_TOKEN || scantoken == COLON_TOKEN) + { + /* + * Structure member offset or array of arrays + */ + int elem_size; + int elem_type = (scantoken == DOT_TOKEN) ? BPTR_TYPE : WPTR_TYPE; + long elem_offset = 0; + if (parse_constval(&elem_offset, &elem_size)) + { + /* + * Constant member offset + */ + if (!emit_value) + { + if (type & VAR_TYPE) + { + if (type & LOCAL_TYPE) + emit_localaddr(value + elem_offset); + else + emit_globaladdrofst(value, elem_offset, type); + } + else if (type & CONST_TYPE) + { + value += elem_offset; + emit_const(value); + } + else // FUNC_TYPE + { + emit_globaladdr(value, type); + emit_const(elem_offset); + emit_op(ADD_TOKEN); + } + emit_value = 1; + } + else + { + if (elem_offset != 0) + { + emit_const(elem_offset); + emit_op(ADD_TOKEN); + } + } + } + else if (scantoken == OPEN_BRACKET_TOKEN) + { + /* + * Array of arrays + */ + if (!emit_value) + { + if (type & ADDR_TYPE) + { + if (type & LOCAL_TYPE) + emit_localaddr(value); + else + emit_globaladdr(value, type); + } + else if (type & CONST_TYPE) + { + emit_const(value); + } + emit_value = 1; + } + while (parse_expr()) + { + if (scantoken != COMMA_TOKEN) + break; + emit_indexword(); + emit_lw(); + } + if (scantoken != CLOSE_BRACKET_TOKEN) + { + parse_error("Missing closing bracket"); + return (0); + } + if (elem_type & WPTR_TYPE) + emit_indexword(); + else + emit_indexbyte(); + } + else + { + parse_error("Invalid member offset"); + return (0); + } + type = elem_type; //(type & ~(ADDR_TYPE | CONST_TYPE)) | elem_type; + } + else if (scantoken == OPEN_PAREN_TOKEN) + { + /* + * Function call + */ + if (!emit_value && (type & VAR_TYPE)) + { + if (type & LOCAL_TYPE) + emit_localaddr(value); + else + emit_globaladdr(value, type); + } + //if (type & (VAR_TYPE | PTR_TYPE)) + // emit_lw(); + if (!(type & (FUNC_TYPE | CONST_TYPE))) + { + if (scan_lookahead() != CLOSE_PAREN_TOKEN) + emit_push(); + } + cparams = 0; + while (parse_expr()) + { + cparams++; + if (scantoken != COMMA_TOKEN) + break; + } + if (scantoken != CLOSE_PAREN_TOKEN) + { + parse_error("Missing closing parenthesis"); + return (0); + } + if (type & (FUNC_TYPE | CONST_TYPE)) + emit_call(value, type); + else + { + if (cparams) + emit_pull(); + emit_ical(); + } + emit_value = 1; + type = WORD_TYPE; //(type & ~(FUNC_TYPE | CONST_TYPE)) | WORD_TYPE; + } + } + if (emit_value) + { + if (rvalue && deref && (type & PTR_TYPE)) + (type & BPTR_TYPE) ? emit_lb() : emit_lw(); + } + else + { + if (type & CONST_TYPE) + emit_const(value); + else if (deref) + { + if (type & FUNC_TYPE) + emit_call(value, type); + else if (type & VAR_TYPE) + { + if (type & LOCAL_TYPE) + (type & BYTE_TYPE) ? emit_llb(value) : emit_llw(value); + else + (type & BYTE_TYPE) ? emit_lab(value, type) : emit_law(value, type); + } + else if (type & PTR_TYPE) + (type & BPTR_TYPE) ? emit_lb() : emit_lw(); + } + else + { + if (type & LOCAL_TYPE) + emit_localaddr(value); + else + emit_globaladdr(value, type); + } + } + while (optos < opsptr) + { + if (!emit_unaryop(pop_op())) + { + parse_error(": Invalid unary operation"); + return (0); + } + } + return (type ? type : WORD_TYPE); +} +int parse_constexpr(long *value, int *size) +{ + long val1, val2; + int type, size1, size2 = 0; + + if (!(type = parse_constval(&val1, &size1))) + return (0); + if (scan() == ADD_TOKEN) + { + if (!parse_constval(&val2, &size2)) + return (0); + *value = val1 + val2; + } + else if (scantoken == SUB_TOKEN) + { + if (!parse_constval(&val2, &size2)) + return (0); + *value = val1 - val2; + } + else if (scantoken == MUL_TOKEN) + { + if (!parse_constval(&val2, &size2)) + return (0); + *value = val1 * val2; + } + else if (scantoken == DIV_TOKEN) + { + if (!parse_constval(&val2, &size2)) + return (0); + *value = val1 / val2; + } + else if (scantoken == AND_TOKEN) + { + if (!parse_constval(&val2, &size2)) + return (0); + *value = val1 & val2; + } + else if (scantoken == OR_TOKEN) + { + if (!parse_constval(&val2, &size2)) + return (0); + *value = val1 | val2; + } + else if (scantoken == EOR_TOKEN) + { + if (!parse_constval(&val2, &size2)) + return (0); + *value = val1 ^ val2; + } + else + *value = val1; + *size = size1 > size2 ? size1 : size2; + return (type); +} +int parse_expr() +{ + int prevmatch; + int matchop = 0; + int optos = opsptr; + int i; + int prevtype, type = 0; + do + { + /* + * Parse sequence of double operand operations. + */ + prevmatch = matchop; + matchop = 0; + if (parse_value(1)) + { + matchop = 1; + for (i = 0; i < sizeof(binary_ops_table); i++) + if (scantoken == binary_ops_table[i]) + { + matchop = 2; + if (binary_ops_precedence[i] >= tos_op_prec(optos)) + if (!emit_op(pop_op())) + { + parse_error(": Invalid binary operation"); + return (0); + } + push_op(scantoken, binary_ops_precedence[i]); + break; + } + } + } + while (matchop == 2); + if (matchop == 0 && prevmatch == 2) + { + parse_error("Missing operand"); + return (0); + } + while (optos < opsptr) + if (!emit_op(pop_op())) + { + parse_error(": Invalid binary operation"); + return (0); + } + return (matchop || prevmatch); +} +int parse_stmnt(void) +{ + int tag_prevbrk, tag_else, tag_endif, tag_while, tag_wend, tag_repeat, tag_for, tag_choice, type, addr, step; + char *idptr; + + /* + * Optimization for last function LEAVE + */ + if (scantoken != END_TOKEN && scantoken != DONE_TOKEN) + prevstmnt = scantoken; + + switch (scantoken) + { + case IF_TOKEN: + if (!parse_expr()) + { + parse_error("Bad expression"); + return (0); + } + tag_else = tag_new(BRANCH_TYPE); + tag_endif = tag_new(BRANCH_TYPE); + emit_brfls(tag_else); + scan(); + do { + while (parse_stmnt()) next_line(); + if (scantoken != ELSEIF_TOKEN) + break; + emit_brnch(tag_endif); + emit_codetag(tag_else); + if (!parse_expr()) + { + parse_error("Bad expression"); + return (0); + } + tag_else = tag_new(BRANCH_TYPE); + emit_brfls(tag_else); + } + while (1); + if (scantoken == ELSE_TOKEN) + { + emit_brnch(tag_endif); + emit_codetag(tag_else); + scan(); + while (parse_stmnt()) next_line(); + emit_codetag(tag_endif); + } + else + { + emit_codetag(tag_else); + emit_codetag(tag_endif); + } + if (scantoken != FIN_TOKEN) + { + parse_error("Missing IF/FIN"); + return (0); + } + break; + case WHILE_TOKEN: + tag_while = tag_new(BRANCH_TYPE); + tag_wend = tag_new(BRANCH_TYPE); + tag_prevbrk = break_tag; + break_tag = tag_wend; + emit_codetag(tag_while); + if (!parse_expr()) + { + parse_error("Bad expression"); + return (0); + } + emit_brfls(tag_wend); + while (parse_stmnt()) next_line(); + if (scantoken != LOOP_TOKEN) + { + parse_error("Missing WHILE/END"); + return (0); + } + emit_brnch(tag_while); + emit_codetag(tag_wend); + break_tag = tag_prevbrk; + break; + case REPEAT_TOKEN: + tag_prevbrk = break_tag; + break_tag = tag_new(BRANCH_TYPE); + tag_repeat = tag_new(BRANCH_TYPE); + emit_codetag(tag_repeat); + scan(); + while (parse_stmnt()) next_line(); + if (scantoken != UNTIL_TOKEN) + { + parse_error("Missing REPEAT/UNTIL"); + return (0); + } + if (!parse_expr()) + { + parse_error("Bad expression"); + return (0); + } + emit_brfls(tag_repeat); + emit_codetag(break_tag); + break_tag = tag_prevbrk; + break; + case FOR_TOKEN: + stack_loop++; + tag_prevbrk = break_tag; + break_tag = tag_new(BRANCH_TYPE); + tag_for = tag_new(BRANCH_TYPE); + if (scan() != ID_TOKEN) + { + parse_error("Missing FOR variable"); + return (0); + } + type = id_type(tokenstr, tokenlen); + addr = id_tag(tokenstr, tokenlen); + if (scan() != SET_TOKEN) + { + parse_error("Missing FOR ="); + return (0); + } + if (!parse_expr()) + { + parse_error("Bad FOR expression"); + return (0); + } + emit_codetag(tag_for); + if (type & LOCAL_TYPE) + type & BYTE_TYPE ? emit_dlb(addr) : emit_dlw(addr); + else + type & BYTE_TYPE ? emit_dab(addr, type) : emit_daw(addr, type); + if (scantoken == TO_TOKEN) + step = 1; + else if (scantoken == DOWNTO_TOKEN) + step = -1; + else + { + parse_error("Missing FOR TO"); + return (0); + } + if (!parse_expr()) + { + parse_error("Bad FOR TO expression"); + return (0); + } + step > 0 ? emit_brgt(break_tag) : emit_brlt(break_tag); + if (scantoken == STEP_TOKEN) + { + if (!parse_expr()) + { + parse_error("Bad FOR STEP expression"); + return (0); + } + emit_op(step > 0 ? ADD_TOKEN : SUB_TOKEN); + } + else + emit_unaryop(step > 0 ? INC_TOKEN : DEC_TOKEN); + while (parse_stmnt()) next_line(); + if (scantoken != NEXT_TOKEN) + { + parse_error("Missing FOR/NEXT "); + return (0); + } + emit_brnch(tag_for); + emit_codetag(break_tag); + emit_drop(); + break_tag = tag_prevbrk; + stack_loop--; + break; + case CASE_TOKEN: + stack_loop++; + tag_prevbrk = break_tag; + break_tag = tag_new(BRANCH_TYPE); + tag_choice = tag_new(BRANCH_TYPE); + if (!parse_expr()) + { + parse_error("Bad CASE expression"); + return (0); + } + next_line(); + while (scantoken != ENDCASE_TOKEN) + { + if (scantoken == OF_TOKEN) + { + if (!parse_expr()) + { + parse_error("Bad CASE OF expression"); + return (0); + } + emit_brne(tag_choice); + while (parse_stmnt()) next_line(); + emit_brnch(break_tag); + emit_codetag(tag_choice); + tag_choice = tag_new(BRANCH_TYPE); + } + else if (scantoken == DEFAULT_TOKEN) + { + scan(); + while (parse_stmnt()) next_line(); + if (scantoken != ENDCASE_TOKEN) + { + parse_error("Bad CASE DEFAULT clause"); + return (0); + } + } + else + { + parse_error("Bad CASE clause"); + return (0); + } + } + emit_codetag(break_tag); + emit_drop(); + break_tag = tag_prevbrk; + stack_loop--; + break; + case BREAK_TOKEN: + if (break_tag) + emit_brnch(break_tag); + else + { + parse_error("BREAK without loop"); + return (0); + } + break; + case RETURN_TOKEN: + if (infunc) + { + int i; + for (i = 0; i < stack_loop; i++) + emit_drop(); + if (!parse_expr()) + emit_const(0); + emit_leave(idlocal_size()); + } + else + { + parse_error("RETURN outside of function"); + return (0); + } + break; + case EOL_TOKEN: + case COMMENT_TOKEN: + return (1); + case ELSE_TOKEN: + case ELSEIF_TOKEN: + case FIN_TOKEN: + case LOOP_TOKEN: + case UNTIL_TOKEN: + case NEXT_TOKEN: + case OF_TOKEN: + case DEFAULT_TOKEN: + case ENDCASE_TOKEN: + case END_TOKEN: + case DONE_TOKEN: + case DEF_TOKEN: + return (0); + case ID_TOKEN: + idptr = tokenstr; + type = id_type(tokenstr, tokenlen); + if (type & (VAR_TYPE | FUNC_TYPE)) + { + addr = id_tag(tokenstr, tokenlen); + if (scan() == SET_TOKEN) + { + if (type & VAR_TYPE) + { + if (!parse_expr()) + { + parse_error("Bad expression"); + return (0); + } + if (type & LOCAL_TYPE) + (type & BYTE_TYPE) ? emit_slb(addr) : emit_slw(addr); + else + (type & BYTE_TYPE) ? emit_sab(addr, type) : emit_saw(addr, type); + break; + } + } + else if ((scantoken == EOL_TOKEN) && (type & FUNC_TYPE)) + { + emit_call(addr, type); + emit_drop(); + break; + } + } + tokenstr = idptr; + default: + scan_rewind(tokenstr); + if ((type = parse_value(0)) != 0) + { + if (scantoken == SET_TOKEN) + { + if (!parse_expr()) + { + parse_error("Bad expression"); + return (0); + } + if (type & LOCAL_TYPE) + (type & (BYTE_TYPE | BPTR_TYPE)) ? emit_sb() : emit_sw(); + else + (type & (BYTE_TYPE | BPTR_TYPE)) ? emit_sb() : emit_sw(); + } + else + { + if (type & BPTR_TYPE) + emit_lb(); + else if (type & WPTR_TYPE) + emit_lw(); + emit_drop(); + } + } + else + { + parse_error("Syntax error"); + return (0); + } + } + if (scan() != EOL_TOKEN && scantoken != COMMENT_TOKEN) + { + parse_error("Extraneous characters"); + return (0); + } + return (1); +} +int parse_var(int type) +{ + char *idstr; + long constval; + int consttype, constsize, arraysize, idlen = 0; + long size = 1; + + if (scan() == ID_TOKEN) + { + idstr = tokenstr; + idlen = tokenlen; + if (scan() == OPEN_BRACKET_TOKEN) + { + size = 0; + parse_constexpr(&size, &constsize); + if (scantoken != CLOSE_BRACKET_TOKEN) + { + parse_error("Missing closing bracket"); + return (0); + } + scan(); + } + } + if (type & WORD_TYPE) + size *= 2; + if (scantoken == SET_TOKEN) + { + if (type & (EXTERN_TYPE | LOCAL_TYPE)) + { + parse_error("Cannot initiallize local/external variables"); + return (0); + } + if (idlen) + idglobal_add(idstr, idlen, type, 0); + if ((consttype = parse_constexpr(&constval, &constsize))) + { + /* + * Variable initialization. + */ + arraysize = emit_data(type, consttype, constval, constsize); + while (scantoken == COMMA_TOKEN) + { + if ((consttype = parse_constexpr(&constval, &constsize))) + arraysize += emit_data(type, consttype, constval, constsize); + else + { + parse_error("Bad array declaration"); + return (0); + } + } + if (size > arraysize) + idglobal_size(PTR_TYPE, size, arraysize); + } + else + { + parse_error("Bad variable initializer"); + return (0); + } + } + else if (idlen) + id_add(idstr, idlen, type, size); + return (1); +} +int parse_vars(int type) +{ + long value; + int idlen, size; + char *idstr; + + switch (scantoken) + { + case CONST_TOKEN: + if (scan() != ID_TOKEN) + { + parse_error("Missing variable"); + return (0); + } + idstr = tokenstr; + idlen = tokenlen; + if (scan() != SET_TOKEN) + { + parse_error("Bad LValue"); + return (0); + } + if (!parse_constexpr(&value, &size)) + { + parse_error("Bad constant"); + return (0); + } + idconst_add(idstr, idlen, value); + break; + case EXPORT_TOKEN: + if (type & (EXTERN_TYPE | LOCAL_TYPE)) + { + parse_error("Cannot export local/imported variables"); + return (0); + } + type = EXPORT_TYPE; + idstr = tokenstr; + if (scan() != BYTE_TOKEN && scantoken != WORD_TOKEN) + { + /* + * This could be an exported definition. + */ + scan_rewind(idstr); + scan(); + return (0); + } + /* + * Fall through to BYTE or WORD declaration. + */ + case BYTE_TOKEN: + case WORD_TOKEN: + type |= (scantoken == BYTE_TOKEN) ? BYTE_TYPE : WORD_TYPE; + if (!parse_var(type)) + return (0); + while (scantoken == COMMA_TOKEN) + { + if (!parse_var(type)) + return (0); + } + break; + case PREDEF_TOKEN: + /* + * Pre definition. + */ + if (scan() == ID_TOKEN) + { + type |= DEF_TYPE; + idstr = tokenstr; + idlen = tokenlen; + idfunc_add(tokenstr, tokenlen, type, tag_new(type)); + while (scan() == COMMA_TOKEN) + { + if (scan() == ID_TOKEN) + { + idstr = tokenstr; + idlen = tokenlen; + idfunc_add(tokenstr, tokenlen, type, tag_new(type)); + } + else + { + parse_error("Bad function pre-declaration"); + return (0); + } + } + } + else + { + parse_error("Bad function pre-declaration"); + return (0); + } + case EOL_TOKEN: + case COMMENT_TOKEN: + return (1); + default: + return (0); + } + return (1); +} +int parse_imps(void) +{ + if (scantoken == IMPORT_TOKEN) + { + if (scan() != ID_TOKEN) + { + parse_error("Bad import definition"); + return (0); + } + emit_moddep(tokenstr, tokenlen); + scan(); + while (parse_vars(EXTERN_TYPE)) next_line(); + if (scantoken != END_TOKEN) + { + parse_error("Syntax error"); + return (0); + } + if (scan() != EOL_TOKEN && scantoken != COMMENT_TOKEN) + { + parse_error("Extraneous characters"); + return (0); + } + } + if (scantoken == EOL_TOKEN || scantoken == COMMENT_TOKEN) + return (1); + emit_moddep(0, 0); + return (0); +} +int parse_defs(void) +{ + char c; + int func_tag, cfnparms, type = GLOBAL_TYPE; + static char bytecode = 0; + if (scantoken == EXPORT_TOKEN) + { + if (scan() != DEF_TOKEN && scantoken != ASM_TOKEN) + { + parse_error("Bad export definition"); + return 0; + } + type = EXPORT_TYPE; + } + if (scantoken == DEF_TOKEN) + { + if (scan() != ID_TOKEN) + { + parse_error("Missing function name"); + return (0); + } + emit_bytecode_seg(); + bytecode = 1; + cfnparms = 0; + infunc = 1; + type |= DEF_TYPE; + if (idglobal_lookup(tokenstr, tokenlen) >= 0) + { + if (!(id_type(tokenstr, tokenlen) & DEF_TYPE)) + { + parse_error("Mismatch function type"); + return (0); + } + if (type & EXTERN_TYPE) + idfunc_extern(tokenstr, tokenlen); + func_tag = id_tag(tokenstr, tokenlen); + } + else + { + func_tag = tag_new(type); + idfunc_add(tokenstr, tokenlen, type, func_tag); + } + c = tokenstr[tokenlen]; + tokenstr[tokenlen] = '\0'; + emit_idfunc(func_tag, type, tokenstr); + tokenstr[tokenlen] = c; + idlocal_reset(); + if (scan() == OPEN_PAREN_TOKEN) + { + do + { + if (scan() == ID_TOKEN) + { + cfnparms++; + idlocal_add(tokenstr, tokenlen, WORD_TYPE, 2); + scan(); + } + } while (scantoken == COMMA_TOKEN); + if (scantoken != CLOSE_PAREN_TOKEN) + { + parse_error("Bad function parameter list"); + return (0); + } + scan(); + } + while (parse_vars(LOCAL_TYPE)) next_line(); + emit_enter(idlocal_size(), cfnparms); + prevstmnt = 0; + while (parse_stmnt()) next_line(); + infunc = 0; + if (scantoken != END_TOKEN) + { + parse_error("Syntax error"); + return (0); + } + if (scan() != EOL_TOKEN && scantoken != COMMENT_TOKEN) + { + parse_error("Extraneous characters"); + return (0); + } + if (prevstmnt != RETURN_TOKEN) + { + emit_const(0); + emit_leave(idlocal_size()); + } + return (1); + } + else if (scantoken == ASM_TOKEN) + { + if (scan() != ID_TOKEN) + { + parse_error("Missing function name"); + return (0); + } + if (bytecode) + { + parse_error("ASM code only allowed before DEF code"); + return (0); + } + cfnparms = 0; + infunc = 1; + type |= ASM_TYPE; + if (idglobal_lookup(tokenstr, tokenlen) >= 0) + { + if (type & EXTERN_TYPE) + idfunc_extern(tokenstr, tokenlen); + func_tag = id_tag(tokenstr, tokenlen); + } + else + { + func_tag = tag_new(type); + idfunc_add(tokenstr, tokenlen, type, func_tag); + } + c = tokenstr[tokenlen]; + tokenstr[tokenlen] = '\0'; + emit_idfunc(func_tag, type, tokenstr); + tokenstr[tokenlen] = c; + if (scan() == OPEN_PAREN_TOKEN) + { + do + { + if (scan() == ID_TOKEN) + { + cfnparms++; + idlocal_add(tokenstr, tokenlen, WORD_TYPE, 2); + scan(); + } + } + while (scantoken == COMMA_TOKEN); + if (scantoken != CLOSE_PAREN_TOKEN) + { + parse_error("Bad function parameter list"); + return (0); + } + scan(); + } + emit_def(1); + do + { + if (scantoken == EOL_TOKEN || scantoken == COMMENT_TOKEN) + next_line(); + else if (scantoken != END_TOKEN) + { + emit_asm(inputline); + next_line(); + } + } + while (scantoken != END_TOKEN); + return (1); + } + if (scantoken == EOL_TOKEN || scantoken == COMMENT_TOKEN) + return (1); + return (0); +} +int parse_module(void) +{ + emit_header(); + if (next_line()) + { + while (parse_imps()) next_line(); + while (parse_vars(GLOBAL_TYPE)) next_line(); + while (parse_defs()) next_line(); + if (scantoken != DONE_TOKEN && scantoken != EOF_TOKEN) + { + emit_start(); + prevstmnt = 0; + while (parse_stmnt()) next_line(); + if (scantoken != DONE_TOKEN) + parse_error("Missing DONE statement"); + emit_const(0); + emit_ret(); + } + } + emit_trailer(); + emit_rld(); + emit_esd(); + return (0); +} diff --git a/plasma3/parse.h b/plasma3/parse.h new file mode 100755 index 0000000..94930b7 --- /dev/null +++ b/plasma3/parse.h @@ -0,0 +1 @@ +int parse_module(void); diff --git a/plasma3/parse.o b/plasma3/parse.o new file mode 100755 index 0000000..b1dca24 Binary files /dev/null and b/plasma3/parse.o differ diff --git a/plasma3/plasm b/plasma3/plasm new file mode 100755 index 0000000..3cc5a65 Binary files /dev/null and b/plasma3/plasm differ diff --git a/plasma3/plasm.c b/plasma3/plasm.c new file mode 100755 index 0000000..de5e0e0 --- /dev/null +++ b/plasma3/plasm.c @@ -0,0 +1,17 @@ +#include +#include "tokens.h" +#include "lex.h" +#include "codegen.h" +#include "parse.h" + +int main(int argc, char **argv) +{ + + if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'A') + emit_flags(ACME); + if (parse_module()) + { + fprintf(stderr, "Compilation complete.\n"); + } + return (0); +} diff --git a/plasma3/pleaides.pla b/plasma3/pleaides.pla new file mode 100755 index 0000000..9b1913f --- /dev/null +++ b/plasma3/pleaides.pla @@ -0,0 +1,3382 @@ +; +; Global constants +; +const FALSE = 0 +const TRUE = -1 +; +; Hardware constants +; +const csw = $0036 +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 pushbttn1 = $C061 +const pushbttn2 = $C062 +const pushbttn3 = $C063 +const keyboard = $C000 +const keystrobe = $C010 +const keyenter = $8D +const keyspace = $A0 +const keyarrowup = $8B +const keyarrowdown = $8A +const keyarrowleft = $88 +const keyarrowright = $95 +const keyescape = $9B +const keyctrla = $81 +const keyctrlb = $82 +const keyctrlc = $83 +const keyctrld = $84 +const keyctrle = $85 +const keyctrli = $89 +const keyctrlk = $8B +const keyctrll = $8C +const keyctrln = $8E +const keyctrlo = $8F +const keyctrlp = $90 +const keyctrlq = $91 +const keyctrlr = $92 +const keyctrls = $93 +const keyctrlt = $94 +const keyctrlu = $95 +const keyctrlv = $96 +const keyctrlw = $97 +const keyctrlx = $98 +const keyctrlz = $9A +const keydelete = $FF +const getbuff = $01FF +const argbuff = $2006 +word txtscrn[] = $0400,$0480,$0500,$0580,$0600,$0680,$0700,$0780 +word = $0428,$04A8,$0528,$05A8,$0628,$06A8,$0728,$07A8 +word = $0450,$04D0,$0550,$05D0,$0650,$06D0,$0750,$07D0 +; +; Data and text buffer constants +; +const machid = $BF98 +const maxlines = 626 +const maxfill = 640 +const iobuffer = $0800 +const databuff = $0C00 +const strlinbuf = $1000 +const strheapmap = $1500 +const strheapmsz = $70 ; = memory@16 bytes per bit map, 128 bytes per 8 bit map, 1K bytes per 8 byte map +const maxlnlen = 79 +const strheap = $7000 +const strheasz = $3800 +const codebuff = $A800 +const codebuffsz = $1000 +const pgjmp = 16 +const changed = 1 +const insmode = 2 +const showcurs = 4 +const uppercase = 8 +const shiftlock = 128 +; +; Editor variables +; +byte nullstr[] = "" +byte version[] = "PLASMA VERSION 0.3 " +byte errorstr[] = "ERROR: $" +byte okstr[] = "OK" +byte perr +byte outofmem[] = "OUT OF MEMORY!" +byte losechng[] = "LOSE CHANGES TO FILE (Y/N)?" +;byte emiterr[] = "EMIT CODE/DATA MISMATCH" +byte untitled[] = "UNTITLED" +byte txtfile[64] = "UNTITLED.PLA" +byte flags = 0 +byte flash = 0 +byte cursx, cursy, scrnleft, curscol, underchr, curschr +word cursrow, scrntop, cursptr +word numlines = 0 +word cutbuf = 0 +word keyin +; +; Predeclared functions +; +func cmdmode +; +; Compiler variables +; +; +; Tokens +; +const ID_TKN = $D6 ; V +const CHR_TKN = $C3 ; C +const INT_TKN = $C9 ; I +const STR_TKN = $D3 ; S +const EOL_TKN = $02 +const EOF_TKN = $01 +const ERR_TKN = $00 +; +; Binary operand operators +; +const SET_TKN = $BD ; = +const ADD_TKN = $AB ; + +const SUB_TKN = $AD ; - +const MUL_TKN = $AA ; * +const DIV_TKN = $AF ; / +const MOD_TKN = $A5 ; % +const OR_TKN = $BF ; ? +const EOR_TKN = $DE ; ^ +const AND_TKN = $A6 ; & +const SHR_TKN = $D2 ; R +const SHL_TKN = $CC ; L +const GT_TKN = $BE ; > +const GE_TKN = $C8 ; H +const LT_TKN = $BC ; < +const LE_TKN = $C2 ; B +const NE_TKN = $D5 ; U +const EQ_TKN = $C5 ; E +const LOGIC_AND_TKN = $CE ; N +const LOGIC_OR_TKN = $CF ; O +; +; Unary operand operators +; +const AT_TKN = $C0 ; @ +const DOT_TKN = $AE ; . +const COLON_TKN = $BA ; : +const NEG_TKN = $AD ; - +const COMP_TKN = $A3 ; # +const LOGIC_NOT_TKN = $A1 ; ! +const BPTR_TKN = $DE ; ^ +const WPTR_TKN = $AA ; * +const INC_TKN = $C1 ; A +const DEC_TKN = $C4 ; D +; +; Enclosure tokens +; +const OPEN_PAREN_TKN = $A8 ; ( +const CLOSE_PAREN_TKN = $A9 ; ) +const OPEN_BRACKET_TKN = $DB ; [ +const CLOSE_BRACKET_TKN = $DD ; ] +; +; Misc. tokens +; +const COMMA_TKN = $AC ; , +const COMMENT_TKN = $BB ; ; +; +; Keyword tokens +; +const CONST_TKN = $80 +const BYTE_TKN = $81 +const WORD_TKN = $82 +const IF_TKN = $83 +const ELSEIF_TKN = $84 +const ELSE_TKN = $85 +const FIN_TKN = $86 +const END_TKN = $87 +const WHILE_TKN = $88 +const LOOP_TKN = $89 +const CASE_TKN = $8A +const OF_TKN = $8B +const DEFAULT_TKN = $8C +const ENDCASE_TKN = $8D +const FOR_TKN = $8E +const TO_TKN = $8F +const DOWNTO_TKN = $90 +const STEP_TKN = $91 +const NEXT_TKN = $92 +const REPEAT_TKN = $93 +const UNTIL_TKN = $94 +const IFUNC_TKN = $95 +const TFUNC_TKN = $96 +const NFUNC_TKN = $97 +const DONE_TKN = $98 +const RETURN_TKN = $99 +const BREAK_TKN = $9A +const START_TKN = $9B +const EXIT_TKN = $9C +const EVAL_TKN = $9D +const FUNC_TKN = $9E +; +; Types +; +const CONST_TYPE = $01 +const BYTE_TYPE = $02 +const WORD_TYPE = $04 +const VAR_TYPE = $06 ; (WORD_TYPE | BYTE_TYPE) +const FUNC_TYPE = $08 +const FUNC_CONST_TYPE = $09 +const ADDR_TYPE = $0E ; (VAR_TYPE | FUNC_TYPE) +const LOCAL_TYPE = $10 +const BPTR_TYPE = $20 +const WPTR_TYPE = $40 +const PTR_TYPE = $60 ; (BPTR_TYPE | WPTR_TYPE) +const XBYTE_TYPE = $22 ; (BPTR_TYPE | BYTE_TYPE) +const XWORD_TYPE = $44 ; (WPTR_TYPE | WORD_TYPE) +const STR_TYPE = $80 +; +; Keywords +; +byte keywrds[] +byte = "IF", IF_TKN +byte = "TO", TO_TKN +byte = "IS", OF_TKN +byte = "OR", LOGIC_OR_TKN +byte = "FOR", FOR_TKN +byte = "FIN", FIN_TKN +byte = "DEF", IFUNC_TKN +byte = "END", END_TKN +byte = "AND", LOGIC_AND_TKN +byte = "NOT", LOGIC_NOT_TKN +byte = "BYTE", BYTE_TKN +byte = "WORD", WORD_TKN +byte = "DEFT", TFUNC_TKN +byte = "DEFN", NFUNC_TKN +byte = "ELSE", ELSE_TKN +byte = "NEXT", NEXT_TKN +byte = "WHEN", CASE_TKN +byte = "LOOP", LOOP_TKN +byte = "FUNC", FUNC_TKN +byte = "STEP", STEP_TKN +byte = "EXIT", EXIT_TKN +byte = "DONE", DONE_TKN +byte = "WEND", ENDCASE_TKN +byte = "CONST", CONST_TKN +byte = "ELSIF", ELSEIF_TKN +byte = "WHILE", WHILE_TKN +byte = "UNTIL", UNTIL_TKN +byte = "BREAK", BREAK_TKN +byte = "OTHER", DEFAULT_TKN +byte = "DOWNTO",DOWNTO_TKN +byte = "REPEAT",REPEAT_TKN +byte = "RETURN",RETURN_TKN +byte = $FF +; +; Mathematical ops +; +const bops_tblsz = 17 ; minus 1 +byte bops_tbl[] ; Highest precedence +byte = MUL_TKN, DIV_TKN, MOD_TKN +byte = ADD_TKN, SUB_TKN +byte = SHR_TKN, SHL_TKN +byte = AND_TKN +byte = EOR_TKN +byte = OR_TKN +byte = GT_TKN, GE_TKN, LT_TKN, LE_TKN +byte = EQ_TKN, NE_TKN +byte = LOGIC_AND_TKN +byte = LOGIC_OR_TKN + ; Lowest precedence +byte bops_prec[] ; Highest precedence +byte = 1, 1, 1 +byte = 2, 2 +byte = 3, 3 +byte = 4 +byte = 5 +byte = 6 +byte = 7, 7, 7, 7 +byte = 8, 8 +byte = 9 +byte = 10 + ; Lowest precedence +byte opstack[16] +byte precstack[16] +word opsp = -1 +; +; Symbol table variables +; +const idglobal_tblsz = 2048 +const idlocal_tblsz = 512 +const idglobal_tbl = $1600 +const idlocal_tbl = $1E00 +const ctag_max = 640 +const ctag_value = $800 +const ctag_flags = $D80 +const idval = 0 +const idtype = 2 +const idname = 3 +const idrecsz = 4 +word globals = 0 +word datasize = 0 +word lastglobal +byte locals = 0 +word framesize = 0 +word lastlocal +const resolved = 1 +const is_ctag = $8000 +const mask_ctag = $7FFF +word codetag = -1 +word codeptr, entrypoint = 0 +byte lastop = $FF +; +; Scanner variables +; +const inbuff = $0200 +const instr = $01FF +byte token, tknlen +byte parserrpos, parserr = 0 +word scanptr, tknptr, parserrln +word constval +word lineno = 0 +; +; Compiler output messages +; +byte entrypt_str[] = "START: " +byte comp_ok_msg[] = "COMPILATION COMPLETE" +byte dup_id[] = "DUPLICATE IDENTIFIER" +byte undecl_id[] = "UNDECLARED IDENTIFIER" +byte bad_cnst[] = "BAD CONSTANT" +byte bad_offset[] = "BAD STRUCT OFFSET" +byte bad_decl[] = "BAD DECLARATION" +byte bad_op[] = "BAD OPERATION" +byte bad_stmnt[] = "BAD STATMENT" +byte bad_expr[] = "BAD EXPRESSION" +byte bad_syntax[] = "BAD SYNTAX" +byte estk_overflw[] = "EVAL STACK OVERFLOW" +byte estk_underflw[] = "EVAL STACK UNDERFLOW" +byte local_overflw[] = "LOCAL FRAME OVERFLOW" +byte global_sym_overflw[] = "GLOBAL SYMBOL TABLE OVERFLOW" +byte local_sym_overflw[] = "LOCAL SYMBOL TABLE OVERFLOW" +byte ctag_full[] = "CODE LABEL OVERFLOW" +byte no_close_paren[] = "MISSING CLOSING PAREN" +byte no_close_bracket[] = "MISSING CLOSING BRACKET" +byte missing_op[] = "MISSING OPERAND" +byte no_fin[] = "MISSING FIN" +byte no_loop[] = "MISSING LOOP" +byte no_until[] = "MISSING UNTIL" +byte no_done[] = "MISSING DONE" +byte no_local_init[] = "NO INITIALIZED LOCALS" +; +; Runtime functions +; +byte runtime0[] = "romcall" +byte RUNTIME0[] = "ROMCALL" +byte runtime1[] = "syscall" +byte RUNTIME1[] = "SYSCALL" +byte runtime2[] = "memset" +byte RUNTIME2[] = "MEMSET" +byte runtime3[] = "memcpy" +byte RUNTIME3[] = "MEMCPY" +byte runtime4[] = "cout" +byte RUNTIME4[] = "COUT" +byte runtime5[] = "cin" +byte RUNTIME5[] = "CIN" +byte runtime6[] = "prstr" +byte RUNTIME6[] = "PRSTR" +byte runtime7[] = "rdstr" +byte RUNTIME7[] = "RDSTR" +; +; Parser variables +; +byte infunc = 0 +byte stack_loop = 0 +byte prevstmnt = 0 +word retfunc_tag = 0 +word break_tag = 0 +func parse_expr, parse_module +; +; ProDOS routines +; +def getpfx(path) + byte params[3] + + ^path = 0 + params.0 = 1 + params:1 = path + perr = syscall($C7, @params) + return path +end +def setpfx(path) + byte params[3] + + params.0 = 1 + params:1 = path + perr = syscall($C6, @params) + return path +end +def open(path, buff) + byte params[6] + + params.0 = 3 + params:1 = path + params:3 = buff + perr = syscall($C8, @params) + return params.5 +end +def close(refnum) + byte params[2] + + params.0 = 1 + params.1 = refnum + perr = syscall($CC, @params) + return perr +end +def read(refnum, buff, len) + byte params[8] + + params.0 = 4 + params.1 = refnum + params:2 = buff + params:4 = len + params:6 = 0 + perr = syscall($CA, @params) + return params:6 +end +def write(refnum, buff, len) + byte params[8] + + params.0 = 4 + params.1 = refnum + params:2 = buff + params:4 = len + params:6 = 0 + perr = syscall($CB, @params) + return params:6 +end +def create(path, access, type, aux) + byte params[12] + + params.0 = 7 + params:1 = path + params.3 = access + params.4 = type + params:5 = aux + params.7 = $1 + params:8 = 0 + params:10 = 0 + perr = syscall($C0, @params) + return perr +end +def destroy(path) + byte params[12] + + params.0 = 1 + params:1 = path + perr = syscall($C1, @params) + return perr +end +def newline(refnum, emask, nlchar) + byte params[4] + + params.0 = 3 + params.1 = refnum + params.2 = emask + params.3 = nlchar + perr = syscall($C9, @params) + return perr +end + +;===================================== +; +; Editor +; +;===================================== + +def crout + return cout ($0D) +end +def bell + return romcall(0, 0, 0, 0, $FBDD) +end +; +; Memory management routines +; +def strcpy(srcstr, dststr) + byte strlen + + strlen = ^srcstr + while (srcstr).[strlen] == $8D or (srcstr).[strlen] == $A0 + strlen = strlen - 1 + loop + ^dststr = strlen + return memcpy(srcstr + 1, dststr + 1, strlen) +end +def heapaddr(ofst, mask) + word addr + + addr = (ofst << 7) + strheap + while !(mask & 1) + addr = addr + 16 + mask = mask >> 1 + loop + return addr +end +def sizemask(size) + if size <= 16 + return $01 + elsif size <= 32 + return $03 + elsif size <= 48 + return $07 + elsif size <= 64 + return $0F + elsif size <= 80 + return $1F + fin +end +deft heapalloc(size) + byte szmask, i + word mapmask + + szmask = sizemask(size) + for i = strheapmsz - 1 downto 0 + if strheapmap.[i] <> $FF + mapmask = szmask + repeat + if strheapmap.[i] & mapmask + mapmask = mapmask << 1 + else + strheapmap.[i] = strheapmap.[i] ? mapmask + return heapaddr(i, mapmask) + fin + until mapmask & $100 + fin + next + bell + prstr(@outofmem) +end +def freestr(strptr) + byte mask, ofst + + if strptr and strptr <> @nullstr + mask = sizemask(^strptr + 1) + ofst = (strptr - strheap) >> 4 + mask = mask << (ofst & $07) + ofst = ofst >> 3 + strheapmap.[ofst] = strheapmap.[ofst] & #mask + fin +end +def newstr(strptr) + byte strlen + word newptr + + strlen = ^strptr + while (strptr).[strlen] == $8D or (strptr).[strlen] == $A0 + strlen = strlen - 1 + loop + if strlen == 0 + return @nullstr + fin + newptr = heapalloc(strlen + 1) + if newptr + memcpy(strptr, newptr, strlen + 1) + ^newptr = strlen + return newptr + fin + return @nullstr +end +def inittxtbuf + word i + + memset(0, strheapmap, strheapmsz) + memset(@nullstr, strlinbuf, maxfill * 2) + entrypoint = 0 + numlines = 0 + cursrow = 0 + curscol = 0 + cursx = 0 + cursy = 0 + scrnleft = 0 + scrntop = 0 + cutbuf = 0 +end +; +; Case conversion/printing routines +; +def caseconv(chr) + if flags & uppercase + if chr & $E0 == $E0 + chr = chr - $E0 + fin + fin + return chr +end +def strupper(strptr) + byte i, chr + + for i = ^strptr downto 1 + chr = (strptr).[i] + if chr & $E0 == $E0 + (strptr).[i] = chr - $E0 + fin + next +end +def strlower(strptr) + byte i, chr + + for i = ^strptr downto 1 + chr = (strptr).[i] + if chr & $E0 == $00 + (strptr).[i] = chr + $E0 + fin + next +end +def txtupper + word i, strptr + + flags = flags ? uppercase + for i = numlines - 1 downto 0 + strupper(strlinbuf:[i]) + next +end +def txtlower + word i, strptr + + flags = flags & #uppercase + for i = numlines - 1 downto 0 + strlower(strlinbuf:[i]) + next +end +def prbyte(h) + cout('$') + romcall(h, 0, 0, 0, $FDDA) +end +def prword(h) + cout('$') + romcall(h >> 8, h, 0, 0, $F941) +end +def print(i) + byte numstr[7] + byte place, sign + + place = 6 + if i < 0 + sign = 1 + i = -i + else + sign = 0 + fin + while i >= 10 + numstr[place] = i % 10 + '0' + i = i / 10 + place = place - 1 + loop + numstr[place] = i + '0' + place = place - 1 + if sign + numstr[place] = '-' + place = place - 1 + fin + numstr[place] = 6 - place + prstr(@numstr[place]) +end +def nametostr(namestr, len, strptr) + ^strptr = len + memcpy(namestr, strptr + 1, len) +end +;def toupper(c) +; if c >= 'a' +; if c <= 'z' +; return c - $20 +; fin +; fin +; return c +;end +asm toupper + LDA ESTKL,X + CMP #'a' + BCC :+ + CMP #'z'+1 + BCS :+ + SEC + SBC #$20 + STA ESTKL,X +: RTS +end +asm clrhibit(strptr) + LDY #$02 ; strptr + LDA (FP),Y + STA TMPL + INY + LDA (FP),Y + STA TMPH + LDY #$00 + LDA (TMP),Y + BEQ :+ + TAY +CLHILP: LDA (TMP),Y + AND #$7F + STA (TMP),Y + DEY + BNE CLHILP +: +end +asm sethibit(strptr) + LDY #$02 ; strptr + LDA (FP),Y + STA TMPL + INY + LDA (FP),Y + STA TMPH + LDY #$00 + LDA (TMP),Y + BEQ :+ + TAY +STHILP: LDA (TMP),Y + ORA #$80 + STA (TMP),Y + DEY + BNE STHILP +: +end +asm cpyln(srcstr, dststr) + LDY #$02 ; srcstr + LDA (FP),Y + STA TMPL + INY + LDA (FP),Y + STA TMPH + INY ; dststr + LDA (FP),Y + STA $06 + INY + LDA (FP),Y + STA $07 + LDY #$00 + LDA (TMP),Y + TAY + LDA #$00 + INY + STA ($06),Y + DEY + BEQ :++ +CPLNLP: LDA (TMP),Y + CMP #$20 + BCS :+ + ADC #$60 +: AND #$7F + STA ($06),Y + DEY + BNE CPLNLP + LDA (TMP),Y +: STA ($06),Y +end +; +; File routines +; +def readtxt(filename) + byte txtbuf[81], refnum, i, j + + refnum = open(filename, iobuffer) + if refnum == 0 + return 0 + fin + newline(refnum, $7F, $0D) + repeat + txtbuf = read(refnum, @txtbuf + 1, maxlnlen) + if txtbuf + sethibit(@txtbuf) + if flags & uppercase + strupper(@txtbuf) + fin + strlinbuf:[numlines] = newstr(@txtbuf) + numlines = numlines + 1 + fin + if !(numlines & $0F) + cout('.') + fin + until txtbuf == 0 or numlines == maxlines + close(refnum) +end +def writetxt(filename) + byte txtbuf[81], refnum + byte j, chr + word i, strptr + + destroy(filename) + create(filename, $C3, $04, $00) ; full access, TXT file + refnum = open(filename, iobuffer) + if refnum == 0 + return 0 + fin + for i = 0 to numlines - 1 + cpyln(strlinbuf:[i], @txtbuf) + txtbuf = txtbuf + 1 + txtbuf[txtbuf] = $0D + write(refnum, @txtbuf + 1, txtbuf) + if !(i & $0F) + cout('.') + fin + next + close(refnum) +end +; +; Screen routines +; +def drawrow(row, ofst, strptr) + byte numchars + word scrnptr + + scrnptr = txtscrn[row] + if ^strptr <= ofst + numchars = 0 + else + numchars = ^strptr - ofst + fin + if numchars >= 40 + numchars = 40 + else + memset($A0A0, scrnptr + numchars, 40 - numchars) + fin + memcpy(strptr + ofst + 1, scrnptr, numchars) +end +deft drawscrn(toprow, ofst) + byte row, numchars + word strptr, scrnptr + + for row = 0 to 23 + strptr = strlinbuf:[toprow + row] + scrnptr = txtscrn[row] + if ^strptr <= ofst + numchars = 0 + else + numchars = ^strptr - ofst + fin + if numchars >= 40 + numchars = 40 + else + memset($A0A0, scrnptr + numchars, 40 - numchars) + fin + memcpy(strptr + ofst + 1, scrnptr, numchars) + next +end +def cursoff + if flags & showcurs + ^cursptr = underchr + flags = flags & #showcurs + fin +end +def curson + if !(flags & showcurs) + cursptr = txtscrn[cursy] + cursx + underchr = ^cursptr + ^cursptr = curschr + flags = flags ? showcurs + fin +end +def cursflash + if flags & showcurs + if flash == 0 + ^cursptr = curschr + elsif flash == 128 + ^cursptr = underchr + fin + flash = flash + 1 + fin +end +def redraw + cursoff + drawscrn(scrntop, scrnleft) + curson +end +def curshome + cursoff + cursrow = 0 + curscol = 0 + cursx = 0 + cursy = 0 + scrnleft = 0 + scrntop = 0 + drawscrn(scrntop, scrnleft) + curson +end +def cursend + cursoff + if numlines > 23 + cursrow = numlines - 1 + cursy = 23 + scrntop = cursrow - 23 + else + cursrow = numlines - 1 + cursy = numlines - 1 + scrntop = 0 + fin + curscol = 0 + cursx = 0 + scrnleft = 0 + drawscrn(scrntop, scrnleft) + curson +end +def cursup + if cursrow > 0 + cursoff + cursrow = cursrow - 1 + if cursy > 0 + cursy = cursy - 1 + else + scrntop = cursrow + drawscrn(scrntop, scrnleft) + fin + curson + fin +end +def pgup + byte i + + for i = pgjmp downto 0 + cursup + next +end +def cursdown + if cursrow < numlines - 1 + cursoff + cursrow = cursrow + 1 + if cursy < 23 + cursy = cursy + 1 + else + scrntop = cursrow - 23 + drawscrn(scrntop, scrnleft) + fin + curson + fin +end +def pgdown + byte i + + for i = pgjmp downto 0 + cursdown + next +end +def cursleft + if curscol > 0 + cursoff + curscol = curscol - 1 + if cursx > 0 + cursx = cursx - 1 + else + scrnleft = curscol + drawscrn(scrntop, scrnleft) + fin + curson + fin +end +def pgleft + byte i + + for i = 7 downto 0 + cursleft + next +end +def cursright + if curscol < 80 + cursoff + curscol = curscol + 1 + if cursx < 39 + cursx = cursx + 1 + else + scrnleft = curscol - 39 + drawscrn(scrntop, scrnleft) + fin + curson + fin +end +def pgright + byte i + + for i = 7 downto 0 + cursright + next +end +; +; Keyboard routines +; +def keyin2e + repeat + cursflash + until ^keyboard >= 128 + return ^keystrobe +end +def keyin2 + byte key, flash + + repeat + cursflash + key = ^keyboard + if key == keyctrll + ^keystrobe + flags = flags ^ shiftlock + key = 0 + fin + until key >= 128 + ^keystrobe + if key == keyctrln + key = $DB ; [ + elsif key == keyctrlp + key = $DF ; _ + elsif key == keyctrlb + key = $DC ; \ + elsif key == keyarrowleft + if ^pushbttn3 < 128 + key = $FF + fin + elsif key >= $C0 and flags < shiftlock + if ^pushbttn3 < 128 + if key == $C0 + key = $D0 ; P + elsif key == $DD + key = $CD ; M + elsif key == $DE + key = $CE ; N + fin + else + key = key ? $E0 + fin + fin + return key +end +; +; Printer routines +; +def printtxt(slot) + byte txtbuf[80] + word i, scrncsw + + scrncsw = *(csw) + *(csw) = $C000 ? (slot << 8) + for i = 0 to numlines - 1 + cpyln(strlinbuf:[i], @txtbuf) + prstr(@txtbuf) + crout + next + *(csw) = scrncsw +end +def openline(row) + if numlines < maxlines + memcpy(@strlinbuf:[row], @strlinbuf:[row + 1], (numlines - row) * 2) + strlinbuf:[row] = @nullstr + numlines = numlines + 1 + flags = flags ? changed + return 1 + fin + bell + return 0 +end +def cutline + freestr(cutbuf) + cutbuf = strlinbuf:[cursrow] + memcpy(@strlinbuf:[cursrow + 1], @strlinbuf:[cursrow], (numlines - cursrow) * 2) + if numlines > 1 + numlines = numlines - 1 + fin + flags = flags ? changed + if cursrow == numlines + cursup + fin + redraw +end +def pasteline + if cutbuf and numlines < maxlines + memcpy(@strlinbuf:[cursrow], @strlinbuf:[cursrow + 1], (numlines - cursrow) * 2) + strlinbuf:[cursrow] = newstr(cutbuf) + numlines = numlines + 1 + flags = flags ? changed + redraw + else + bell + fin +end +def joinline + byte joinstr[80], joinlen + + if cursrow < numlines - 1 + strcpy(strlinbuf:[cursrow], @joinstr) + joinlen = joinstr + ^(strlinbuf:[cursrow + 1]) + if joinlen < 80 + memcpy(strlinbuf:[cursrow + 1] + 1, @joinstr + joinstr + 1, ^(strlinbuf:[cursrow + 1])) + joinstr = joinlen + freestr(strlinbuf:[cursrow]) + strlinbuf:[cursrow] = newstr(@joinstr) + freestr(strlinbuf:[cursrow + 1]) + numlines = numlines - 1 + memcpy(@strlinbuf:[cursrow + 2], @strlinbuf:[cursrow + 1], (numlines - cursrow) * 2) + flags = flags ? changed + redraw + else + bell + fin + fin +end +def splitline + byte splitstr[80], splitlen + + if openline(cursrow + 1) + if curscol + splitlen = ^(strlinbuf:[cursrow]) + if curscol < splitlen - 1 + memcpy(strlinbuf:[cursrow] + curscol + 1, @splitstr + 1, splitlen - curscol) + splitstr = splitlen - curscol + strlinbuf:[cursrow + 1] = newstr(@splitstr) + memcpy(strlinbuf:[cursrow] + 1, @splitstr + 1, curscol) + splitstr = curscol + freestr(strlinbuf:[cursrow]) + strlinbuf:[cursrow] = newstr(@splitstr) + fin + else + strlinbuf:[cursrow + 1] = strlinbuf:[cursrow] + strlinbuf:[cursrow] = @nullstr + fin + curscol = 0 + cursx = 0 + scrnleft = 0 + redraw + cursdown + fin +end +def editkey(key) + if key >= keyspace + return 1 + elsif key == keydelete + return 1 + elsif key == keyctrld + return 1 + elsif key == keyctrlr + return 1 + fin +end +def editline(key) + byte editstr[80] + word undoline + + if (editkey(key)) + flags = flags ? changed + memset($A0A0, @editstr, 80) + strcpy(strlinbuf:[cursrow], @editstr) + undoline = strlinbuf:[cursrow] + strlinbuf:[cursrow] = @editstr + repeat + if key >= keyspace + if key == keydelete + if curscol > 0 + if curscol <= editstr + memcpy(@editstr[curscol + 1], @editstr[curscol], editstr - curscol) + editstr = editstr - 1 + fin + curscol = curscol - 1 + cursoff + if cursx > 0 + cursx = cursx - 1 + drawrow(cursy, scrnleft, @editstr) + else + scrnleft = scrnleft - 1 + drawscrn(scrntop, scrnleft) + fin + curson + fin + elsif curscol < maxlnlen + curscol = curscol + 1 + cursx = cursx + 1 + if flags & insmode + if editstr < maxlnlen or editstr.maxlnlen == $A0 + editstr = editstr + 1 + if curscol >= editstr + editstr = curscol + else + memcpy(@editstr[curscol], @editstr[curscol + 1], editstr - curscol) + fin + else + curscol = curscol - 1 + cursx = cursx - 1 + key = editstr[curscol] + bell + fin + else + if curscol > editstr + editstr = curscol + fin + fin + editstr[curscol] = caseconv(key) + cursoff + if cursx <= 39 + drawrow(cursy, scrnleft, @editstr) + else + scrnleft = scrnleft + 1 + cursx = 39 + drawscrn(scrntop, scrnleft) + fin + curson + else + bell + fin + elsif key == keyctrld + if curscol < editstr + memcpy(@editstr[curscol + 2], @editstr[curscol + 1], editstr - curscol) + editstr = editstr - 1 + cursoff + drawrow(cursy, scrnleft, @editstr) + curson + fin + elsif key == keyctrlr + strcpy(undoline, @editstr) + cursoff + drawrow(cursy, scrnleft, @editstr) + curson + fin + key = keyin() + until !editkey(key) + if editstr + strlinbuf:[cursrow] = newstr(@editstr) + else + strlinbuf:[cursrow] = @nullstr + fin + freestr(undoline) + fin + return key +end +def editmode + repeat + when editline(keyin()) + is keyarrowup + cursup + is keyarrowdown + cursdown + is keyarrowleft + cursleft + is keyarrowright + cursright + is keyctrlw + pgup + is keyctrlz + pgdown + is keyctrla + pgleft + is keyctrls + pgright + is keyctrlq + curshome + is keyctrle + cursend + is keyctrlx + cutline + is keyctrlv + pasteline + is keyctrlo + openline(cursrow) + redraw + is keyenter + if flags & insmode + splitline + else + openline(cursrow + 1) + cursdown + redraw + fin + is keyctrlt + joinline + is keyctrli + if flags & insmode + flags = flags & #insmode + curschr = ' ' + else + flags = flags ? insmode + curschr = '+' + fin + is keyctrlc + if flags & uppercase + txtlower + else + txtupper + fin + redraw + is keyescape + cursoff + cmdmode + redraw + otherwise + bell + wend + until 0 +end +; +; Command mode +; +def prfiles(optpath) + byte path[64] + byte refnum + byte firstblk + byte entrylen, entriesblk + byte i, type, len + word entry, filecnt + + if ^optpath + strcpy(optpath, @path) + else + getpfx(@path) + prstr(@path) + crout + fin + refnum = open(@path, iobuffer); + if perr + return perr + fin + firstblk = 1 + repeat + if read(refnum, databuff, 512) == 512 + entry = databuff + 4 + if firstblk + entrylen = databuff.$23 + entriesblk = databuff.$24 + filecnt = databuff:$25 + entry = entry + entrylen + fin + for i = firstblk to entriesblk + type = ^entry + if type <> 0 + len = type & $0F + ^entry = len + prstr(entry) + if type & $F0 == $D0 ; Is it a directory? + cout('/') + len = len + 1 + fin + for len = 20 - len downto 1 + cout(' ') + next + filecnt = filecnt - 1 + fin + entry = entry + entrylen + next + firstblk = 0 + else + filecnt = 0 + fin + until filecnt == 0 + close(refnum) + crout + return 0 +end +def striplead(strptr, chr) + while ^strptr and ^(strptr + 1) == chr + memcpy(strptr + 2, strptr + 1, ^strptr) + ^strptr = ^strptr - 1 + loop +end +def parsecmd(strptr) + byte cmd + + cmd = 0 + striplead(strptr, $A0) + if ^strptr + cmd = ^(strptr + 1) + striplead(strptr, cmd) + fin + if ^strptr + striplead(strptr, $A0) + fin + return cmd & $7F +end +def upcase(chr) + if chr >= 'a' and chr <= 'z' + chr = chr - 'a' + 'A' + fin + return chr +end +def chkchng + if flags & changed + prstr(@losechng) + if upcase(keyin() & $7F) == 'N' + crout + return 0 + fin + crout + fin + return 1 +end +def quit + if chkchng + exit + fin +end +def cmdmode + byte slot + word cmdptr + + romcall(0, 0, 0, 0, $FC58) + crout + while 1 + prstr(@txtfile) + cmdptr = rdstr($BA) + when upcase(parsecmd(cmdptr)) + is 'A' + readtxt(cmdptr) + flags = flags ? changed + is 'R' + if chkchng + inittxtbuf + strcpy(cmdptr, @txtfile) + readtxt(@txtfile) + entrypoint = 0 + flags = flags & #changed + fin + is 'W' + if ^cmdptr + strcpy(cmdptr, @txtfile) + fin + writetxt(@txtfile) + if flags & changed + entrypoint = 0 + fin + flags = flags & #changed + is 'Q' + quit + is 'C' + prfiles(cmdptr) + is 'P' + setpfx(cmdptr) + is 'H' + if ^cmdptr + slot = cmdptr.1 & $7F - '0' + else + slot = 1 + fin + printtxt(slot) + is 'E' + return + is 0 + return + is 'N' + if chkchng + inittxtbuf + numlines = 1 + strcpy(@untitled, @txtfile) + fin + is 'X' + if flags & changed or !entrypoint + parse_module + if parserr + bell + cursrow = parserrln + scrntop = cursrow & $FFF8 + cursy = cursrow - scrntop + curscol = parserrpos + scrnleft = curscol & $FFE0 + cursx = curscol - scrnleft + else + crout + (entrypoint)() + fin + else + (entrypoint)() + fin + crout + is 'V' + prstr(@version) + wend + if perr + prstr(@errorstr) + romcall(perr, 0, 0, 0, $FDDA) + else + prstr(@okstr) + fin + crout + loop +end + +;===================================== +; +; PLASMA Compiler +; +;===================================== + +; +; Error handler +; +def parse_err(err) + if !parserr + parserr = TRUE + parserrln = lineno - 1 + parserrpos = tknptr - inbuff + print(lineno) + cout(':') + prstr(err) + crout + fin + return ERR_TKN +end +; +; Emit bytecode +; +def ctag_new + if codetag >= ctag_max + return parse_err(@ctag_full) + fin + codetag = codetag + 1 + ctag_value:[codetag] = 0 + ctag_flags.[codetag] = 0 + return codetag ? is_ctag +end +def ctag_resolve(tag, addr) + word updtptr, nextptr + + tag = tag & mask_ctag + if ctag_flags.[tag] & resolved + return parse_err(@dup_id) + fin + updtptr = ctag_value:[tag] + while updtptr + ; + ; Update list of addresses needing resolution + ; + nextptr = *updtptr + *updtptr = addr + updtptr = nextptr + loop + ctag_value:[tag] = addr + ctag_flags.[tag] = ctag_flags.[tag] ? resolved +end +defn emit_byte(bval) + ^codeptr = bval + codeptr = codeptr + 1 +end +defn emit_word(wval) + *codeptr = wval + codeptr = codeptr + 2 +end +def emit_fill(size) + memset(0, codeptr, size) + codeptr = codeptr + size +end +def emit_codetag(tag) + return ctag_resolve(tag, codeptr) +end +deft emit_op(op) + lastop = op + return emit_byte(op) +end +def emit_tag(tag) + word updtptr + + if tag & is_ctag + tag = tag & mask_ctag + updtptr = ctag_value:[tag] + if !(ctag_flags.[tag] & resolved) + ; + ; Add to list of tags needing resolution + ; + ctag_value:[tag] = codeptr + fin + emit_word(updtptr) + else + emit_word(tag + codebuff) + fin +end +def emit_iddata(value, size, namestr) + return emit_fill(size) +end +def emit_data(vartype, consttype, constval, constsize) + byte i + word size, chrptr + + if consttype == 0 + size = constsize + emit_fill(constsize) + elsif consttype == STR_TYPE + size = constsize + chrptr = constval + constsize = constsize - 1 + emit_byte(constsize) + while constsize > 0 + emit_byte(^chrptr) + chrptr = chrptr + 1 + constsize = constsize - 1 + loop + else + if vartype == WORD_TYPE + size = 2 + emit_word(constval) + else + size = 1 + emit_byte(constval) + fin + fin + return size +end +def emit_const(cval) + if cval == 0 + emit_op($00) + elsif cval > 0 and cval < 256 + emit_op($2A) + emit_byte(cval) + else + emit_op($2C) + emit_word(cval) + fin +end +def emit_lb + return emit_op($60) +end +def emit_lw + return emit_op($62) +end +def emit_llb(index) + emit_op($64) + return emit_byte(index) +end +def emit_llw(index) + emit_op($66) + return emit_byte(index) +end +def emit_lab(tag) + emit_op($68) + return emit_tag(tag) +end +def emit_law(tag) + emit_op($6A) + return emit_tag(tag) +end +def emit_sb + return emit_op($70) +end +def emit_sw + return emit_op($72) +end +def emit_slb(index) + emit_op($74) + return emit_byte(index) +end +def emit_slw(index) + emit_op($76) + return emit_byte(index) +end +def emit_dlb(index) + emit_op($6C) + return emit_byte(index) +end +def emit_dlw(index) + emit_op($6E) + return emit_byte(index) +end +def emit_sab(tag) + emit_op($78) + return emit_tag(tag) +end +def emit_saw(tag) + emit_op($7A) + return emit_tag(tag) +end +def emit_dab(tag) + emit_op($7C) + return emit_tag(tag) +end +def emit_daw(tag) + emit_op($7E) + return emit_tag(tag) +end +def emit_call(tag, cparams) + emit_op($54) + return emit_tag(tag) +end +def emit_ical(cparams) + emit_op($56) + return emit_byte(cparams) +end +def emit_push + emit_op($34) +end +def emit_pull + ; + ; Skip if last op was push + ; + if lastop == $34 + codeptr = codeptr - 1 + lastop = $FF + else + emit_op($36) + fin +end +def emit_localaddr(index) + emit_op($28) + return emit_byte(index) +end +def emit_globaladdr(tag) + emit_op($26) + return emit_tag(tag) +end +def emit_indexbyte + return emit_op($2E) +end +def emit_indexword + return emit_op($1E) +end +def emit_unaryop(op) + when op + is NEG_TKN + emit_op($10) + is COMP_TKN + emit_op($12) + is LOGIC_NOT_TKN + emit_op($20) + is INC_TKN + emit_op($0C) + is DEC_TKN + emit_op($0E) + is BPTR_TKN + emit_op($60) + is WPTR_TKN + emit_op($62) + otherwise + return FALSE + wend + return TRUE +end +def emit_binaryop(op) + when op + is MUL_TKN + ; + ; Replace MUL 2 with SHL 1 + ; + if lastop == $2A and ^(codeptr - 1) == 2 ; CB 2 + codeptr = codeptr - 1 + emit_byte(1) ; CB 1 + emit_op($1A) ; SHL + else + emit_op($06) + fin + is DIV_TKN + ; + ; Replace DIV 2 with SHR 1 + ; + if lastop == $2A and ^(codeptr - 1) == 2 ; CB 2 + codeptr = codeptr - 1 + emit_byte(1) ; CB 1 + emit_op($1C) ; SHR + else + emit_op($08) + fin + is MOD_TKN + emit_op($0A) + is ADD_TKN + ; + ; Replace ADD 1 with INCR + ; + if lastop == $2A and ^(codeptr - 1) == 1 ; CB 1 + codeptr = codeptr - 2 + emit_op($0C) ; INC_OP + else + emit_op($02) + fin + is SUB_TKN + ; + ; Replace SUB 1 with DECR + ; + if lastop == $2A and ^(codeptr - 1) == 1 ; CB 1 + codeptr = codeptr - 2 + emit_op($0E) ; DEC_OP + else + emit_op($04) + fin + is SHL_TKN + emit_op($1A) + is SHR_TKN + emit_op($1C) + is AND_TKN + emit_op($14) + is OR_TKN + emit_op($16) + is EOR_TKN + emit_op($18) + is EQ_TKN + emit_op($40) + is NE_TKN + emit_op($42) + is GE_TKN + emit_op($48) + is LT_TKN + emit_op($46) + is GT_TKN + emit_op($44) + is LE_TKN + emit_op($4A) + is LOGIC_OR_TKN + emit_op($22) + is LOGIC_AND_TKN + emit_op($24) + otherwise + return FALSE + wend + return TRUE +end +def emit_brtru(tag) + emit_op($4E) + return emit_tag(tag) +end +def emit_brfls(tag) + emit_op($4C) + return emit_tag(tag) +end +def emit_brgt(tag) + emit_op($3A) + return emit_tag(tag) +end +def emit_brlt(tag) + emit_op($38) + return emit_tag(tag) +end +def emit_brne(tag) + emit_op($3E) + return emit_tag(tag) +end +def emit_jump(tag) + emit_op($50) + return emit_tag(tag) +end +def emit_drop + return emit_op($30) +end +def emit_leave(framesize) + if framesize > 2 + emit_op($5A) + else + emit_op($5C) + fin +end +def emit_enter(framesize, cparams) + emit_byte(emit_enter.[0]) + emit_byte(emit_enter.[1]) + emit_byte(emit_enter.[2]) + if framesize > 2 + emit_op($58) + emit_byte(framesize) + emit_byte(cparams) + fin +end +def emit_start + ; + ; Save address + ; + entrypoint = codeptr + emit_byte(emit_start.[0]) + emit_byte(emit_start.[1]) + return emit_op(emit_start.[2]) +end +def emit_exit + emit_op($00) + return emit_op($5C) +end +; +; Lexical anaylzer +; +;defn isalpha(c) +; if c >= 'A' and c <= 'Z' +; return TRUE +; elsif c >= 'a' and c <= 'z' +; return TRUE +; elsif c == '_' +; return TRUE +; fin +; return FALSE +;end +asm isalpha + LDY #$00 + LDA ESTKL,X + CMP #'A' + BCC ISALRET + CMP #'Z'+1 + BCS :+ + DEY + BNE ISALRET +: CMP #'a' + BCC ISALRET + CMP #'z'+1 + BCS :+ + DEY + BNE ISALRET +: CMP #'_' + BNE ISALRET + DEY +ISALRET: + STY ESTKL,X + STY ESTKH,X + RTS +end +;defn isnum(c) +; if c >= '0' and c <= '9' +; return TRUE +; fin +; return FALSE +;end +asm isnum + LDY #$00 + LDA ESTKL,X + CMP #'0' + BCC :+ + CMP #'9'+1 + BCS :+ + DEY +: STY ESTKL,X + STY ESTKH,X + RTS +end +;defn isalphanum(c) +; if c >= 'A' and c <= 'Z' +; return TRUE +; elsif c >= '0' and c <= '9' +; return TRUE +; elsif c >= 'a' and c <= 'z' +; return TRUE +; elsif c == '_' +; return TRUE +; fin +; return FALSE +;end +asm isalphanum + LDY #$00 + LDA ESTKL,X + CMP #'0' + BCC ISANRET + CMP #'9'+1 + BCS :+ + DEY + BNE ISANRET +: CMP #'A' + BCC ISANRET + CMP #'Z'+1 + BCS :+ + DEY + BNE ISANRET +: CMP #'a' + BCC ISANRET + CMP #'z'+1 + BCS :+ + DEY + BNE ISANRET +: CMP #'_' + BNE ISANRET + DEY +ISANRET: + STY ESTKL,X + STY ESTKH,X + RTS +end +deft keymatch(chrptr, len) + byte i, keypos + + keypos = 0 + while keywrds[keypos] < len + keypos = keypos + keywrds[keypos] + 2 + loop + while keywrds[keypos] == len + for i = 1 to len + if toupper((chrptr).[i - 1]) <> keywrds[keypos + i] + break + fin + next + if i > len + return keywrds[keypos + keywrds[keypos] + 1] + fin + keypos = keypos + keywrds[keypos] + 2 + loop + return ID_TKN +end +def skipspace + ; + ; Skip whitespace + ; + while ^scanptr and ^scanptr <= ' ' + scanptr = scanptr + 1 + loop + tknptr = scanptr + return !^scanptr or ^scanptr == ';' +end +deft scan + ; + ; Scan for token based on first character + ; + if skipspace + if token <> EOF_TKN + token = EOL_TKN + fin + elsif isalpha(^scanptr) + ; + ; ID, either variable name or reserved word + ; + repeat + scanptr = scanptr + 1 + until !isalphanum(^scanptr) + tknlen = scanptr - tknptr; + token = keymatch(tknptr, tknlen) + elsif isnum(^scanptr) + ; + ; Number constant + ; + token = INT_TKN + constval = 0 + repeat + constval = constval * 10 + ^scanptr - '0' + scanptr = scanptr + 1 + until !isnum(^scanptr) + elsif ^scanptr == '$' + ; + ; Hexadecimal constant + ; + token = INT_TKN; + constval = 0 + repeat + scanptr = scanptr + 1 + if ^scanptr >= '0' and ^scanptr <= '9' + constval = (constval << 4) + ^scanptr - '0' + elsif ^scanptr >= 'A' and ^scanptr <= 'F' + constval = (constval << 4) + ^scanptr - '7'; 'A'-10 + elsif ^scanptr >= 'a' and ^scanptr <= 'f' + constval = (constval << 4) + ^scanptr - 'W'; 'a'-10 + else + break; + fin + until !^scanptr + elsif ^scanptr == $27 ; ' + ; + ; Character constant + ; + token = CHR_TKN + if ^(scanptr + 1) <> $5C ; \ + constval = ^(scanptr + 1) + if ^(scanptr + 2) <> $27 ; ' + return parse_err(@bad_cnst) + fin + scanptr = scanptr + 3 + else + when ^(scanptr + 2) + is 'n' + constval = $0D + is 'r' + constval = $0A + is 't' + constval = $09 + otherwise + constval = ^(scanptr + 2) + wend + if ^(scanptr + 3) <> $27 ; ' + return parse_err(@bad_cnst) + fin + scanptr = scanptr + 4 + fin + elsif ^scanptr == '"' + ; + ; String constant + ; + token = STR_TKN + scanptr = scanptr + 1 + constval = scanptr + while ^scanptr and ^scanptr <> '"' + scanptr = scanptr + 1 + loop + if !^scanptr + return parse_err(@bad_cnst) + fin + scanptr = scanptr + 1 + else + ; + ; Potential two and three character tokens + ; + when ^scanptr + is '>' + if ^(scanptr + 1) == '>' + token = SHR_TKN + scanptr = scanptr + 2 + elsif ^(scanptr + 1) == '=' + token = GE_TKN + scanptr = scanptr + 2 + else + token = GT_TKN + scanptr = scanptr + 1 + fin + is '<' + if ^(scanptr + 1) == '<' + token = SHL_TKN + scanptr = scanptr + 2 + elsif ^(scanptr + 1) == '=' + token = LE_TKN + scanptr = scanptr + 2 + elsif ^(scanptr + 1) == '>' + token = NE_TKN + scanptr = scanptr + 2 + else + token = LT_TKN + scanptr = scanptr + 1 + fin + is '=' + if ^(scanptr + 1) == '=' + token = EQ_TKN + scanptr = scanptr + 2; + else + token = SET_TKN; + scanptr = scanptr + 1 + fin + otherwise + ; + ; Simple single character tokens + ; + token = ^scanptr ? $80 + scanptr = scanptr + 1 + wend + fin + tknlen = scanptr - tknptr + return token +end +def rewind(ptr) + scanptr = ptr +end +; +; Get next line of input +; +def nextln +; if ^keyboard == $A0 +; ^keystrobe +; while ^keyboard < 128 +; loop +; ^keystrobe +; elsif ^keyboard == $82 +; lineno = numlines +; ^keystrobe +; fin + scanptr = inbuff + if lineno < numlines + cpyln(strlinbuf:[lineno], instr) + lineno = lineno + 1 + if !(lineno & $0F) + cout('.') + fin + ; cout('>') + ; prstr(instr) + ; crout + scan + else + ^instr = 0 + ^inbuff = $00 + token = DONE_TKN + fin + return ^instr +end +; +; Alebraic op to stack op +; +def push_op(op, prec) + opsp = opsp + 1 + if opsp == 16 + return parse_err(@estk_overflw) + fin + opstack[opsp] = op + precstack[opsp] = prec +end +def pop_op + if opsp < 0 + return parse_err(@estk_underflw) + fin + opsp = opsp - 1 + return opstack[opsp + 1] +end +def tos_op + if opsp < 0 + return 0 + fin + return opstack[opsp] +end +def tos_op_prec(tos) + if opsp <= tos + return 100 + fin + return precstack[opsp] +end +; +; Symbol table +; +deft idmatch(nameptr, len, idptr, idcnt) + byte i + + while idcnt + if len == (idptr).idname + for i = 1 to len + if (nameptr).[i - 1] <> (idptr).idname.[i] + break + fin + next + if i > len + return idptr + fin + fin + idptr = idptr + (idptr).idname + idrecsz + idcnt = idcnt - 1 + loop + return 0 +end +def dumpsym(idptr, idcnt) + while idcnt + prword((idptr):idval) + cout(' ') + prbyte((idptr).idtype) + cout(' ') + prstr(@(idptr).idname) + cout('=') + if (idptr).idtype & ADDR_TYPE + if (idptr):idval & is_ctag + prword(ctag_value:[(idptr):idval & mask_ctag]) + else + prword((idptr):idval + codebuff) + fin + else + prword((idptr):idval) + fin + crout + idptr = idptr + (idptr).idname + idrecsz + idcnt = idcnt - 1 + loop +end +def id_lookup(nameptr, len) + word idptr + + idptr = idmatch(nameptr, len, idlocal_tbl, locals) + if idptr + return idptr + fin + idptr = idmatch(nameptr, len, idglobal_tbl, globals) + if idptr + return idptr + fin + return parse_err(@undecl_id) +end +def idglobal_lookup(nameptr, len) + return idmatch(nameptr, len, idglobal_tbl, globals) +end +def idlocal_add(namestr, len, type, size) + if idmatch(namestr, len, @idlocal_tbl, locals) + return parse_err(@dup_id) + fin + (lastlocal):idval = framesize + (lastlocal).idtype = type ? LOCAL_TYPE + nametostr(namestr, len, lastlocal + idname) + locals = locals + 1 + lastlocal = lastlocal + idrecsz + len + if lastlocal > idlocal_tbl + idlocal_tblsz + prstr(@local_sym_overflw) + exit + fin + framesize = framesize + size + if framesize > 255 + prstr(@local_overflw) + return FALSE + fin + return TRUE +end +def iddata_add(namestr, len, type, size) + if idmatch(namestr, len, idglobal_tbl, globals) + return parse_err(@dup_id) + fin + (lastglobal):idval = datasize + (lastglobal).idtype = type + nametostr(namestr, len, lastglobal + idname) + emit_iddata(datasize, size, lastglobal + idname) + globals = globals + 1 + lastglobal = lastglobal + idrecsz + len + if lastglobal > idglobal_tbl + idglobal_tblsz + prstr(@global_sym_overflw) + exit + fin + datasize = datasize + size + return TRUE +end +def iddata_size(type, varsize, initsize) + if varsize > initsize + datasize = datasize + emit_data(0, 0, 0, varsize - initsize) + else + datasize = datasize + initsize + fin +; if datasize <> codeptr - codebuff +; prstr(@emiterr) +; keyin() +; fin +end +def idglobal_add(namestr, len, type, value) + if idmatch(namestr, len, idglobal_tbl, globals) + return parse_err(@dup_id) + fin + (lastglobal):idval = value + (lastglobal).idtype = type + nametostr(namestr, len, lastglobal + idname) + globals = globals + 1 + lastglobal = lastglobal + idrecsz + len + if lastglobal > idglobal_tbl + idglobal_tblsz + prstr(@global_sym_overflw) + exit + fin + return TRUE +end +def idfunc_add(namestr, len, tag) + return idglobal_add(namestr, len, FUNC_TYPE, tag) +end +def idconst_add(namestr, len, value) + return idglobal_add(namestr, len, CONST_TYPE, value) +end +def idglobal_init + word ctag + + lineno = 0 + parserr = 0 + codeptr = codebuff + lastop = $FF + entrypoint = 0 + datasize = 0 + globals = 0 + lastglobal = idglobal_tbl + codetag = -1 + ctag = ctag_new + idfunc_add(@runtime0 + 1, runtime0, ctag) + idfunc_add(@RUNTIME0 + 1, RUNTIME0, ctag) + ctag_resolve(ctag, @romcall) + ctag = ctag_new + idfunc_add(@runtime1 + 1, runtime1, ctag) + idfunc_add(@RUNTIME1 + 1, RUNTIME1, ctag) + ctag_resolve(ctag, @syscall) + ctag = ctag_new + idfunc_add(@runtime2 + 1, runtime2, ctag) + idfunc_add(@RUNTIME2 + 1, RUNTIME2, ctag) + ctag_resolve(ctag, @memset) + ctag = ctag_new + idfunc_add(@runtime3 + 1, runtime3, ctag) + idfunc_add(@RUNTIME3 + 1, RUNTIME3, ctag) + ctag_resolve(ctag, @memcpy) + ctag = ctag_new + idfunc_add(@runtime4 + 1, runtime4, ctag) + idfunc_add(@RUNTIME4 + 1, RUNTIME4, ctag) + ctag_resolve(ctag, @cout) + ctag = ctag_new + idfunc_add(@runtime5 + 1, runtime5, ctag) + idfunc_add(@RUNTIME5 + 1, RUNTIME5, ctag) + ctag_resolve(ctag, @cin) + ctag = ctag_new + idfunc_add(@runtime6 + 1, runtime6, ctag) + idfunc_add(@RUNTIME6 + 1, RUNTIME6, ctag) + ctag_resolve(ctag, @prstr) + ctag = ctag_new + idfunc_add(@runtime7 + 1, runtime7, ctag) + idfunc_add(@RUNTIME7 + 1, RUNTIME7, ctag) + ctag_resolve(ctag, @rdstr) +end +def idlocal_init + locals = 0 + framesize = 2 + lastlocal = idlocal_tbl +end +; +; Parser +; +def parse_term + when scan + is ID_TKN + return TRUE + is INT_TKN + return TRUE + is CHR_TKN + return TRUE + is STR_TKN + return TRUE + is OPEN_PAREN_TKN + if !parse_expr + return FALSE + fin + if token <> CLOSE_PAREN_TKN + return parse_err(@no_close_paren) + fin + return TRUE + wend + return FALSE +end +def parse_constval(valptr, sizeptr) + byte mod, type + word idptr + + mod = 0 + type = 0 + *valptr = 0 + while !parse_term + when token + is SUB_TKN + mod = mod ? 1 + is COMP_TKN + mod = mod ? 2 + is LOGIC_NOT_TKN + mod = mod ? 4 + is AT_TKN + mod = mod ? 8 + otherwise + return 0 + wend + loop + when token + is STR_TKN + *valptr = constval + ^sizeptr = tknlen - 1 + type = STR_TYPE + if mod + return parse_err(@bad_op) + fin + is CHR_TKN + *valptr = constval + ^sizeptr = 1 + type = BYTE_TYPE + is INT_TKN + *valptr = constval + ^sizeptr = 2 + type = WORD_TYPE + is ID_TKN + ^sizeptr = 2 + idptr = id_lookup(tknptr, tknlen) + if !idptr + return parse_err(@bad_cnst) + fin + type = (idptr).idtype + *valptr = (idptr):idval + if type & VAR_TYPE and !(mod & 8) + return parse_err(@bad_cnst) + fin + otherwise + return parse_err(@bad_cnst) + wend + if mod & 1 + *valptr = -*valptr + fin + if mod & 2 + *valptr = #*valptr + fin + if mod & 4 + *valptr = !*valptr + fin + return type +end +deft ispostop + scan + when token + is OPEN_PAREN_TKN + return TRUE + is OPEN_BRACKET_TKN + return TRUE + is DOT_TKN + return TRUE + is COLON_TKN + return TRUE + wend + return FALSE +end +def parse_value(rvalue) + byte cparams, deref, type, emit_val + word optos, idptr, value + byte elem_type, elem_size + word elem_offset + + deref = rvalue + optos = opsp + type = 0 + emit_val = FALSE + value = 0 + + ; + ; Parse pre-ops + ; + while !parse_term + when token + is ADD_TKN + is BPTR_TKN + if deref + push_op(token, 0) + else + type = type ? BPTR_TYPE + deref = deref + 1 + fin + is WPTR_TKN + if deref + push_op(token, 0) + else + type = type ? WPTR_TYPE + deref = deref + 1 + fin + is AT_TKN + deref = deref - 1 + is SUB_TKN + push_op(token, 0) + is COMP_TKN + push_op(token, 0) + is LOGIC_NOT_TKN + push_op(token, 0) + otherwise + return 0 + wend + loop + ; + ; Determine terminal type + ; + when token + is INT_TKN + type = type ? CONST_TYPE + value = constval + is CHR_TKN + type = type ? CONST_TYPE + value = constval + is ID_TKN + idptr = id_lookup(tknptr, tknlen) + if !idptr + return 0 + fin + if !(idptr).idtype + return 0 + fin + type = type ? (idptr).idtype + value = (idptr):idval + is CLOSE_PAREN_TKN + type = type ? WORD_TYPE + emit_val = TRUE + otherwise + return 0 + wend + ; + ; Constant optimizations + ; + if type & CONST_TYPE + cparams = TRUE + while optos < opsp and cparams + when tos_op + is NEG_TKN + pop_op + value = -value + is COMP_TKN + pop_op + value = #value + is LOGIC_NOT_TKN + pop_op + value = !value + otherwise + cparams = FALSE + wend + loop + fin + ; + ; Parse post-ops + ; + while ispostop + if token == OPEN_BRACKET_TKN + ; + ; Array + ; + if !emit_val + if type & ADDR_TYPE + if type & LOCAL_TYPE + emit_localaddr(value) + else + emit_globaladdr(value) + fin + elsif type & CONST_TYPE + emit_const(value) + fin + emit_val = TRUE + fin ; !emit_val + if type & PTR_TYPE + emit_lw + fin + if !parse_expr + return 0 + fin + if token <> CLOSE_BRACKET_TKN + return parse_err(@no_close_bracket) + fin + if type & WORD_TYPE + type = WPTR_TYPE + emit_indexword + else + type = BPTR_TYPE + emit_indexbyte + fin + elsif token == DOT_TKN or token == COLON_TKN + ; + ; Dot and Colon + ; + if token == DOT_TKN + elem_type = BPTR_TYPE + else + elem_type = WPTR_TYPE + fin + if parse_constval(@elem_offset, @elem_size) + ; + ; Constant structure offset + ; + if !emit_val + if type & VAR_TYPE + if type & LOCAL_TYPE + emit_localaddr(value + elem_offset) + else + ; emit_globaladdr(value + elem_offset) + emit_globaladdr(value) + emit_const(elem_offset) + emit_binaryop(ADD_TKN) + fin + elsif type & CONST_TYPE + value = value + elem_offset + emit_const(value) + else ; FUNC_TYPE + emit_globaladdr(value) + emit_const(elem_offset) + emit_binaryop(ADD_TKN) + fin + emit_val = TRUE + else + if elem_offset <> 0 + emit_const(elem_offset) + emit_binaryop(ADD_TKN) + fin + fin ; !emit_val + elsif token == OPEN_BRACKET_TKN + ; + ; Array of arrays + ; + if !emit_val + if type & ADDR_TYPE + if type & LOCAL_TYPE + emit_localaddr(value) + else + emit_globaladdr(value) + fin + elsif type & CONST_TYPE + emit_const(value) + fin + emit_val = TRUE + fin ; !emit_val + while parse_expr + if token <> COMMA_TKN + break + fin + emit_indexword + emit_lw + loop + if token <> CLOSE_BRACKET_TKN + return parse_err(@no_close_bracket) + fin + if elem_type & WPTR_TYPE + emit_indexword + else + emit_indexbyte + fin + else + return parse_err(@bad_offset) + fin + type = elem_type + elsif token == OPEN_PAREN_TKN + ; + ; Function call + ; + if !emit_val and type & VAR_TYPE + if type & LOCAL_TYPE + emit_localaddr(value) + else + emit_globaladdr(value) + fin + fin + if !(type & FUNC_CONST_TYPE) + emit_push + fin + cparams = 0 + while parse_expr + cparams = cparams + 1 + if token <> COMMA_TKN + break + fin + loop + if token <> CLOSE_PAREN_TKN + return parse_err(@no_close_paren) + fin + if type & FUNC_CONST_TYPE + emit_call(value, cparams) + else + emit_pull + emit_ical(cparams) + fin + emit_val = TRUE + type = WORD_TYPE + fin + loop + if emit_val + if rvalue + if deref and type & PTR_TYPE + if type & BPTR_TYPE + emit_lb + else + emit_lw + fin + fin + fin + else ; emit_val + if type & CONST_TYPE + emit_const(value) + elsif deref + if type & FUNC_TYPE + emit_call(value, 0) + elsif type & VAR_TYPE + if type & LOCAL_TYPE + if type & BYTE_TYPE + emit_llb(value) + else + emit_llw(value) + fin + else + if type & BYTE_TYPE + emit_lab(value) + else + emit_law(value) + fin + fin + elsif type & PTR_TYPE + if type & BPTR_TYPE + emit_lb + else + emit_lw + fin + fin + else + if type & LOCAL_TYPE + emit_localaddr(value) + else + emit_globaladdr(value) + fin + fin + fin ; emit_val + while optos < opsp + if !emit_unaryop(pop_op) + return parse_err(@bad_op) + fin + loop + return type +end +def parse_constexpr(valptr, sizeptr) + byte type, size1, size2 + word val1, val2 + + type = parse_constval(@val1, @size1) + if !type + return 0 + fin + size2 = 0 + when scan + is ADD_TKN + type = parse_constval(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 + val2 + is SUB_TKN + type = parse_constval(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 - val2 + is MUL_TKN + type = parse_constval(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 * val2 + is DIV_TKN + type = parse_constval(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 + val2 + is MOD_TKN + type = parse_constval(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 % val2 + is AND_TKN + type = parse_constval(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 & val2 + is OR_TKN + type = parse_constval(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 ? val2 + is EOR_TKN + type = parse_constval(@val2, @size2) + if !type + return 0 + fin + *valptr = val1 ^ val2 + otherwise + *valptr = val1 + wend + if size1 > size2 + ^sizeptr = size1 + else + ^sizeptr = size2 + fin + return type +end +def parse_expr + byte prevmatch, matchop, i + word optos + + matchop = 0 + optos = opsp + repeat + prevmatch = matchop + matchop = 0 + if parse_value(1) + matchop = 1 + for i = 0 to bops_tblsz + if token == bops_tbl[i] + matchop = 2 + if bops_prec[i] >= tos_op_prec(optos) + if !emit_binaryop(pop_op) + return parse_err(@bad_op) + fin + fin + push_op(token, bops_prec[i]) + break + fin + next + fin + until matchop <> 2 + if matchop == 0 and prevmatch == 2 + return parse_err(@missing_op) + fin + while optos < opsp + if !emit_binaryop(pop_op) + return parse_err(@bad_op) + fin + loop + return matchop or prevmatch +end +def parse_stmnt + byte type, i + word tag_prevbrk, tag_else, tag_endif, tag_while, tag_wend + word tag_repeat, tag_for, tag_choice, idptr, saveptr, addr, stepdir + + if token <> END_TKN and token <> DONE_TKN + prevstmnt = token + fin + when token + is IF_TKN + if !parse_expr + return 0 + fin + tag_else = ctag_new + tag_endif = ctag_new + emit_brfls(tag_else) + scan + repeat + while parse_stmnt + nextln + loop + if token <> ELSEIF_TKN + break + fin + emit_jump(tag_endif) + emit_codetag(tag_else) + if !parse_expr + return 0 + fin + tag_else = ctag_new + emit_brfls(tag_else) + until FALSE + if token == ELSE_TKN + emit_jump(tag_endif) + emit_codetag(tag_else) + scan + while parse_stmnt + nextln + loop + emit_codetag(tag_endif) + else + emit_codetag(tag_else) + emit_codetag(tag_endif) + fin + if token <> FIN_TKN + return parse_err(@no_fin) + fin + is FOR_TKN + stack_loop = stack_loop + 1 + tag_for = ctag_new + tag_prevbrk = break_tag + break_tag = ctag_new + if scan <> ID_TKN + return parse_err(@bad_stmnt) + fin + idptr = id_lookup(tknptr, tknlen) + if idptr + type = (idptr).idtype + addr = (idptr):idval + else + return FALSE + fin + if scan <> SET_TKN + return parse_err(@bad_stmnt) + fin + if !parse_expr + return parse_err(@bad_stmnt) + fin + emit_codetag(tag_for) + if type & LOCAL_TYPE + if type & BYTE_TYPE + emit_dlb(addr) + else + emit_dlw(addr) + fin + else + if type & BYTE_TYPE + emit_dab(addr) + else + emit_daw(addr) + fin + fin + if token == TO_TKN + stepdir = 1 + elsif token == DOWNTO_TKN + stepdir = -1 + else + return parse_err(@bad_stmnt) + fin + if !parse_expr + return parse_err(@bad_stmnt) + fin + if stepdir > 0 + emit_brgt(break_tag) + else + emit_brlt(break_tag) + fin + if token == STEP_TKN + if !parse_expr + return parse_err(@bad_stmnt) + fin + if stepdir > 0 + emit_binaryop(ADD_TKN) + else + emit_binaryop(SUB_TKN) + fin + else + if stepdir > 0 + emit_unaryop(INC_TKN) + else + emit_unaryop(DEC_TKN) + fin + fin + while parse_stmnt + nextln + loop + if token <> NEXT_TKN + return parse_err(@bad_stmnt) + fin + emit_jump(tag_for) + emit_codetag(break_tag) + emit_drop + break_tag = tag_prevbrk + stack_loop = stack_loop - 1 + is WHILE_TKN + tag_while = ctag_new + tag_wend = ctag_new + tag_prevbrk = break_tag + break_tag = tag_wend + emit_codetag(tag_while) + if !parse_expr + return 0 + fin + emit_brfls(tag_wend) + while parse_stmnt + nextln + loop + if token <> LOOP_TKN + return parse_err(@no_loop) + fin + emit_jump(tag_while) + emit_codetag(tag_wend) + break_tag = tag_prevbrk + is REPEAT_TKN + tag_repeat = ctag_new + tag_prevbrk = break_tag + break_tag = ctag_new + emit_codetag(tag_repeat) + scan + while parse_stmnt + nextln + loop + if token <> UNTIL_TKN + return parse_err(@no_until) + fin + if !parse_expr + return 0 + fin + emit_brfls(tag_repeat) + emit_codetag(break_tag) + break_tag = tag_prevbrk + is CASE_TKN + stack_loop = stack_loop + 1 + tag_choice = ctag_new + tag_prevbrk = break_tag + break_tag = ctag_new + if !parse_expr + return parse_err(@bad_stmnt) + fin + nextln + while token <> ENDCASE_TKN + when token + is OF_TKN + if !parse_expr + return parse_err(@bad_stmnt) + fin + emit_brne(tag_choice) + while parse_stmnt + nextln + loop + emit_jump(break_tag) + emit_codetag(tag_choice) + tag_choice = ctag_new + is DEFAULT_TKN + scan + while parse_stmnt + nextln + loop + if token <> ENDCASE_TKN + return parse_err(@bad_stmnt) + fin + otherwise + return parse_err(@bad_stmnt) + wend + loop + emit_codetag(break_tag) + emit_drop + break_tag = tag_prevbrk + stack_loop = stack_loop - 1 + is BREAK_TKN + if break_tag + emit_jump(break_tag) + else + return parse_err(@bad_stmnt) + fin + is RETURN_TKN + if infunc + for i = 1 to stack_loop + emit_drop + next + if !parse_expr + emit_const(0) + fin + emit_leave(framesize) + else + return parse_err(@bad_stmnt) + fin + is EXIT_TKN + if !parse_expr + emit_const(0) + fin + emit_exit + is ELSE_TKN + return FALSE + is ELSEIF_TKN + return FALSE + is FIN_TKN + return FALSE + is LOOP_TKN + return FALSE + is UNTIL_TKN + return FALSE + is NEXT_TKN + return FALSE + is OF_TKN + return FALSE + is DEFAULT_TKN + return FALSE + is ENDCASE_TKN + return FALSE + is END_TKN + return FALSE + is DONE_TKN + return FALSE + is IFUNC_TKN + return FALSE + is TFUNC_TKN + return FALSE + is NFUNC_TKN + return FALSE + is EOF_TKN + return FALSE + is EOL_TKN + return TRUE + otherwise + if token == ID_TKN + saveptr = tknptr + idptr = id_lookup(tknptr, tknlen) + if !idptr + return FALSE + fin + type = (idptr).idtype + if type & ADDR_TYPE + addr = (idptr):idval + if scan == SET_TKN + if type & VAR_TYPE + if !parse_expr + return parse_err(@bad_expr) + fin + if type & LOCAL_TYPE + if type & BYTE_TYPE + emit_slb(addr) + else + emit_slw(addr) + fin + else + if type & BYTE_TYPE + emit_sab(addr) + else + emit_saw(addr) + fin + fin + return TRUE + fin + elsif token == EOL_TKN and type & FUNC_TYPE + emit_call(addr, 0) + emit_drop + return TRUE + fin + fin + tknptr = saveptr + fin + rewind(tknptr) + type = parse_value(0) + if type + if token == SET_TKN + if !parse_expr + return parse_err(@bad_expr) + fin + if type & XBYTE_TYPE + emit_sb + else + emit_sw + fin + else + if type & BPTR_TYPE + emit_lb + elsif type & WPTR_TYPE + emit_lw + fin + emit_drop + fin + else + return parse_err(@bad_syntax) + fin + wend + if scan <> EOL_TKN + return parse_err(@bad_syntax) + fin + return TRUE +end +def parse_var(type) + byte consttype, constsize, idlen + word idptr, constval, arraysize, size + + idlen = 0 + size = 1 + if scan == ID_TKN + idptr = tknptr + idlen = tknlen + if scan == OPEN_BRACKET_TKN + size = 0 + parse_constexpr(@size, @constsize) + if token <> CLOSE_BRACKET_TKN + return parse_err(@no_close_bracket) + fin + scan + fin + fin + if type == WORD_TYPE + size = size * 2 + fin + if token == SET_TKN + if infunc + return parse_err(@no_local_init) + fin + if idlen + iddata_add(idptr, idlen, type, 0) + fin + consttype = parse_constexpr(@constval, @constsize) + if consttype + arraysize = emit_data(type, consttype, constval, constsize) + while token == COMMA_TKN + consttype = parse_constexpr(@constval, @constsize) + if consttype + arraysize = arraysize + emit_data(type, consttype, constval, constsize) + else + return parse_err(@bad_decl) + fin + loop + if token <> EOL_TKN + return parse_err(@no_close_bracket) + fin + iddata_size(PTR_TYPE, size, arraysize); + else + return parse_err(@bad_decl) + fin + elsif idlen + if infunc + idlocal_add(idptr, idlen, type, size) + else + iddata_add(idptr, idlen, type, size) + fin + fin + return TRUE +end +def parse_vars + byte idlen, type, size + word value, idptr + + when token + is CONST_TKN + if scan <> ID_TKN + return parse_err(@bad_cnst) + fin + idptr = tknptr; + idlen = tknlen + if scan <> SET_TKN + return parse_err(@bad_cnst) + fin + if !parse_constexpr(@value, @size) + return parse_err(@bad_cnst) + fin + idconst_add(idptr, idlen, value) + is BYTE_TKN + type = BYTE_TYPE + repeat + if !parse_var(type) + return FALSE + fin + until token <> COMMA_TKN + is WORD_TKN + type = WORD_TYPE + repeat + if !parse_var(type) + return FALSE + fin + until token <> COMMA_TKN + is FUNC_TKN + repeat + if scan == ID_TKN + idfunc_add(tknptr, tknlen, ctag_new) + else + return parse_err(@bad_decl) + fin + until scan <> COMMA_TKN + is EOL_TKN + return TRUE + otherwise + return FALSE + wend + return TRUE +end +def parse_func + byte defopt, cfnparms + word func_tag, idptr + + if token == IFUNC_TKN or token == TFUNC_TKN or token == NFUNC_TKN + defopt = token - IFUNC_TKN + if scan <> ID_TKN + return parse_err(@bad_decl) + fin + cfnparms = 0 + infunc = TRUE + idptr = idglobal_lookup(tknptr, tknlen) + if idptr + func_tag = (idptr):idval + else + func_tag = ctag_new + idfunc_add(tknptr, tknlen, func_tag) + fin + emit_codetag(func_tag) + retfunc_tag = ctag_new + idlocal_init + if scan == OPEN_PAREN_TKN + repeat + if scan == ID_TKN + cfnparms = cfnparms + 1 + idlocal_add(tknptr, tknlen, WORD_TYPE, 2) + scan + fin + until token <> COMMA_TKN + if token <> CLOSE_PAREN_TKN + return parse_err(@bad_decl) + fin + scan + fin + while parse_vars + nextln + loop + emit_enter(framesize, cfnparms) + prevstmnt = 0 + while parse_stmnt + nextln + loop + infunc = FALSE + if token <> END_TKN + return parse_err(@bad_syntax) + fin + if scan <> EOL_TKN + return parse_err(@bad_syntax) + fin + if prevstmnt <> RETURN_TKN + emit_const(0) + emit_leave(framesize) + fin + return TRUE + elsif token == EOL_TKN + return TRUE + fin + return FALSE +end +def parse_module + entrypoint = 0 + idglobal_init + idlocal_init + if nextln + while parse_vars + nextln + loop + while parse_func + nextln + loop + if token <> DONE_TKN + emit_start + prevstmnt = 0 + while parse_stmnt + nextln + loop + if token <> DONE_TKN + parse_err(@no_done) + fin + if prevstmnt <> EXIT_TKN + emit_const(0) + emit_exit + fin + fin + ; dumpsym(idglobal_tbl, globals) + ; prstr(@entrypt_str) + ; prword(entrypoint) + ; crout + ; keyin() + return TRUE + fin + return FALSE +end +; +; Init editor +; +if !(^machid & $80) + flags = uppercase ? shiftlock + keyin = @keyin2 +else + keyin = @keyin2e +fin +inittxtbuf +if ^argbuff + strcpy(argbuff, @txtfile) + prstr(@txtfile) + readtxt(@txtfile) +else + numlines = 1 +fin +curschr = '+' +flags = flags ? insmode +drawscrn(scrntop, scrnleft) +curson +editmode +done diff --git a/plasma3/plvm b/plasma3/plvm new file mode 100755 index 0000000..a2dd00a Binary files /dev/null and b/plasma3/plvm differ diff --git a/plasma3/plvm.c b/plasma3/plvm.c new file mode 100755 index 0000000..d2fdfbf --- /dev/null +++ b/plasma3/plvm.c @@ -0,0 +1,895 @@ +#include +#include +#include +#include + +typedef unsigned char code; +typedef unsigned char byte; +typedef signed short word; +typedef unsigned short uword; +typedef unsigned short address; +/* + * Debug + */ +int show_state = 0; +/* + * Bytecode memory + */ +#define BYTE_PTR(bp) ((byte)(*bp++)) +#define WORD_PTR(bp) ((word)(*bp++|(*++bp << 8))) +#define UWORD_PTR(bp) ((uword)(*bp++|(*++bp << 8))) +#define MOD_ADDR 0x1000 +#define DEF_CALL 0x0800 +#define DEF_CALLSZ 0x0800 +#define DEF_ENTRYSZ 6 +#define MEM_SIZE 65536 +byte mem_data[MEM_SIZE], mem_code[MEM_SIZE]; +byte *mem_bank[2] = {mem_data, mem_code}; +uword sp = 0x01FE, fp = 0xBEFF, heap = 0x6000, xheap = 0x0800, deftbl = DEF_CALL, lastdef = DEF_CALL; + +#define EVAL_STACKSZ 16 +#define PUSH(v) (*(--esp))=(v) +#define POP (*(esp++)) +#define UPOP ((uword)(*(esp++))) +#define TOS (esp[0]) +word eval_stack[EVAL_STACKSZ]; +word *esp = eval_stack + EVAL_STACKSZ; + +#define SYMTBLSZ 1024 +#define SYMSZ 16 +#define MODTBLSZ 128 +#define MODSZ 16 +#define MODLSTSZ 32 +byte symtbl[SYMTBLSZ]; +byte *lastsym = symtbl; +byte modtbl[MODTBLSZ]; +byte *lastmod = modtbl; +/* + * Utility routines. + * + * A DCI string is one that has the high bit set for every character except the last. + * More efficient than C or Pascal strings. + */ +int dcitos(byte *dci, char *str) +{ + int len = 0; + do + str[len] = *dci & 0x7F; + while ((len++ < 15) && (*dci++ & 0x80)); + str[len] = 0; + return len; +} +int stodci(char *str, byte *dci) +{ + int len = 0; + do + dci[len] = toupper(*str) | 0x80; + while (*str++ && (len++ < 15)); + dci[len - 1] &= 0x7F; + return len; +} + +/* + * Heap routines. + */ +uword avail_heap(void) +{ + return fp - heap; +} +uword alloc_heap(int size) +{ + uword addr = heap; + heap += size; + if (heap >= fp) + { + printf("Error: heap/frame collision.\n"); + exit (1); + } + return addr; +} +uword free_heap(int size) +{ + heap -= size; + return fp - heap; +} +uword mark_heap(void) +{ + return heap; +} +int release_heap(uword newheap) +{ + heap = newheap; + return fp - heap; +} +uword avail_xheap(void) +{ + return 0xC000 - xheap; +} +uword alloc_xheap(int size) +{ + uword addr = xheap; + xheap += size; + if (xheap >= 0xC000) + { + printf("Error: xheap extinguished.\n"); + exit (1); + } + return addr; +} +uword free_xheap(int size) +{ + xheap -= size; + return 0xC000 - heap; +} +uword mark_xheap(void) +{ + return xheap; +} +int release_xheap(uword newxheap) +{ + xheap = newxheap; + return 0xC000 - xheap; +} +/* + * Copy from data mem to code mem. + */ +void xmemcpy(uword src, uword dst, uword size) +{ + while (size--) + mem_code[dst + size] = mem_data[src + size]; +} +/* + * Copy from code mem to data mem. + */ +void memxcpy(uword src, uword dst, uword size) +{ + while (size--) + mem_data[dst + size] = mem_code[src + size]; +} +/* + * DCI table routines, + */ +void dump_tbl(byte *tbl) +{ + int len; + byte *entbl; + while (*tbl) + { + len = 0; + while (*tbl & 0x80) + { + putchar(*tbl++ & 0x7F); + len++; + } + putchar(*tbl++); + putchar(':'); + while (len++ < 15) + putchar(' '); + printf("$%04X\n", tbl[0] | (tbl[1] << 8)); + tbl += 2; + } +} +uword lookup_tbl(byte *dci, byte *tbl) +{ + char str[20]; + byte *match, *entry = tbl; + while (*entry) + { + match = dci; + while (*entry == *match) + { + if ((*entry & 0x80) == 0) + return entry[1] | (entry[2] << 8); + entry++; + match++; + } + while (*entry++ & 0x80); + entry += 2; + } + dcitos(dci, str); + return 0; +} +int add_tbl(byte *dci, int val, byte *tbl, byte **last) +{ + while (*dci & 0x80) + *(*last)++ = *dci++; + *(*last)++ = *dci++; + *(*last)++ = val; + *(*last)++ = val >> 8; +} + +/* + * Symbol table routines. + */ +void dump_sym(void) +{ + printf("\nSystem Symbol Table:\n"); + dump_tbl(symtbl); +} +uword lookup_sym(byte *sym) +{ + return lookup_tbl(sym, symtbl); +} +int add_sym(byte *sym, int addr) +{ + return add_tbl(sym, addr, symtbl, &lastsym); +} + +/* + * Module routines. + */ +void dump_mod(void) +{ + printf("\nSystem Module Table:\n"); + dump_tbl(modtbl); +} +uword lookup_mod(byte *mod) +{ + return lookup_tbl(mod, modtbl); +} +int add_mod(byte *mod, int addr) +{ + return add_tbl(mod, addr, symtbl, &lastmod); +} +defcall_add(int bank, int addr) +{ + mem_data[lastdef] = bank ? 2 : 1; + mem_data[lastdef + 1] = addr; + mem_data[lastdef + 2] = addr >> 8; + return lastdef++; +} +int def_lookup(byte *cdd, int defaddr) +{ + int i, calldef = 0; + for (i = 0; cdd[i * 4] == 0x02; i++) + { + if ((cdd[i * 4 + 1] | (cdd[i * 4 + 2] << 8)) == defaddr) + { + calldef = cdd + i * 4 - mem_data; + break; + } + } + return calldef; +} +int extern_lookup(byte *esd, int index) +{ + byte *sym; + char string[32]; + while (*esd) + { + sym = esd; + esd += dcitos(esd, string); + if ((esd[0] & 0x10) && (esd[1] == index)) + return lookup_sym(sym); + esd += 3; + } + printf("\nError: extern index %d not found in ESD.\n", index); + return 0; +} +int load_mod(byte *mod) +{ + int len, size, end, magic, bytecode, fixup, addr, modaddr = mark_heap(); + byte *moddep, *rld, *esd, *cdd, *sym; + byte header[128]; + char filename[32], string[17]; + + dcitos(mod, filename); + printf("Load module %s\n"); + int fd = open(filename, O_RDONLY, 0); + if ((fd > 0) && (len = read(fd, header, 128)) > 0) + { + magic = header[2] | (header[3] << 8); + if (magic == 0xDA7E) + { + /* + * This is a relocatable bytecode module. + */ + bytecode = header[4] | (header[5] << 8); + moddep = header + 6; + if (*moddep) + { + /* + * Load module dependencies. + */ + close(fd); + while (*moddep) + { + if (lookup_mod(moddep) == 0) + load_mod(moddep); + moddep += dcitos(moddep, string); + } + modaddr = mark_heap(); + fd = open(filename, O_RDONLY, 0); + len = read(fd, mem_data + modaddr, 128); + } + else + memcpy(mem_data + modaddr, header, len); + } + addr = modaddr + len; + while ((len = read(fd, mem_data + addr, 4096)) > 0) + addr += len; + close(fd); + size = addr - modaddr; + len = mem_data[modaddr + 0] | (mem_data[modaddr + 1] << 8); + end = modaddr + len; + rld = mem_data + modaddr + len; // Re-Locatable Directory + esd = rld; // Extern+Entry Symbol Directory + bytecode += modaddr - MOD_ADDR; + while (*esd != 0x00) // Scan to end of RLD + esd += 4; + esd++; + cdd = rld; + if (show_state) + { + /* + * Dump different parts of module. + */ + printf("Module size: %d\n", size); + printf("Module code+data size: %d\n", len); + printf("Module magic: $%04X\n", magic); + printf("Module bytecode: $%04X\n", bytecode); + } + /* + * Print out the Re-Location Dictionary. + */ + if (show_state) + printf("\nRe-Location Dictionary:\n"); + while (*rld) + { + if (rld[0] == 0x02) + { + if (show_state) printf("\tDEF CODE"); + addr = rld[1] | (rld[2] << 8); + addr += modaddr - MOD_ADDR; + rld[1] = addr; + rld[2] = addr >> 8; + end = rld - mem_data + 4; + } + else + { + addr = rld[1] | (rld[2] << 8); + addr += modaddr - MOD_ADDR; + if (rld[0] & 0x80) + fixup = mem_data[addr] | (mem_data[addr + 1] << 8); + else + fixup = mem_data[addr]; + if (rld[0] & 0x10) + { + if (show_state) printf("\tEXTERN[$%02X] ", rld[3]); + fixup += extern_lookup(esd, rld[3]); + } + else + { + if (show_state) printf("\tINTERN "); + fixup += modaddr - MOD_ADDR; + if (fixup >= bytecode) + /* + * Replace with call def dictionary. + */ + fixup = def_lookup(cdd, fixup); + } + if (rld[0] & 0x80) + { + if (show_state) printf("WORD"); + mem_data[addr] = fixup; + mem_data[addr + 1] = fixup >> 8; + } + else + { + if (show_state) printf("BYTE"); + mem_data[addr] = fixup; + } + + } + if (show_state) printf("@$%04X\n", addr); + rld += 4; + } + if (show_state) printf("\nExternal/Entry Symbol Directory:\n"); + while (*esd) + { + sym = esd; + esd += dcitos(esd, string); + if (esd[0] & 0x10) + { + if (show_state) printf("\tIMPORT %s[$%02X]\n", string, esd[1]); + } + else if (esd[0] & 0x08) + { + addr = esd[1] | (esd[2] << 8); + addr += modaddr - MOD_ADDR; + if (show_state) printf("\tEXPORT %s@$%04X\n", string, addr); + if (addr >= bytecode) + addr = def_lookup(cdd, addr); + add_sym(sym, addr); + } + esd += 3; + } + } + else + { + printf("Error: Unable to load module %s\n", filename); + exit (1); + } + /* + * Reserve heap space for relocated module. + */ + alloc_heap(end - modaddr); + return (fd > 0); +} +void interp(code *ip); + +void call(word pc) +{ + int i, s; + char sz[64]; + + switch (mem_data[pc++]) + { + case 0: // NULL call + printf("NULL call code\n"); + break; + case 1: // BYTECODE in mem_code + interp(mem_code + (mem_data[pc] + (mem_data[pc + 1] << 8))); + break; + case 2: // BYTECODE in mem_data + interp(mem_data + (mem_data[pc] + (mem_data[pc + 1] << 8))); + break; + case 3: // LIBRARY STDLIB::VIEWPORT + printf("Set Window %d, %d, %d, %n/n", POP, POP, POP, POP); + PUSH(0); + break; + case 4: // LIBRARY STDLIB::PUTC + putchar(POP); + PUSH(0); + break; + case 5: // LIBRARY STDLIB::PUTS + s = POP; + i = mem_data[s++]; + PUSH(i); + while (i--) + putchar(mem_data[s++]); + break; + case 6: // LIBRARY STDLIB::PUTSZ + s = POP; + while (i = mem_data[s++]) + { + if (i == '\r') + i = '\n'; + putchar(i); + } + PUSH(0); + break; + case 7: // LIBRARY STDLIB::GETC + PUSH(getchar()); + break; + case 8: // LIBRARY STDLIB::GETS + gets(sz); + i = 0; + while (sz[i]) + mem_data[0x200 + i++] = sz[i]; + mem_data[0x200 + i] = 0; + mem_data[0x1FF] = i; + PUSH(i); + break; + case 9: // LIBRARY STDLIB::CLS + puts("\033[2J"); + fflush(stdout); + PUSH(0); + PUSH(0); + case 10: // LIBRARY STDLIB::GOTOXY + s = POP + 1; + i = POP + 1; + printf("\033[%d;%df", s, i); + fflush(stdout); + PUSH(0); + break; + default: + printf("Bad call code\n"); + } +} + +/* + * OPCODE TABLE + * +OPTBL: DW ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E + DW NEG,COMP,AND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E + DW NOT,LOR,LAND,LA,LLA,CB,CW,SWAP ; 20 22 24 26 28 2A 2C 2E + DW DROP,DUP,PUSH,PULL,BRGT,BRLT,BREQ,BRNE ; 30 32 34 36 38 3A 3C 3E + DW ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E + DW BRNCH,IBRNCH,CALL,ICAL,ENTER,LEAVE,RET,??? ; 50 52 54 56 58 5A 5C 5E + DW LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E + DW SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E +*/ +void interp(code *ip) +{ + word val, ea, frmsz, parmcnt; + + while (1) + { + if (show_state) + { + word *dsp = &eval_stack[EVAL_STACKSZ - 1]; + printf("$%04X: $%02X [ ", ip - mem_data, *ip); + while (dsp >= esp) + printf("$%04X ", (*dsp--) & 0xFFFF); + printf("]\n"); + } + switch (*ip++) + { + /* + * 0x00-0x0F + */ + case 0x00: // ZERO : TOS = 0 + PUSH(0); + break; + case 0x02: // ADD : TOS = TOS + TOS-1 + val = POP; + ea = POP; + PUSH(ea + val); + break; + case 0x04: // SUB : TOS = TOS-1 - TOS + val = POP; + ea = POP; + PUSH(ea - val); + break; + case 0x06: // MUL : TOS = TOS * TOS-1 + val = POP; + ea = POP; + PUSH(ea * val); + break; + case 0x08: // DIV : TOS = TOS-1 / TOS + val = POP; + ea = POP; + PUSH(ea / val); + break; + case 0x0A: // MOD : TOS = TOS-1 % TOS + val = POP; + ea = POP; + PUSH(ea % val); + break; + case 0x0C: // INCR : TOS = TOS + 1 + TOS++; + break; + case 0x0E: // DECR : TOS = TOS - 1 + TOS--; + break; + /* + * 0x10-0x1F + */ + case 0x10: // NEG : TOS = -TOS + TOS = -TOS; + break; + case 0x12: // COMP : TOS = ~TOS + TOS = ~TOS; + break; + case 0x14: // AND : TOS = TOS & TOS-1 + val = POP; + ea = POP; + PUSH(ea & val); + break; + case 0x16: // IOR : TOS = TOS ! TOS-1 + val = POP; + ea = POP; + PUSH(ea | val); + break; + case 0x18: // XOR : TOS = TOS ^ TOS-1 + val = POP; + ea = POP; + PUSH(ea ^ val); + break; + case 0x1A: // SHL : TOS = TOS-1 << TOS + val = POP; + ea = POP; + PUSH(ea << val); + break; + case 0x1C: // SHR : TOS = TOS-1 >> TOS + val = POP; + ea = POP; + PUSH(ea >> val); + break; + case 0x1E: // IDXW : TOS = TOS * 2 + TOS *= 2; + break; + /* + * 0x20-0x2F + */ + case 0x20: // NOT : TOS = !TOS + TOS = !TOS; + break; + case 0x22: // LOR : TOS = TOS || TOS-1 + val = POP; + ea = POP; + PUSH(ea || val); + break; + case 0x24: // LAND : TOS = TOS && TOS-1 + val = POP; + ea = POP; + PUSH(ea && val); + break; + case 0x26: // LA : TOS = @VAR ; equivalent to CW ADDRESSOF(VAR) + PUSH(WORD_PTR(ip)); + break; + case 0x28: // LLA : TOS = @LOCALVAR ; equivalent to CW FRAMEPTR+OFFSET(LOCALVAR) + PUSH(fp + BYTE_PTR(ip)); + break; + case 0x2A: // CB : TOS = CONSTANTBYTE (IP) + PUSH(BYTE_PTR(ip)); + break; + case 0x2C: // CW : TOS = CONSTANTWORD (IP) + PUSH(WORD_PTR(ip)); + break; + case 0x2E: // SWAP : TOS = TOS-1, TOS-1 = TOS + val = POP; + ea = POP; + PUSH(val); + PUSH(ea); + break; + /* + * 0x30-0x3F + */ + case 0x30: // DROP : TOS = + esp++;; + break; + case 0x32: // DUP : TOS = TOS + val = TOS; + PUSH(val); + break; + case 0x34: // PUSH : TOSP = TOS + val = POP; + mem_data[sp--] = val >> 8; + mem_data[sp--] = val; + break; + case 0x36: // PULL : TOS = TOSP + PUSH(mem_data[++sp] | (mem_data[++sp] << 8)); + break; + case 0x38: // BRGT : TOS-1 > TOS ? IP += (IP) + val = POP; + ea = POP; + if (ea <= val) + ip += WORD_PTR(ip) - 2; + else + ip += 2; + break; + case 0x3A: // BRLT : TOS-1 < TOS ? IP += (IP) + val = POP; + ea = TOS; + if (ea >= val) + ip += WORD_PTR(ip) - 2; + else + ip += 2; + break; + case 0x3C: // BREQ : TOS == TOS-1 ? IP += (IP) + val = POP; + ea = TOS; + if (ea == val) + ip += WORD_PTR(ip) - 2; + else + ip += 2; + break; + case 0x3E: // BRNE : TOS != TOS-1 ? IP += (IP) + val = POP; + ea = TOS; + if (ea != val) + ip += WORD_PTR(ip) - 2; + else + ip += 2; + break; + /* + * 0x40-0x4F + */ + case 0x40: // ISEQ : TOS = TOS == TOS-1 + val = POP; + ea = POP; + PUSH(ea == val); + break; + case 0x42: // ISNE : TOS = TOS != TOS-1 + val = POP; + ea = POP; + PUSH(ea != val); + break; + case 0x44: // ISGT : TOS = TOS-1 > TOS + val = POP; + ea = POP; + PUSH(ea <= val); + break; + case 0x46: // ISLT : TOS = TOS-1 < TOS + val = POP; + ea = POP; + PUSH(ea >= val); + break; + case 0x48: // ISGE : TOS = TOS-1 >= TOS + val = POP; + ea = POP; + PUSH(ea < val); + break; + case 0x4A: // ISLE : TOS = TOS-1 <= TOS + val = POP; + ea = POP; + PUSH(ea > val); + break; + case 0x4C: // BRFLS : !TOS ? IP += (IP) + if (!POP) + ip += WORD_PTR(ip) - 2; + else + ip += 2; + break; + case 0x4E: // BRTRU : TOS ? IP += (IP) + if (POP) + ip += WORD_PTR(ip) - 2; + else + ip += 2; + break; + /* + * 0x50-0x5F + */ + case 0x50: // BRNCH : IP += (IP) + ip += WORD_PTR(ip) - 2; + break; + case 0x52: // IBRNCH : IP += TOS + ip += POP; + break; + case 0x54: // CALL : TOFP = IP, IP = (IP) ; call + call(UWORD_PTR(ip)); + break; + case 0x56: // ICALL : TOFP = IP, IP = (TOS) ; indirect call + val = POP; + ea = mem_data[val] | (mem_data[val + 1] << 8); + call(ea); + break; + case 0x58: // ENTER : NEW FRAME, FOREACH PARAM LOCALVAR = TOS + frmsz = BYTE_PTR(ip); + mem_data[fp - frmsz] = fp; + mem_data[fp - frmsz + 1] = fp >> 8; + fp -= frmsz; + parmcnt = BYTE_PTR(ip); + while (parmcnt--) + { + val = POP; + mem_data[fp + parmcnt + 2] = val; + mem_data[fp + parmcnt + 3] = val >> 8; + } + break; + case 0x5A: // LEAVE : DEL FRAME, IP = TOFP + fp = mem_data[fp] | (mem_data[fp + 1] << 8); + case 0x5C: // RET : IP = TOFP + return; + case 0x5E: // ??? + break; + /* + * 0x60-0x6F + */ + case 0x60: // LB : TOS = BYTE (TOS) + val = UPOP; + PUSH(mem_data[val]); + break; + case 0x62: // LW : TOS = WORD (TOS) + ea = POP; + PUSH(mem_data[ea] | (mem_data[ea + 1] << 8)); + break; + case 0x64: // LLB : TOS = LOCALBYTE [IP] + PUSH(mem_data[fp + BYTE_PTR(ip)]); + break; + case 0x66: // LLW : TOS = LOCALWORD [IP] + ea = fp + BYTE_PTR(ip); + PUSH(mem_data[ea] | (mem_data[ea + 1] << 8)); + break; + case 0x68: // LAB : TOS = BYTE (IP) + PUSH(mem_data[UWORD_PTR(ip)]); + break; + case 0x6A: // LAW : TOS = WORD (IP) + ea = UWORD_PTR(ip); + PUSH(mem_data[ea] | (mem_data[ea + 1] << 8)); + break; + case 0x6C: // DLB : TOS = TOS, LOCALBYTE [IP] = TOS + mem_data[fp + BYTE_PTR(ip)] = TOS; + break; + case 0x6E: // DLW : TOS = TOS, LOCALWORD [IP] = TOS + ea = fp + BYTE_PTR(ip); + mem_data[ea] = TOS; + mem_data[ea + 1] = TOS >> 8; + break; + /* + * 0x70-0x7F + */ + case 0x70: // SB : BYTE (TOS) = TOS-1 + val = POP; + ea = POP; + mem_data[ea] = val; + break; + case 0x72: // SW : WORD (TOS) = TOS-1 + val = POP; + ea = POP; + mem_data[ea] = val; + mem_data[ea + 1] = val >> 8; + break; + case 0x74: // SLB : LOCALBYTE [TOS] = TOS-1 + mem_data[fp + BYTE_PTR(ip)] = POP; + break; + case 0x76: // SLW : LOCALWORD [TOS] = TOS-1 + ea = fp + BYTE_PTR(ip); + val = POP; + mem_data[ea] = val; + mem_data[ea + 1] = val >> 8; + break; + case 0x78: // SAB : BYTE (IP) = TOS + mem_data[WORD_PTR(ip)] = POP; + break; + case 0x7A: // SAW : WORD (IP) = TOS + ea = WORD_PTR(ip); + val = POP; + mem_data[ea] = val; + mem_data[ea + 1] = val >> 8; + break; + case 0x7C: // DAB : TOS = TOS, BYTE (IP) = TOS + mem_data[WORD_PTR(ip)] = TOS; + break; + case 0x7E: // DAW : TOS = TOS, WORD (IP) = TOS + ea = WORD_PTR(ip); + mem_data[ea] = TOS; + mem_data[ea + 1] = TOS >> 8; + break; + /* + * Odd codes and everything else are errors. + */ + default: + fprintf(stderr, "Illegal opcode 0x%02X @ 0x%04X\n", ip[-1], ip - mem_code); + } + } +} + +char *stdlib_exp[] = { + "VIEWPORT", + "PUTC", + "PUTS", + "PUTSZ", + "GETC", + "GETS", + "CLS", + "GOTOXY" +}; + +byte stdlib[] = { + 0x00 +}; + +int main(int argc, char **argv) +{ + byte dci[32]; + int i; + + if (--argc) + { + argv++; + if ((*argv)[0] == '-' && (*argv)[1] == 's') + { + show_state = 1; + argc--; + argv++; + } + /* + * Add default library. + */ + stodci("STDLIB", dci); + add_mod(dci, 0xFFFF); + for (i = 0; i < 8; i++) + { + mem_data[i] = i + 3; + stodci(stdlib_exp[i], dci); + add_sym(dci, i); + } + if (argc) + { + stodci(*argv, dci); + load_mod(dci); + if (show_state) dump_sym(); + argc--; + argv++; + } + if (argc) + { + stodci(*argv, dci); + call(lookup_sym(dci)); + } + } + return 0; +} \ No newline at end of file diff --git a/plasma3/plvm.c~ b/plasma3/plvm.c~ new file mode 100755 index 0000000..ccf17e7 --- /dev/null +++ b/plasma3/plvm.c~ @@ -0,0 +1,895 @@ +#include +#include +#include +#include + +typedef unsigned char code; +typedef unsigned char byte; +typedef signed short word; +typedef unsigned short uword; +typedef unsigned short address; +/* + * Debug + */ +int show_state = 0; +/* + * Bytecode memory + */ +#define BYTE_PTR(bp) ((byte)(*bp++)) +#define WORD_PTR(bp) ((word)(*bp++|(*++bp << 8))) +#define UWORD_PTR(bp) ((uword)(*bp++|(*++bp << 8))) +#define MOD_ADDR 0x1000 +#define DEF_CALL 0x0800 +#define DEF_CALLSZ 0x0800 +#define DEF_ENTRYSZ 6 +#define MEM_SIZE 65536 +byte mem_data[MEM_SIZE], mem_code[MEM_SIZE]; +byte *mem_bank[2] = {mem_data, mem_code}; +word sp = 0x01FE, fp = 0xBEFF, heap = 0x6000, xheap = 0x0800, deftbl = DEF_CALL, lastdef = DEF_CALL; + +#define EVAL_STACKSZ 16 +#define PUSH(v) (*(--esp))=(v) +#define POP (*(esp++)) +#define UPOP ((uword)(*(esp++))) +#define TOS (esp[0]) +word eval_stack[EVAL_STACKSZ]; +word *esp = eval_stack + EVAL_STACKSZ; + +#define SYMTBLSZ 1024 +#define SYMSZ 16 +#define MODTBLSZ 128 +#define MODSZ 16 +#define MODLSTSZ 32 +byte symtbl[SYMTBLSZ]; +byte *lastsym = symtbl; +byte modtbl[MODTBLSZ]; +byte *lastmod = modtbl; +/* + * Utility routines. + * + * A DCI string is one that has the high bit set for every character except the last. + * More efficient than C or Pascal strings. + */ +int dcitos(byte *dci, char *str) +{ + int len = 0; + do + str[len] = *dci & 0x7F; + while ((len++ < 15) && (*dci++ & 0x80)); + str[len] = 0; + return len; +} +int stodci(char *str, byte *dci) +{ + int len = 0; + do + dci[len] = toupper(*str) | 0x80; + while (*str++ && (len++ < 15)); + dci[len - 1] &= 0x7F; + return len; +} + +/* + * Heap routines. + */ +uword avail_heap(void) +{ + return fp - heap; +} +uword alloc_heap(int size) +{ + uword addr = heap; + heap += size; + if (heap >= fp) + { + printf("Error: heap/frame collision.\n"); + exit (1); + } + return addr; +} +uword free_heap(int size) +{ + heap -= size; + return fp - heap; +} +uword mark_heap(void) +{ + return heap; +} +int release_heap(uword newheap) +{ + heap = newheap; + return fp - heap; +} +uword avail_xheap(void) +{ + return 0xC000 - xheap; +} +uword alloc_xheap(int size) +{ + uword addr = xheap; + xheap += size; + if (xheap >= 0xC000) + { + printf("Error: xheap extinguished.\n"); + exit (1); + } + return addr; +} +uword free_xheap(int size) +{ + xheap -= size; + return 0xC000 - heap; +} +uword mark_xheap(void) +{ + return xheap; +} +int release_xheap(uword newxheap) +{ + xheap = newxheap; + return 0xC000 - xheap; +} +/* + * Copy from data mem to code mem. + */ +void xmemcpy(uword src, uword dst, uword size) +{ + while (size--) + mem_code[dst + size] = mem_data[src + size]; +} +/* + * Copy from code mem to data mem. + */ +void memxcpy(uword src, uword dst, uword size) +{ + while (size--) + mem_data[dst + size] = mem_code[src + size]; +} +/* + * DCI table routines, + */ +void dump_tbl(byte *tbl) +{ + int len; + byte *entbl; + while (*tbl) + { + len = 0; + while (*tbl & 0x80) + { + putchar(*tbl++ & 0x7F); + len++; + } + putchar(*tbl++); + putchar(':'); + while (len++ < 15) + putchar(' '); + printf("$%04X\n", tbl[0] | (tbl[1] << 8)); + tbl += 2; + } +} +uword lookup_tbl(byte *dci, byte *tbl) +{ + char str[20]; + byte *match, *entry = tbl; + while (*entry) + { + match = dci; + while (*entry == *match) + { + if ((*entry & 0x80) == 0) + return entry[1] | (entry[2] << 8); + entry++; + match++; + } + while (*entry++ & 0x80); + entry += 2; + } + dcitos(dci, str); + return 0; +} +int add_tbl(byte *dci, int val, byte *tbl, byte **last) +{ + while (*dci & 0x80) + *(*last)++ = *dci++; + *(*last)++ = *dci++; + *(*last)++ = val; + *(*last)++ = val >> 8; +} + +/* + * Symbol table routines. + */ +void dump_sym(void) +{ + printf("\nSystem Symbol Table:\n"); + dump_tbl(symtbl); +} +uword lookup_sym(byte *sym) +{ + return lookup_tbl(sym, symtbl); +} +int add_sym(byte *sym, int addr) +{ + return add_tbl(sym, addr, symtbl, &lastsym); +} + +/* + * Module routines. + */ +void dump_mod(void) +{ + printf("\nSystem Module Table:\n"); + dump_tbl(modtbl); +} +uword lookup_mod(byte *mod) +{ + return lookup_tbl(mod, modtbl); +} +int add_mod(byte *mod, int addr) +{ + return add_tbl(mod, addr, symtbl, &lastmod); +} +defcall_add(int bank, int addr) +{ + mem_data[lastdef] = bank ? 2 : 1; + mem_data[lastdef + 1] = addr; + mem_data[lastdef + 2] = addr >> 8; + return lastdef++; +} +int def_lookup(byte *cdd, int defaddr) +{ + int i, calldef = 0; + for (i = 0; cdd[i * 4] == 0x02; i++) + { + if ((cdd[i * 4 + 1] | (cdd[i * 4 + 2] << 8)) == defaddr) + { + calldef = cdd + i * 4 - mem_data; + break; + } + } + return calldef; +} +int extern_lookup(byte *esd, int index) +{ + byte *sym; + char string[32]; + while (*esd) + { + sym = esd; + esd += dcitos(esd, string); + if ((esd[0] & 0x10) && (esd[1] == index)) + return lookup_sym(sym); + esd += 3; + } + printf("\nError: extern index %d not found in ESD.\n", index); + return 0; +} +int load_mod(byte *mod) +{ + int len, size, end, magic, bytecode, fixup, addr, modaddr = mark_heap(); + byte *moddep, *rld, *esd, *cdd, *sym; + byte header[128]; + char filename[32], string[17]; + + dcitos(mod, filename); + printf("Load module %s\n"); + int fd = open(filename, O_RDONLY, 0); + if ((fd > 0) && (len = read(fd, header, 128)) > 0) + { + magic = header[2] | (header[3] << 8); + if (magic == 0xDA7E) + { + /* + * This is a relocatable bytecode module. + */ + bytecode = header[4] | (header[5] << 8); + moddep = header + 6; + if (*moddep) + { + /* + * Load module dependencies. + */ + close(fd); + while (*moddep) + { + if (lookup_mod(moddep) == 0) + load_mod(moddep); + moddep += dcitos(moddep, string); + } + modaddr = mark_heap(); + fd = open(filename, O_RDONLY, 0); + len = read(fd, mem_data + modaddr, 128); + } + else + memcpy(mem_data + modaddr, header, len); + } + addr = modaddr + len; + while ((len = read(fd, mem_data + addr, 4096)) > 0) + addr += len; + close(fd); + size = addr - modaddr; + len = mem_data[modaddr + 0] | (mem_data[modaddr + 1] << 8); + end = modaddr + len; + rld = mem_data + modaddr + len; // Re-Locatable Directory + esd = rld; // Extern+Entry Symbol Directory + bytecode += modaddr - MOD_ADDR; + while (*esd != 0x00) // Scan to end of RLD + esd += 4; + esd++; + cdd = rld; + if (show_state) + { + /* + * Dump different parts of module. + */ + printf("Module size: %d\n", size); + printf("Module code+data size: %d\n", len); + printf("Module magic: $%04X\n", magic); + printf("Module bytecode: $%04X\n", bytecode); + } + /* + * Print out the Re-Location Dictionary. + */ + if (show_state) + printf("\nRe-Location Dictionary:\n"); + while (*rld) + { + if (rld[0] == 0x02) + { + if (show_state) printf("\tDEF CODE"); + addr = rld[1] | (rld[2] << 8); + addr += modaddr - MOD_ADDR; + rld[1] = addr; + rld[2] = addr >> 8; +// end = rld - mem_data + 4; + } + else + { + addr = rld[1] | (rld[2] << 8); + addr += modaddr - MOD_ADDR; + if (rld[0] & 0x80) + fixup = mem_data[addr] | (mem_data[addr + 1] << 8); + else + fixup = mem_data[addr]; + if (rld[0] & 0x10) + { + if (show_state) printf("\tEXTERN[$%02X] ", rld[3]); + fixup += extern_lookup(esd, rld[3]); + } + else + { + if (show_state) printf("\tINTERN "); + fixup += modaddr - MOD_ADDR; + if (fixup >= bytecode) + /* + * Replace with call def dictionary. + */ + fixup = def_lookup(cdd, fixup); + } + if (rld[0] & 0x80) + { + if (show_state) printf("WORD"); + mem_data[addr] = fixup; + mem_data[addr + 1] = fixup >> 8; + } + else + { + if (show_state) printf("BYTE"); + mem_data[addr] = fixup; + } + + } + if (show_state) printf("@$%04X\n", addr); + rld += 4; + } + if (show_state) printf("\nExternal/Entry Symbol Directory:\n"); + while (*esd) + { + sym = esd; + esd += dcitos(esd, string); + if (esd[0] & 0x10) + { + if (show_state) printf("\tIMPORT %s[$%02X]\n", string, esd[1]); + } + else if (esd[0] & 0x08) + { + addr = esd[1] | (esd[2] << 8); + addr += modaddr - MOD_ADDR; + if (show_state) printf("\tEXPORT %s@$%04X\n", string, addr); + if (addr >= bytecode) + addr = def_lookup(cdd, addr); + add_sym(sym, addr); + } + esd += 3; + } + } + else + { + printf("Error: Unable to load module %s\n", filename); + exit (1); + } + /* + * Reserve heap space for relocated module. + */ + alloc_heap(end - modaddr); + return (fd > 0); +} +void interp(code *ip); + +void call(word pc) +{ + int i, s; + char sz[64]; + + switch (mem_data[pc++]) + { + case 0: // NULL call + printf("NULL call code\n"); + break; + case 1: // BYTECODE in mem_code + interp(mem_code + (mem_data[pc] + (mem_data[pc + 1] << 8))); + break; + case 2: // BYTECODE in mem_data + interp(mem_data + (mem_data[pc] + (mem_data[pc + 1] << 8))); + break; + case 3: // LIBRARY STDLIB::VIEWPORT + printf("Set Window %d, %d, %d, %n/n", POP, POP, POP, POP); + PUSH(0); + break; + case 4: // LIBRARY STDLIB::PUTC + putchar(POP); + PUSH(0); + break; + case 5: // LIBRARY STDLIB::PUTS + s = POP; + i = mem_data[s++]; + PUSH(i); + while (i--) + putchar(mem_data[s++]); + break; + case 6: // LIBRARY STDLIB::PUTSZ + s = POP; + while (i = mem_data[s++]) + { + if (i == '\r') + i = '\n'; + putchar(i); + } + PUSH(0); + break; + case 7: // LIBRARY STDLIB::GETC + PUSH(getchar()); + break; + case 8: // LIBRARY STDLIB::GETS + gets(sz); + i = 0; + while (sz[i]) + mem_data[0x200 + i++] = sz[i]; + mem_data[0x200 + i] = 0; + mem_data[0x1FF] = i; + PUSH(i); + break; + case 9: // LIBRARY STDLIB::CLS + puts("\033[2J"); + fflush(stdout); + PUSH(0); + PUSH(0); + case 10: // LIBRARY STDLIB::GOTOXY + s = POP + 1; + i = POP + 1; + printf("\033[%d;%df", s, i); + fflush(stdout); + PUSH(0); + break; + default: + printf("Bad call code\n"); + } +} + +/* + * OPCODE TABLE + * +OPTBL: DW ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E + DW NEG,COMP,AND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E + DW NOT,LOR,LAND,LA,LLA,CB,CW,SWAP ; 20 22 24 26 28 2A 2C 2E + DW DROP,DUP,PUSH,PULL,BRGT,BRLT,BREQ,BRNE ; 30 32 34 36 38 3A 3C 3E + DW ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E + DW BRNCH,IBRNCH,CALL,ICAL,ENTER,LEAVE,RET,??? ; 50 52 54 56 58 5A 5C 5E + DW LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E + DW SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E +*/ +void interp(code *ip) +{ + word val, ea, frmsz, parmcnt; + + while (1) + { + if (show_state) + { + word *dsp = &eval_stack[EVAL_STACKSZ - 1]; + printf("$%04X: $%02X [ ", ip - mem_data, *ip); + while (dsp >= esp) + printf("$%04X ", (*dsp--) & 0xFFFF); + printf("]\n"); + } + switch (*ip++) + { + /* + * 0x00-0x0F + */ + case 0x00: // ZERO : TOS = 0 + PUSH(0); + break; + case 0x02: // ADD : TOS = TOS + TOS-1 + val = POP; + ea = POP; + PUSH(ea + val); + break; + case 0x04: // SUB : TOS = TOS-1 - TOS + val = POP; + ea = POP; + PUSH(ea - val); + break; + case 0x06: // MUL : TOS = TOS * TOS-1 + val = POP; + ea = POP; + PUSH(ea * val); + break; + case 0x08: // DIV : TOS = TOS-1 / TOS + val = POP; + ea = POP; + PUSH(ea / val); + break; + case 0x0A: // MOD : TOS = TOS-1 % TOS + val = POP; + ea = POP; + PUSH(ea % val); + break; + case 0x0C: // INCR : TOS = TOS + 1 + TOS++; + break; + case 0x0E: // DECR : TOS = TOS - 1 + TOS--; + break; + /* + * 0x10-0x1F + */ + case 0x10: // NEG : TOS = -TOS + TOS = -TOS; + break; + case 0x12: // COMP : TOS = ~TOS + TOS = ~TOS; + break; + case 0x14: // AND : TOS = TOS & TOS-1 + val = POP; + ea = POP; + PUSH(ea & val); + break; + case 0x16: // IOR : TOS = TOS ! TOS-1 + val = POP; + ea = POP; + PUSH(ea | val); + break; + case 0x18: // XOR : TOS = TOS ^ TOS-1 + val = POP; + ea = POP; + PUSH(ea ^ val); + break; + case 0x1A: // SHL : TOS = TOS-1 << TOS + val = POP; + ea = POP; + PUSH(ea << val); + break; + case 0x1C: // SHR : TOS = TOS-1 >> TOS + val = POP; + ea = POP; + PUSH(ea >> val); + break; + case 0x1E: // IDXW : TOS = TOS * 2 + TOS *= 2; + break; + /* + * 0x20-0x2F + */ + case 0x20: // NOT : TOS = !TOS + TOS = !TOS; + break; + case 0x22: // LOR : TOS = TOS || TOS-1 + val = POP; + ea = POP; + PUSH(ea || val); + break; + case 0x24: // LAND : TOS = TOS && TOS-1 + val = POP; + ea = POP; + PUSH(ea && val); + break; + case 0x26: // LA : TOS = @VAR ; equivalent to CW ADDRESSOF(VAR) + PUSH(WORD_PTR(ip)); + break; + case 0x28: // LLA : TOS = @LOCALVAR ; equivalent to CW FRAMEPTR+OFFSET(LOCALVAR) + PUSH(fp + BYTE_PTR(ip)); + break; + case 0x2A: // CB : TOS = CONSTANTBYTE (IP) + PUSH(BYTE_PTR(ip)); + break; + case 0x2C: // CW : TOS = CONSTANTWORD (IP) + PUSH(WORD_PTR(ip)); + break; + case 0x2E: // SWAP : TOS = TOS-1, TOS-1 = TOS + val = POP; + ea = POP; + PUSH(val); + PUSH(ea); + break; + /* + * 0x30-0x3F + */ + case 0x30: // DROP : TOS = + esp++;; + break; + case 0x32: // DUP : TOS = TOS + val = TOS; + PUSH(val); + break; + case 0x34: // PUSH : TOSP = TOS + val = POP; + mem_data[sp--] = val >> 8; + mem_data[sp--] = val; + break; + case 0x36: // PULL : TOS = TOSP + PUSH(mem_data[++sp] | (mem_data[++sp] << 8)); + break; + case 0x38: // BRGT : TOS-1 > TOS ? IP += (IP) + val = POP; + ea = POP; + if (ea <= val) + ip += WORD_PTR(ip) - 2; + else + ip += 2; + break; + case 0x3A: // BRLT : TOS-1 < TOS ? IP += (IP) + val = POP; + ea = TOS; + if (ea >= val) + ip += WORD_PTR(ip) - 2; + else + ip += 2; + break; + case 0x3C: // BREQ : TOS == TOS-1 ? IP += (IP) + val = POP; + ea = TOS; + if (ea == val) + ip += WORD_PTR(ip) - 2; + else + ip += 2; + break; + case 0x3E: // BRNE : TOS != TOS-1 ? IP += (IP) + val = POP; + ea = TOS; + if (ea != val) + ip += WORD_PTR(ip) - 2; + else + ip += 2; + break; + /* + * 0x40-0x4F + */ + case 0x40: // ISEQ : TOS = TOS == TOS-1 + val = POP; + ea = POP; + PUSH(ea == val); + break; + case 0x42: // ISNE : TOS = TOS != TOS-1 + val = POP; + ea = POP; + PUSH(ea != val); + break; + case 0x44: // ISGT : TOS = TOS-1 > TOS + val = POP; + ea = POP; + PUSH(ea <= val); + break; + case 0x46: // ISLT : TOS = TOS-1 < TOS + val = POP; + ea = POP; + PUSH(ea >= val); + break; + case 0x48: // ISGE : TOS = TOS-1 >= TOS + val = POP; + ea = POP; + PUSH(ea < val); + break; + case 0x4A: // ISLE : TOS = TOS-1 <= TOS + val = POP; + ea = POP; + PUSH(ea > val); + break; + case 0x4C: // BRFLS : !TOS ? IP += (IP) + if (!POP) + ip += WORD_PTR(ip) - 2; + else + ip += 2; + break; + case 0x4E: // BRTRU : TOS ? IP += (IP) + if (POP) + ip += WORD_PTR(ip) - 2; + else + ip += 2; + break; + /* + * 0x50-0x5F + */ + case 0x50: // BRNCH : IP += (IP) + ip += WORD_PTR(ip) - 2; + break; + case 0x52: // IBRNCH : IP += TOS + ip += POP; + break; + case 0x54: // CALL : TOFP = IP, IP = (IP) ; call + call(UWORD_PTR(ip)); + break; + case 0x56: // ICALL : TOFP = IP, IP = (TOS) ; indirect call + val = POP; + ea = mem_data[val] | (mem_data[val + 1] << 8); + call(ea); + break; + case 0x58: // ENTER : NEW FRAME, FOREACH PARAM LOCALVAR = TOS + frmsz = BYTE_PTR(ip); + mem_data[fp - frmsz] = fp; + mem_data[fp - frmsz + 1] = fp >> 8; + fp -= frmsz; + parmcnt = BYTE_PTR(ip); + while (parmcnt--) + { + val = POP; + mem_data[fp + parmcnt + 2] = val; + mem_data[fp + parmcnt + 3] = val >> 8; + } + break; + case 0x5A: // LEAVE : DEL FRAME, IP = TOFP + fp = mem_data[fp] | (mem_data[fp + 1] << 8); + case 0x5C: // RET : IP = TOFP + return; + case 0x5E: // ??? + break; + /* + * 0x60-0x6F + */ + case 0x60: // LB : TOS = BYTE (TOS) + val = UPOP; + PUSH(mem_data[val]); + break; + case 0x62: // LW : TOS = WORD (TOS) + ea = POP; + PUSH(mem_data[ea] | (mem_data[ea + 1] << 8)); + break; + case 0x64: // LLB : TOS = LOCALBYTE [IP] + PUSH(mem_data[fp + BYTE_PTR(ip)]); + break; + case 0x66: // LLW : TOS = LOCALWORD [IP] + ea = fp + BYTE_PTR(ip); + PUSH(mem_data[ea] | (mem_data[ea + 1] << 8)); + break; + case 0x68: // LAB : TOS = BYTE (IP) + PUSH(mem_data[UWORD_PTR(ip)]); + break; + case 0x6A: // LAW : TOS = WORD (IP) + ea = UWORD_PTR(ip); + PUSH(mem_data[ea] | (mem_data[ea + 1] << 8)); + break; + case 0x6C: // DLB : TOS = TOS, LOCALBYTE [IP] = TOS + mem_data[fp + BYTE_PTR(ip)] = TOS; + break; + case 0x6E: // DLW : TOS = TOS, LOCALWORD [IP] = TOS + ea = fp + BYTE_PTR(ip); + mem_data[ea] = TOS; + mem_data[ea + 1] = TOS >> 8; + break; + /* + * 0x70-0x7F + */ + case 0x70: // SB : BYTE (TOS) = TOS-1 + val = POP; + ea = POP; + mem_data[ea] = val; + break; + case 0x72: // SW : WORD (TOS) = TOS-1 + val = POP; + ea = POP; + mem_data[ea] = val; + mem_data[ea + 1] = val >> 8; + break; + case 0x74: // SLB : LOCALBYTE [TOS] = TOS-1 + mem_data[fp + BYTE_PTR(ip)] = POP; + break; + case 0x76: // SLW : LOCALWORD [TOS] = TOS-1 + ea = fp + BYTE_PTR(ip); + val = POP; + mem_data[ea] = val; + mem_data[ea + 1] = val >> 8; + break; + case 0x78: // SAB : BYTE (IP) = TOS + mem_data[WORD_PTR(ip)] = POP; + break; + case 0x7A: // SAW : WORD (IP) = TOS + ea = WORD_PTR(ip); + val = POP; + mem_data[ea] = val; + mem_data[ea + 1] = val >> 8; + break; + case 0x7C: // DAB : TOS = TOS, BYTE (IP) = TOS + mem_data[WORD_PTR(ip)] = TOS; + break; + case 0x7E: // DAW : TOS = TOS, WORD (IP) = TOS + ea = WORD_PTR(ip); + mem_data[ea] = TOS; + mem_data[ea + 1] = TOS >> 8; + break; + /* + * Odd codes and everything else are errors. + */ + default: + fprintf(stderr, "Illegal opcode 0x%02X @ 0x%04X\n", ip[-1], ip - mem_code); + } + } +} + +char *stdlib_exp[] = { + "VIEWPORT", + "PUTC", + "PUTS", + "PUTSZ", + "GETC", + "GETS", + "CLS", + "GOTOXY" +}; + +byte stdlib[] = { + 0x00 +}; + +int main(int argc, char **argv) +{ + byte dci[32]; + int i; + + if (--argc) + { + argv++; + if ((*argv)[0] == '-' && (*argv)[1] == 's') + { + show_state = 1; + argc--; + argv++; + } + /* + * Add default library. + */ + stodci("STDLIB", dci); + add_mod(dci, 0xFFFF); + for (i = 0; i < 8; i++) + { + mem_data[i] = i + 3; + stodci(stdlib_exp[i], dci); + add_sym(dci, i); + } + if (argc) + { + stodci(*argv, dci); + load_mod(dci); + if (show_state) dump_sym(); + argc--; + argv++; + } + if (argc) + { + stodci(*argv, dci); + call(lookup_sym(dci)); + } + } + return 0; +} \ No newline at end of file diff --git a/plasma3/plvm02.s b/plasma3/plvm02.s new file mode 100755 index 0000000..22cdd1f --- /dev/null +++ b/plasma3/plvm02.s @@ -0,0 +1,1612 @@ +.PC02 +.DEFINE EQU = +.DEFINE DB .BYTE +.DEFINE DW .WORD +.DEFINE DS .RES +.DEFINE ORG .ORG +.DEFINE STKCHK 1 +.DEFINE TMRCHK 1 +;********************************************************** +;* +;* SYSTEM ROUTINES AND LOCATIONS +;* +;********************************************************** +;* +;* MONITOR SPECIAL LOCATIONS AND PRODOS MLI +;* +CSWL EQU $36 +CSWH EQU $37 +PROMPTCHAR EQU $33 +PRODOS EQU $BF00 +MACHID EQU $BF98 +;* +;* HARDWARE ADDRESSES +;* +KEYBD EQU $C000 +CLRKBD EQU $C010 +SPKR EQU $C030 +ROMIN EQU $C081 +LCBNK2 EQU $C083 +LCBNK1 EQU $C08B +ALTZPOFF EQU $C008 +ALTZPON EQU $C009 +ALTRAMRDOFF EQU $C002 +ALTRAMRDON EQU $C003 +ALTRAMWROFF EQU $C004 +ALTRAMWRON EQU $C005 +;* +;* AUXMEM ACCESS MACROS +;* +.IF IS65C02 +.MACRO AUXZP_ACCESS_ON + STA ALTZPON ; TURN ON ALT ZP AND LC +.ENDMACRO +.MACRO AUXZP_ACCESS_OFF + STA ALTZPOFF ; TURN OFF ALT ZP AND LC +.ENDMACRO +.MACRO AUXMEM_RDACCESS_ON + STA ALTRAMRDON +.ENDMACRO +.MACRO AUXMEM_RDACCESS_OFF + STA ALTRAMRDOFF +.ENDMACRO +.MACRO AUXMEM_WRACCESS_ON + STA ALTRAMWRON +.ENDMACRO +.MACRO AUXMEM_WRACCESS_OFF + STA ALTRAMWROFF +.ENDMACRO +.ELSE +.MACRO AUXZP_ACCESS_ON + SEI ; TURN INTERRUPTS OFF + STA ALTZPON ; TURN ON ALT ZP AND LC +.ENDMACRO +.MACRO AUXZP_ACCESS_OFF + STA ALTZPOFF ; TURN OFF ALT ZP AND LC + CLI ; TURN INTERRUPTS BACK ON +.ENDMACRO +.MACRO AUXMEM_RDACCESS_ON + SEI + STA ALTRAMRDON +.ENDMACRO +.MACRO AUXMEM_RDACCESS_OFF + STA ALTRAMRDOFF + CLI +.ENDMACRO +.MACRO AUXMEM_WRACCESS_ON + SEI + STA ALTRAMWRON +.ENDMACRO +.MACRO AUXMEM_WRACCESS_OFF + STA ALTRAMWROFF + CLI +.ENDMACRO +.ENDIF +;* +;* SIMPLIFUED ACCESS MACROS +;* +.IF IS65C02 +.MACRO LDA_IPC + LDA (PC) +.ENDMACRO +.MACRO LDA_ITMPL + LDA (TMP) +.ENDMACRO +.MACRO LDA_ITMPH + LDY #$01 + LDA (TMP),Y +.ENDMACRO +.MACRO LDA0 + LDA #$00 +.ENDMACRO +.MACRO STA_ITMPL + STA (TMP) +.ENDMACRO +.MACRO STA_ITMPH + LDY #$01 + STA (TMP),Y +.ENDMACRO +.MACRO ST0 ADDR + STZ ADDR +.ENDMACRO +.MACRO CLRY +.ENDMACRO +.ELSE +.MACRO LDA_IPC + LDA (PC),Y +.ENDMACRO +.MACRO LDA_ITMPL + LDA (TMP),Y +.ENDMACRO +.MACRO LDA_ITMPH + INY + LDA (TMP),Y + DEY +.ENDMACRO +.MACRO LDA0 + TYA +.ENDMACRO +.MACRO STA_ITMPL + STA (TMP),Y +.ENDMACRO +.MACRO STA_ITMPH + INY + STA (TMP),Y + DEY +.ENDMACRO +.MACRO ST0 ADDR + STY ADDR +.ENDMACRO +.MACRO CLRY + LDY #$00 +.ENDMACRO +.ENDIF + +;********************************************************** +;* +;* VM ZERO PAGE LOCATIONS +;* +;********************************************************** +ESTKSZ EQU $20 +ESTK EQU $C0 +ESTKL EQU ESTK +ESTKH EQU ESTK+ESTKSZ/2 +VMZP EQU ESTK+ESTKSZ +FRMP EQU VMZP+$00 +FRMPL EQU FRMP +FRMPH EQU FRMP+1 +PC EQU VMZP+$02 +PCL EQU PC +PCH EQU PC+1 +TICK EQU VMZP+$04 +ESP EQU VMZP+$05 + +TMP EQU VMZP+$0A +TMPL EQU TMP +TMPH EQU TMP+1 +TMPX EQU TMP+2 +NPARMS EQU TMPL +FRMSZ EQU TMPH +DVSIGN EQU TMPX +JSROP EQU VMZP+$0D + + ORG $D000 +;* +;* OPCODE TABLE +;* +OPTBL: DW ZERO,ADD,SUB,MUL,DIV,DIVMOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E + DW NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E + DW NOT,LOR,LAND,LA,LLA,CB,CW,SWAP ; 20 22 24 26 28 2A 2C 2E + DW DROP,DUP,PUSH,PULL,BRLT,BRGT,BREQ,BRNE ; 30 32 34 36 38 3A 3C 3E + DW ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E + DW SKIP,ISKIP,CALL,ICAL,ENTER,LEAVE,RET,??? ; 50 52 54 56 58 5A 5C 5E + DW LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E + DW SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E +;* +;* OPXCODE TABLE +;* +OPXTBL: DW ZERO,ADD,SUB,MUL,DIV,DIVMOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E + DW NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E + DW NOT,LOR,LAND,LAX,LLAX,CBX,CWX,SWAP ; 20 22 24 26 28 2A 2C 2E + DW DROP,DUP,PUSH,PULL,BRLTX,BRGTX,BREQX,BRNEX ; 30 32 34 36 38 3A 3C 3E + DW ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLSX,BRTRUX ; 40 42 44 46 48 4A 4C 4E + DW SKIPX,ISKIPX,CALLX,ICAL,ENTER,LEAVE,RET,??? ; 50 52 54 56 58 5A 5C 5E + DW LB,LW,LLBX,LLWX,LABX,LAWX,DLBX,DLWX ; 60 62 64 66 68 6A 6C 6E + DW SB,SW,SLBX,SLWX,SABX,SAWX,DABX,DAWX ; 70 72 74 76 78 7A 7C 7E +;* +;* COMMAND LOADER CODE +;* + CLD + CLV + BVC :+ + JMP PLASMA +: + .INCLUDE "cmd.byte" + +;*********************************************** +;* +;* INTERPRETER INITIALIZATION +;* +;*********************************************** +;* +;* INIT AND ENTER INTO PLASMA BYTECODE INTERPRETER +;* X:Y:A = ADDRESS OF INITAL ENTRYPOINT +;* +PLASMA: STA PCL + STY PCH + STX TMP + CLD + LDY #$20 +: LDA PAGE3,Y + STA $03D0,Y + DEY + BPL :- + LDX #ESTKSZ/2 + INY ; LDY #$00 + STY TICK + LDA #$6C + STA JSROP + LDA #>OPTBL + STA JSROP+2 + LDA TMP + BEQ FETCHOP + LDA MACHID + AND #$30 + CMP #$30 + BEQ FETCHOPX +_RTS: RTS +_BRK: BRK +;* +;* PAGE 3 VECTORS INTO INTERPRETER +;* +PAGE3: BIT $C080 ; $03D0 - INTERP ENTRY + JMP _INTERP + BIT $C080 ; $03D6 - INTERPX ENTRY + JMP _INTERPX + BIT $C080 ; $03DC - LEAVE ENTRY + JMP _LEAVE + BIT $C080 ; $03E2 - ENTER ENTRY + JMP _ENTER + DW _RTS ; $03E8 - PERIODIC VECTOR + DW _BRK ; $03EA - INT VECTOR +TMRVEC EQU $03E8 +INTVEC EQU $03EA +;* +;* ENTER INTO INLINE BYTECODE +;* +_INTERP: PLA + STA PCL + PLA + STA PCH + LDY #$00 + BEQ NEXTOP +TOCKOP: JSR TICKTOCK +FETCHOP: +.IF TMRCHK + DEC TICK + BEQ TOCKOP +.ENDIF + LDA_IPC + STA JSROP+1 + JSR JSROP +.IF STKCHK + CPX #ESTKSZ/2+1 + BCS STKINT +.ENDIF +NEXTOP: INC PCL + BNE FETCHOP + INC PCH + BNE FETCHOP +STKINT: LDA #$FF +INTJMP: JMP (INTVEC) +TICKTOCK: JMP (TMRVEC) +TMPJMP: JMP (TMP) +;* +;* ENTER INTO EXTERNAL BYTECODE +;* +_INTERPX: PLA + STA TMPL + PLA + STA TMPH + LDY #$01 + LDA (TMP),Y + STA PCL + INY + LDA (TMP),Y + STA PCH + INY + LDA (TMP),Y + TAY + BNE FETCHOPX + BEQ FETCHOP +TOCKOPX: JSR TICKTOCK +FETCHOPX: +.IF TMRCHK + DEC TICK + BEQ TOCKOPX +.ENDIF + AUXMEM_RDACCESS_ON + LDA_IPC + AUXMEM_RDACCESS_OFF + ORA #$80 ; SELECT OPX CODES + STA JSROP+1 + JSR JSROP +.IF STKCHK + CPX #ESTKSZ/2+1 + BCS STKINT +.ENDIF +NEXTOPX: INC PCL + BNE FETCHOPX + INC PCH + BNE FETCHOPX +;* +;* 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 + RTS +;* +;* 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 + RTS +;* +;* SHIFT TOS-1 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 + RTS +;* +;* MUL TOS-1 BY TOS +;* +MUL: ST0 TMPL ; PRODL + ST0 TMPH ; PRODH + LDY #$10 +MUL1: LSR ESTKH,X ; MULTPLRH + ROR ESTKL,X ; MULTPLRL + BCC MUL2 + LDA ESTKL+1,X ; MULTPLNDL + CLC + ADC TMPL ; PRODL + STA TMPL + LDA ESTKH+1,X ; MULTPLNDH + ADC TMPH ; PRODH + STA TMPH +MUL2: ASL ESTKL+1,X ; MULTPLNDL + ROL ESTKH+1,X ; MULTPLNDH + DEY + BNE MUL1 + INX + LDA TMPL ; PRODL + STA ESTKL,X + LDA TMPH ; PRODH + STA ESTKH,X + RTS +;* +;* INTERNAL DIVIDE ALGORITHM +;* +_DIV: LDA ESTKH,X + AND #$80 + STA DVSIGN + BPL _DIV1 + JSR NEG + INC DVSIGN +_DIV1: LDA ESTKH+1,X + BPL _DIV2 + INX + JSR NEG + DEX + INC DVSIGN + BNE _DIV3 +_DIV2: ORA ESTKL+1,X ; DVDNDL + BNE _DIV3 + STA TMPL + STA TMPH + RTS +_DIV3: LDY #$11 ; #BITS+1 + LDA #$00 + STA TMPL ; REMNDRL + STA TMPH ; REMNDRH +_DIV4: ASL ESTKL+1,X ; DVDNDL + ROL ESTKH+1,X ; DVDNDH + DEY + BCC _DIV4 + STY ESTKL-1,X +_DIV5: ROL TMPL ; REMNDRL + ROL TMPH ; REMNDRH + LDA TMPL ; REMNDRL + SEC + SBC ESTKL,X ; DVSRL + TAY + LDA TMPH ; REMNDRH + SBC ESTKH,X ; DVSRH + BCC _DIV6 + STA TMPH ; REMNDRH + STY TMPL ; REMNDRL +_DIV6: ROL ESTKL+1,X ; DVDNDL + ROL ESTKH+1,X ; DVDNDH + DEC ESTKL-1,X + BNE _DIV5 + CLRY + RTS +;* +;* DIV TOS-1 BY TOS +;* +DIV: JSR _DIV + INX + LSR DVSIGN ; SIGN(RESULT) = (SIGN(DIVIDEND) + SIGN(DIVISOR)) & 1 + BCS NEG + RTS +;* +;* NEGATE TOS +;* +NEG: LDA0 + SEC + SBC ESTKL,X + STA ESTKL,X + LDA0 + SBC ESTKH,X + STA ESTKH,X + RTS +;* +;* DIV,MOD TOS-1 BY TOS +;* +DIVMOD: JSR _DIV + LDA TMPL ; REMNDRL + STA ESTKL,X + LDA TMPH ; REMNDRH + STA ESTKH,X + LDA DVSIGN ; REMAINDER IS SIGN OF DIVIDEND + BPL DIVMOD1 + JSR NEG +DIVMOD1: LSR DVSIGN + BCC DIVMOD2 ; DIV RESULT TOS-1 + INX + JSR NEG + DEX +DIVMOD2: RTS +;* +;* INCREMENT TOS +;* +INCR: INC ESTKL,X + BNE INCR1 + INC ESTKH,X +INCR1: RTS +;* +;* DECREMENT TOS +;* +DECR: LDA ESTKL,X + BNE DECR1 + DEC ESTKH,X +DECR1: DEC ESTKL,X + RTS +;* +;* BITWISE COMPLIMENT TOS +;* +COMP: LDA #$FF + EOR ESTKL,X + STA ESTKL,X + LDA #$FF + EOR ESTKH,X + STA ESTKH,X + RTS +;* +;* 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 + RTS +;* +;* 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 + RTS +;* +;* 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 + RTS +;* +;* SHIFT TOS-1 LEFT BY TOS +;* +SHL: 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: INX + RTS +;* +;* SHIFT TOS-1 RIGHT BY TOS +;* +SHR: 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: INX + RTS +;* +;* LOGICAL NOT +;* +NOT: LDA ESTKL,X + ORA ESTKH,X + BNE NOT1 + LDA #$FF + STA ESTKL,X + STA ESTKH,X + RTS +NOT1: ST0 {ESTKL,X} + ST0 {ESTKH,X} + RTS +;* +;* LOGICAL AND +;* +LAND: LDA ESTKL,X + ORA ESTKH,X + BEQ LAND1 + LDA ESTKL+1,X + ORA ESTKH+1,X + BEQ LAND1 + LDA #$FF +LAND1: STA ESTKL+1,X + STA ESTKH+1,X + INX + RTS +;* +;* LOGICAL OR +;* +LOR: LDA ESTKL,X + ORA ESTKH,X + ORA ESTKL+1,X + ORA ESTKH+1,X + BEQ LOR1 + LDA #$FF +LOR1: STA ESTKL+1,X + STA ESTKH+1,X +;* +;* DROP TOS +;* +DROP: INX + RTS +;* +;* SWAP TOS WITH TOS-1 +;* +SWAP: LDA ESTKL,X + LDY ESTKL+1,X + STA ESTKL+1,X + STY ESTKL,X + LDA ESTKH,X + LDY ESTKH+1,X + STA ESTKH+1,X + STY ESTKH,X + CLRY + RTS +;* +;* DUPLICATE TOS +;* +DUP: DEX + LDA ESTKL+1,X + STA ESTKL,X + LDA ESTKH+1,X + STA ESTKH,X + RTS +;* +;* PUSH FROM EVAL STACK TO CALL STACK +;* +PUSH: PLA + STA TMPH + PLA + STA TMPL + LDA ESTKL,X + PHA + LDA ESTKH,X + PHA + INX + LDA TMPL + PHA + LDA TMPH + PHA + RTS +;* +;* PULL FROM CALL STACK TO EVAL STACK +;* +PULL: PLA + STA TMPH + PLA + STA TMPL + DEX + PLA + STA ESTKH,X + PLA + STA ESTKL,X + LDA TMPL + PHA + LDA TMPH + PHA + RTS +;* +;* CONSTANT +;* +ZERO: DEX + ST0 {ESTKL,X} + ST0 {ESTKH,X} + RTS +CB: DEX + INC PCL + BNE CB1 + INC PCH +CB1: LDA_IPC + STA ESTKL,X + ST0 {ESTKH,X} + RTS +;* +;* LOAD ADDRESS - CHECK FOR DATA OR CODE SPACE +;* +LA: +CW: DEX + INC PCL + BNE CW1 + INC PCH +CW1: LDA_IPC + STA ESTKL,X + INC PCL + BNE CW2 + INC PCH +CW2: LDA_IPC + STA ESTKH,X + RTS +;* +;* LOAD VALUE FROM ADDRESS TAG +;* +LB: LDA ESTKL,X + STA TMPL + LDA ESTKH,X + STA TMPH + LDA_ITMPL + STA ESTKL,X + ST0 {ESTKH,X} + RTS +LW: LDA ESTKL,X + STA TMPL + LDA ESTKH,X + STA TMPH + LDA_ITMPL + STA ESTKL,X + LDA_ITMPH + STA ESTKH,X + RTS +;* +;* LOAD ADDRESS OF LOCAL FRAME OFFSET +;* +LLA: INC PCL + BNE LLA1 + INC PCH +LLA1: LDA_IPC + DEX + CLC + ADC FRMPL + STA ESTKL,X + LDA0 + ADC FRMPH + STA ESTKH,X + RTS +;* +;* LOAD VALUE FROM LOCAL FRAME OFFSET +;* +LLB: INC PCL + BNE LLB1 + INC PCH +LLB1: LDA_IPC + TAY + DEX + LDA (FRMP),Y + STA ESTKL,X + CLRY + ST0 {ESTKH,X} + RTS +LLW: INC PCL + BNE LLW1 + INC PCH +LLW1: LDA_IPC + TAY + DEX + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + CLRY + RTS +;* +;* LOAD VALUE FROM ABSOLUTE ADDRESS +;* +LAB: INC PCL + BNE LAB1 + INC PCH +LAB1: LDA_IPC + STA TMPL + INC PCL + BNE LAB2 + INC PCH +LAB2: LDA_IPC + STA TMPH + LDA_ITMPL + DEX + STA ESTKL,X + ST0 {ESTKH,X} + RTS +LAW: INC PCL + BNE LAW1 + INC PCH +LAW1: LDA_IPC + STA TMPL + INC PCL + BNE LAW2 + INC PCH +LAW2: LDA_IPC + STA TMPH + LDA_ITMPL + DEX + STA ESTKL,X + LDA_ITMPH + STA ESTKH,X + RTS +;* +;* STORE VALUE TO ADDRESS +;* +SB: LDA ESTKL+1,X + STA TMPL + LDA ESTKH+1,X + STA TMPH + LDA ESTKL,X + STA_ITMPL + INX + INX + RTS +SW: LDA ESTKL+1,X + STA TMPL + LDA ESTKH+1,X + STA TMPH + LDA ESTKL,X + STA_ITMPL + LDA ESTKH,X + STA_ITMPH + INX + INX + RTS +;* +;* STORE VALUE TO LOCAL FRAME OFFSET +;* +SLB: INC PCL + BNE SLB1 + INC PCH +SLB1: LDA_IPC + TAY + LDA ESTKL,X + STA (FRMP),Y + INX + CLRY + RTS +SLW: INC PCL + BNE SLW1 + INC PCH +SLW1: LDA_IPC + TAY + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y + INX + CLRY + RTS +;* +;* STORE VALUE TO LOCAL FRAME OFFSET WITHOUT POPPING STACK +;* +DLB: INC PCL + BNE DLB1 + INC PCH +DLB1: LDA_IPC + TAY + LDA ESTKL,X + STA (FRMP),Y + CLRY + RTS +DLW: INC PCL + BNE DLW1 + INC PCH +DLW1: LDA_IPC + TAY + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y + CLRY + RTS +;* +;* STORE VALUE TO ABSOLUTE ADDRESS +;* +SAB: INC PCL + BNE SAB1 + INC PCH +SAB1: LDA_IPC + STA TMPL + INC PCL + BNE SAB2 + INC PCH +SAB2: LDA_IPC + STA TMPH + LDA ESTKL,X + STA_ITMPL + INX + RTS +SAW: INC PCL + BNE SAW1 + INC PCH +SAW1: LDA_IPC + STA TMPL + INC PCL + BNE SAW2 + INC PCH +SAW2: LDA_IPC + STA TMPH + LDA ESTKL,X + STA_ITMPL + LDA ESTKH,X + STA_ITMPH + INX + RTS +;* +;* STORE VALUE TO ABSOLUTE ADDRESS WITHOUT POPPING STACK +;* +DAB: INC PCL + BNE DAB1 + INC PCH +DAB1: LDA_IPC + STA TMPL + INC PCL + BNE DAB2 + INC PCH +DAB2: LDA_IPC + STA TMPH + LDA ESTKL,X + STA_ITMPL + RTS +DAW: INC PCL + BNE DAW1 + INC PCH +DAW1: LDA_IPC + STA TMPL + INC PCL + BNE DAW2 + INC PCH +DAW2: LDA_IPC + STA TMPH + LDA ESTKL,X + STA_ITMPL + LDA ESTKH,X + STA_ITMPH + RTS +;* +;* COMPARES +;* +ISEQ: +.IF IS65C02 + LDY #$00 +.ENDIF + LDA ESTKL,X + CMP ESTKL+1,X + BNE ISEQ1 + LDA ESTKH,X + CMP ESTKH+1,X + BNE ISEQ1 + DEY +ISEQ1: STY ESTKL+1,X + STY ESTKH+1,X + INX + CLRY + RTS +ISNE: +.IF IS65C02 + LDY #$FF +.ELSE + DEY ; LDY #$FF +.ENDIF + LDA ESTKL,X + CMP ESTKL+1,X + BNE ISNE1 + LDA ESTKH,X + CMP ESTKH+1,X + BNE ISNE1 + INY +ISNE1: STY ESTKL+1,X + STY ESTKH+1,X + INX + CLRY + RTS +ISGE: +.IF IS65C02 + LDY #$00 +.ELSE + ; LDY #$00 +.ENDIF + LDA ESTKL+1,X + CMP ESTKL,X + LDA ESTKH+1,X + SBC ESTKH,X + BVC ISGE1 + EOR #$80 +ISGE1: BMI ISGE2 + DEY +ISGE2: STY ESTKL+1,X + STY ESTKH+1,X + INX + CLRY + RTS +ISGT: +.IF IS65C02 + LDY #$00 +.ELSE + ; LDY #$00 +.ENDIF + LDA ESTKL,X + CMP ESTKL+1,X + LDA ESTKH,X + SBC ESTKH+1,X + BVC ISGT1 + EOR #$80 +ISGT1: BPL ISGT2 + DEY +ISGT2: STY ESTKL+1,X + STY ESTKH+1,X + INX + CLRY + RTS +ISLE: +.IF IS65C02 + LDY #$00 +.ELSE + ; LDY #$00 +.ENDIF + LDA ESTKL,X + CMP ESTKL+1,X + LDA ESTKH,X + SBC ESTKH+1,X + BVC ISLE1 + EOR #$80 +ISLE1: BMI ISLE2 + DEY +ISLE2: STY ESTKL+1,X + STY ESTKH+1,X + INX + CLRY + RTS +ISLT: +.IF IS65C02 + LDY #$00 +.ELSE + ; LDY #$00 +.ENDIF + LDA ESTKL+1,X + CMP ESTKL,X + LDA ESTKH+1,X + SBC ESTKH,X + BVC ISLT1 + EOR #$80 +ISLT1: BPL ISLT2 + DEY +ISLT2: STY ESTKL+1,X + STY ESTKH+1,X + INX + CLRY + RTS +;* +;* SKIPS +;* +SKPTRU: INX + LDA ESTKH-1,X + ORA ESTKL-1,X + BEQ NOSKIP +SKIP: +.IF IS65C02 + LDY #$01 +.ELSE + INY ; LDY #$01 +.ENDIF + LDA (PC),Y + PHA + INY + LDA (PC),Y + STA PCH + PLA + STA PCL + PLA + PLA + CLRY + JMP FETCHOP +SKPFLS: INX + LDA ESTKH-1,X + ORA ESTKL-1,X + BEQ SKIP +NOSKIP: LDA #$02 + CLC + ADC PCL + STA PCL + BCC NOSK1 + INC PCH +NOSK1: RTS +SKPEQ: INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE NOSKIP + LDA ESTKL-1,X + CMP ESTKL,X + BEQ SKIP + BNE NOSKIP +SKPNE: INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE SKIP + LDA ESTKL-1,X + CMP ESTKL,X + BEQ NOSKIP + BNE SKIP +SKPGT: INX + LDA ESTKL-1,X + CMP ESTKL,X + LDA ESTKH-1,X + SBC ESTKH,X + BMI SKIP + BPL NOSKIP +SKPLT: INX + LDA ESTKL,X + CMP ESTKL-1,X + LDA ESTKH,X + SBC ESTKH-1,X + BMI SKIP + BPL NOSKIP +;* +;* INDIRECT SKIP TO ADDRESS +;* +ISKIP: PLA + PLA + LDA ESTKL,X + STA PCL + LDA ESTKH,X + STA PCH + INX + JMP FETCHOP +;* +;* EXTERNAL SYS CALL +;* +INT: INC PCL + BNE INT1 + INC PCH +INT1: LDA_IPC + JSR INTJMP + CLRY + RTS +;* +;* CALL INTO ABSOLUTE ADDRESS (NATIVE CODE) +;* +CALL: INC PCL + BNE CALL1 + INC PCH +CALL1: LDA_IPC + STA TMPL + INC PCL + BNE CALL2 + INC PCH +CALL2: LDA_IPC + STA TMPH + LDA PCH + PHA + LDA PCL + PHA + JSR TMPJMP + PLA + STA PCL + PLA + STA PCH + CLRY + RTS +;* +;* INDIRECT CALL TO ADDRESS (NATIVE CODE) +;* +ICAL: LDA ESTKL,X + STA TMPL + LDA ESTKH,X + STA TMPH + INX + LDA PCH + PHA + LDA PCL + PHA + JSR TMPJMP + PLA + STA PCL + PLA + STA PCH + CLRY + RTS +;* +;* ENTER FUNCTION WITH FRAME SIZE AND PARAM COUNT +;* +_ENTER: STY FRMSZ + JMP ENTER3 +ENTER: INC PCL + BNE ENTER1 + INC PCH +ENTER1: LDA_IPC + STA FRMSZ + INC PCL + BNE ENTER2 + INC PCH +ENTER2: LDA_IPC +ENTER3: STA NPARMS + LDA FRMPL + PHA + SEC + SBC FRMSZ + STA FRMPL + LDA FRMPH + PHA + SBC #$00 + STA FRMPH + LDY #$01 + PLA + STA (FRMP),Y + DEY + PLA + STA (FRMP),Y + LDA NPARMS + BEQ ENTER5 + ASL + TAY + INY +ENTER4: LDA ESTKH,X + STA (FRMP),Y + DEY + LDA ESTKL,X + STA (FRMP),Y + DEY + INX + DEC TMPL + BNE ENTER4 +ENTER5: LDY #$00 + RTS +;* +;* LEAVE FUNCTION +;* +LEAVE: PLA + PLA +_LEAVE: LDY #$01 + LDA (FRMP),Y + DEY + PHA + LDA (FRMP),Y + STA FRMPL + PLA + STA FRMPH + RTS +RET: PLA + PLA + RTS +;*********************************************** +;* +;* XMOD VERSIONS OF BYTECODE OPS +;* +;*********************************************** +;* +;* CONSTANT +;* +CBX: DEX + INC PCL + BNE CBX1 + INC PCH +CBX1: AUXMEM_RDACCESS_ON + LDA_IPC + AUXMEM_RDACCESS_OFF + STA ESTKL,X + STY ESTKH,X + RTS +;* +;* LOAD ADDRESS +;* +LAX: +CWX: DEX + INC PCL + BNE CWX1 + INC PCH +CWX1: AUXMEM_RDACCESS_ON + LDA_IPC + STA ESTKL,X + INC PCL + BNE CWX2 + INC PCH +CWX2: LDA_IPC + AUXMEM_RDACCESS_OFF + STA ESTKH,X + RTS +;* +;* LOAD ADDRESS OF LOCAL FRAME OFFSET +;* +LLAX: INC PCL + BNE LLAX1 + INC PCH +LLAX1: AUXMEM_RDACCESS_ON + LDA_IPC + AUXMEM_RDACCESS_OFF + DEX + CLC + ADC FRMPL + STA ESTKL,X + LDA0 + ADC FRMPH + STA ESTKH,X + RTS +;* +;* LOAD VALUE FROM LOCAL FRAME OFFSET +;* +LLBX: INC PCL + BNE LLBX1 + INC PCH +LLBX1: AUXMEM_RDACCESS_ON + LDA_IPC + AUXMEM_RDACCESS_OFF + TAY + DEX + LDA (FRMP),Y + STA ESTKL,X + CLRY + ST0 {ESTKH,X} + RTS +LLWX: INC PCL + BNE LLWX1 + INC PCH +LLWX1: AUXMEM_RDACCESS_ON + LDA_IPC + AUXMEM_RDACCESS_OFF + TAY + DEX + LDA (FRMP),Y + STA ESTKL,X + INY + LDA (FRMP),Y + STA ESTKH,X + CLRY + RTS +;* +;* LOAD VALUE FROM ABSOLUTE ADDRESS +;* +LABX: INC PCL + BNE LABX1 + INC PCH +LABX1: AUXMEM_RDACCESS_ON + LDA_IPC + STA TMPL + INC PCL + BNE LABX2 + INC PCH +LABX2: LDA_IPC + AUXMEM_RDACCESS_OFF + STA TMPH + DEX + LDA_ITMPL + STA ESTKL,X + ST0 {ESTKH,X} + RTS +LAWX: INC PC + BNE LAWX1 + INC PCH +LAWX1: AUXMEM_RDACCESS_ON + LDA_IPC + STA TMPL + INC PCL + BNE LAWX2 + INC PCH + DEX +LAWX2: LDA_IPC + STA TMPH + LDA_ITMPL + STA ESTKL,X + LDA_ITMPH + AUXMEM_RDACCESS_OFF + STA ESTKH,X + RTS +;* +;* STORE VALUE TO LOCAL FRAME OFFSET +;* +SLBX: INC PCL + BNE SLBX1 + INC PCH +SLBX1: AUXMEM_RDACCESS_ON + LDA_IPC + AUXMEM_RDACCESS_OFF + TAY + LDA ESTKL,X + STA (FRMP),Y + INX + CLRY + RTS +SLWX: INC PCL + BNE SLWX1 + INC PCH +SLWX1: AUXMEM_RDACCESS_ON + LDA_IPC + AUXMEM_RDACCESS_OFF + TAY + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y + INX + CLRY + RTS +;* +;* STORE VALUE TO LOCAL FRAME OFFSET WITHOUT POPPING STACK +;* +DLBX: INC PCL + BNE DLBX1 + INC PCH +DLBX1: AUXMEM_RDACCESS_ON + LDA_IPC + AUXMEM_RDACCESS_OFF + TAY + LDA ESTKL,X + STA (FRMP),Y + CLRY + RTS +DLWX: INC PCL + BNE DLWX1 + INC PCH +DLWX1: AUXMEM_RDACCESS_ON + LDA_IPC + AUXMEM_RDACCESS_OFF + TAY + LDA ESTKL,X + STA (FRMP),Y + INY + LDA ESTKH,X + STA (FRMP),Y + CLRY + RTS +;* +;* STORE VALUE TO ABSOLUTE ADDRESS +;* +SABX: INC PCL + BNE SABX1 + INC PCH +SABX1: AUXMEM_RDACCESS_ON + LDA_IPC + STA TMPL + INC PCL + BNE SABX2 + INC PCH +SABX2: LDA_IPC + AUXMEM_RDACCESS_OFF + STA TMPH + LDA ESTKL,X + STA_ITMPL + INX + RTS +SAWX: INC PCL + BNE SAWX1 + INC PCH +SAWX1: AUXMEM_RDACCESS_ON + LDA_IPC + STA TMPL + INC PCL + BNE SAWX2 + INC PCH +SAWX2: LDA_IPC + AUXMEM_RDACCESS_OFF + STA TMPH + LDA ESTKL,X + STA_ITMPL + LDA ESTKH,X + STA_ITMPH + INX + RTS +;* +;* STORE VALUE TO ABSOLUTE ADDRESS WITHOUT POPPING STACK +;* +DABX: INC PCL + BNE DABX1 + INC PCH +DABX1: AUXMEM_RDACCESS_ON + LDA_IPC + STA TMPL + INC PCL + BNE DABX2 + INC PCH +DABX2: LDA_IPC + AUXMEM_RDACCESS_OFF + STA TMPH + LDA ESTKL,X + STA_ITMPL + RTS +DAWX: INC PCL + BNE DAWX1 + INC PCH +DAWX1: AUXMEM_RDACCESS_ON + LDA_IPC + STA TMPL + INC PCL + BNE DAWX2 + INC PCH +DAWX2: LDA_IPC + AUXMEM_RDACCESS_OFF + STA TMPH + LDA ESTKL,X + STA_ITMPL + LDA ESTKH,X + STA_ITMPH + RTS +;* +;* SKIPS +;* +SKPTRUX: INX + LDA ESTKH-1,X + ORA ESTKL-1,X + BEQ NOSKIPX +SKIPX: +.IF IS65C02 + LDY #$01 +.ELSE + INY ; LDY #$01 +.ENDIF + AUXMEM_RDACCESS_ON + LDA_IPC + PHA + INY + LDA_IPC + AUXMEM_RDACCESS_OFF + STA PCH + PLA + STA PCL + PLA + PLA + CLRY + CLRY + JMP FETCHOPX +SKPFLSX: INX + LDA ESTKH-1,X + ORA ESTKL-1,X + BEQ SKIPX +NOSKIPX: LDA #$02 + CLC + ADC PCL + STA PCL + BCC NOSKX1 + INC PCH +NOSKX1: RTS +SKPEQX: INX + ; INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE NOSKIPX + LDA ESTKL-1,X + CMP ESTKL,X + BEQ SKIPX + BNE NOSKIPX +SKPNEX: INX + ; INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE SKIPX + LDA ESTKL-1,X + CMP ESTKL,X + BEQ NOSKIPX + BNE SKIPX +SKPGTX: INX + ; INX + LDA ESTKL-1,X + CMP ESTKL,X + LDA ESTKH-1,X + SBC ESTKH,X + BMI SKIPX + BPL NOSKIPX +SKPLTX: INX + ; INX + LDA ESTKL,X + CMP ESTKL-1,X + LDA ESTKH,X + SBC ESTKH-1,X + BMI SKIPX + BPL NOSKIPX +;* +;* INDIRECT SKIP TO ADDRESS +;* +ISKIPX: PLA + PLA + LDA ESTKL,X + STA PCL + LDA ESTKH,X + STA PCH + INX + JMP FETCHOPX +;* +;* EXTERNAL SYS CALL +;* +INTX: INC PCL + BNE INTX1 + INC PCH +INTX1: AUXMEM_RDACCESS_ON + LDA_IPC + AUXMEM_RDACCESS_OFF + JSR INTJMP + CLRY + RTS +;* +;* CALL TO ABSOLUTE ADDRESS (NATIVE CODE) +;* +CALLX: INC PCL + BNE CALLX1 + INC PCH +CALLX1: AUXMEM_RDACCESS_ON + LDA_IPC + STA TMPL + INC PCL + BNE CALLX2 + INC PCH +CALLX2: LDA_IPC + AUXMEM_RDACCESS_OFF + STA TMPH + LDA PCH + PHA + LDA PCL + PHA + JSR TMPJMP + PLA + STA PCL + PLA + STA PCH + CLRY + RTS diff --git a/plasma3/samplib.s b/plasma3/samplib.s new file mode 100755 index 0000000..210ed6a --- /dev/null +++ b/plasma3/samplib.s @@ -0,0 +1,147 @@ +; +; Sample PLASMA library. +; +!TO "samplib.bin", PLAIN +* = $1000 +; +; DATA/CODE SEGMENT +; +_SEGBEGIN + !WORD _SEGEND-_SEGBEGIN ; LENGTH OF HEADER + CODE/DATA + BYTECODE SEGMENT +; +; MODULE HEADER +; + !WORD $DA7E ; MAGIC # + !WORD _SUBSEG ; BYTECODE SUB-SEGMENT +; +; MODULE DEPENDENCY LIST +; NOTE: DCI = PSUEDO OP FOR ASCII STRING WITH HI BIT SET EXCEPT LAST CHAR +; + ;DCI "STDLIB" + !CT "hi.ascii" + !TX "STDLI" + !CT RAW + !TX 'B' + ;DCI "FILEIO" + !CT "hi.ascii" + !TX "FILEI" + !CT RAW + !TX 'O' + !BYTE 0 +; +; NATIVE CODE + GLOBAL DATA +; +COUNT !WORD 0 +INCCNT +FIXUP1 INC COUNT + BNE XINIT +FIXUP2 INC COUNT+1 +XINIT RTS +; +; BYTECODE SUB-SEGMENT +; +_SUBSEG +MYFUNC !BYTE $58, $01, $16 ; ENTER 1,16 + !BYTE $66, $02 ; LLW 2 + !BYTE $2A, $01 ; CB 1 + !BYTE $54 ; CALL EXTERN(1) "OPEN" +FIXUP4 !WORD $0000 + !BYTE $6E, $04 ; DLW 4 + !BYTE $54 ; CALL EXTERN(3) "READ" +FIXUP5 !WORD $0000 + !BYTE $30 ; DROP + !BYTE $66, $04 ; LLW 4 + !BYTE $54 ; CALL EXTERN(2) ; "CLOSE" +FIXUP6 !WORD $0000 + !BYTE $30 ; DROP + !BYTE $6A ; LAW COUNT +FIXUP7 !WORD $0000 + !BYTE $54 ; CALL INCNT +FIXUP8 !WORD $0000 + !BYTE $5A ; LEAVE +; +; END OF CODE/DATA + BYTECODE SEGMENT +; +_SEGEND +; +; BYTCODE FUNCTION DICTIONARY +; + !BYTE $A1 ; FIXUP FLAGS + !WORD MYFUNC ; FIXUP OFFSET + !BYTE $00 ; FIXUP LO BYTE (OF HI BYTE)/IMPORT INDEX +; +; RE-LOCATION DICTIONARY (FIXUP TABLE) +; + !BYTE $81 ; FIXUP FLAGS + !WORD FIXUP1+1 ; FIXUP OFFSET + !BYTE $00 ; FIXUP LO BYTE (OF HI BYTE)/IMPORT INDEX + !BYTE $81 + !WORD FIXUP2+1 + !BYTE $00 + !BYTE $91 ; IMPORT FIXUP + !WORD FIXUP4 + !BYTE $01 ; IMPORT INDEX 1 + !BYTE $91 + !WORD FIXUP5 + !BYTE $03 + !BYTE $91 + !WORD FIXUP6 + !BYTE $02 + !BYTE $81 + !WORD FIXUP7 + !BYTE $00 + !BYTE $81 + !WORD FIXUP8 + !BYTE $00 + !BYTE 0 ; END OF RLD +; +; EXTERNAL/ENTRY SYMBOL DIRECTORY +;; +; IMPORT TABLE +; +IMPTBL ;DCI "OPEN" ; EXTERNAL SYMBOL NAME + !CT "hi.ascii" + !TX "OPE" + !CT RAW + !TX 'N' + !BYTE $10 ; EXTERNAL SYMBOL FLAG + !WORD 1 ; SYMBOL INDEX + ;DCI "CLOSE" + !CT "hi.ascii" + !TX "CLOS" + !CT RAW + !TX 'E' + !BYTE $10 + !WORD 2 + ;DCI "READ" + !CT "hi.ascii" + !TX "REA" + !CT RAW + !TX 'D' + !BYTE $10 + !WORD 3 + ;DCI "MEMSET" + !CT "hi.ascii" + !TX "MEMSE" + !CT RAW + !TX 'T' + !BYTE $10 + !WORD 4 +; +; EXPORT TABLE +; +EXPTBL ;DCI "INCNT" ; ENTRY SYMBOL NAME + !CT "hi.ascii" + !TX "INCN" + !CT RAW + !TX 'T' + !BYTE $08 ; ENTRY SYMBOL FLAG + !WORD INCCNT ; OFFSET + ;DCI "MYFUNC" + !CT "hi.ascii" + !TX "MYFUN" + !CT RAW + !TX 'C' + !BYTE $08 + !WORD MYFUNC + !BYTE 0 ; END OF ESD diff --git a/plasma3/symbols.h b/plasma3/symbols.h new file mode 100755 index 0000000..bbd62b1 --- /dev/null +++ b/plasma3/symbols.h @@ -0,0 +1,39 @@ +/* + * Symbol table types. + */ +#define GLOBAL_TYPE (0) +#define CONST_TYPE (1 << 0) +#define WORD_TYPE (1 << 1) +#define BYTE_TYPE (1 << 2) +#define VAR_TYPE (WORD_TYPE | BYTE_TYPE) +#define ASM_TYPE (1 << 3) +#define DEF_TYPE (1 << 4) +#define BRANCH_TYPE (1 << 5) +#define FUNC_TYPE (ASM_TYPE | DEF_TYPE) +#define LOCAL_TYPE (1 << 6) +#define EXTERN_TYPE (1 << 7) +#define ADDR_TYPE (VAR_TYPE | FUNC_TYPE | EXTERN_TYPE) +#define WPTR_TYPE (1 << 8) +#define BPTR_TYPE (1 << 9) +#define PTR_TYPE (BPTR_TYPE | WPTR_TYPE) +#define STRING_TYPE (1 << 10) +#define TAG_TYPE (1 << 11) +#define EXPORT_TYPE (1 << 12) + +int id_match(char *name, int len, char *id); +int idlocal_lookup(char *name, int len); +int idglobal_lookup(char *name, int len); +int idconst_lookup(char *name, int len); +int idlocal_add(char *name, int len, int type, int size); +int idglobal_add(char *name, int len, int type, int size); +int id_add(char *name, int len, int type, int size); +int idfunc_set(char *name, int len, int type); +int idfunc_add(char *name, int len, int type, int tag); +int idconst_add(char *name, int len, int value); +int id_tag(char *name, int len); +int id_const(char *name, int len); +int id_type(char *name, int len); +void idglobal_size(int type, int size, int constsize); +int idlocal_size(void); +void idlocal_reset(void); +int tag_new(int type); diff --git a/plasma3/symbols.h~ b/plasma3/symbols.h~ new file mode 100755 index 0000000..16d5aee --- /dev/null +++ b/plasma3/symbols.h~ @@ -0,0 +1,39 @@ +/* + * Symbol table types. + */ +#define GLOBAL_TYPE (0) +#define CONST_TYPE (1 << 0) +#define WORD_TYPE (1 << 1) +#define BYTE_TYPE (1 << 2) +#define VAR_TYPE (WORD_TYPE | BYTE_TYPE) +#define ASM_TYPE (1 << 3) +#define DEF_TYPE (1 << 4) +#define BRANCH_TYPE (1 << 5) +#define FUNC_TYPE (ASM_TYPE | DEF_TYPE) +#define LOCAL_TYPE (1 << 6) +#define EXTERN_TYPE (1 << 7) +#define ADDR_TYPE (VAR_TYPE | FUNC_TYPE | EXTERN_TYPE) +#define WPTR_TYPE (1 << 8) +#define BPTR_TYPE (1 << 9) +#define PTR_TYPE (BPTR_TYPE | WPTR_TYPE) +#define STRING_TYPE (1 << 10) +#define TAG_TYPE (1 << 11) +#define EXPORT_TYPE (1 << 12) + +int id_match(char *name, int len, char *id); +int idlocal_lookup(char *name, int len); +int idglobal_lookup(char *name, int len); +int idconst_lookup(char *name, int len); +int idlocal_add(char *name, int len, int type, int size); +int idglobal_add(char *name, int len, int type, int size); +int id_add(char *name, int len, int type, int size); +int idfunc_extern(char *name, int len); +int idfunc_add(char *name, int len, int type, int tag); +int idconst_add(char *name, int len, int value); +int id_tag(char *name, int len); +int id_const(char *name, int len); +int id_type(char *name, int len); +void idglobal_size(int type, int size, int constsize); +int idlocal_size(void); +void idlocal_reset(void); +int tag_new(int type); diff --git a/plasma3/test.a b/plasma3/test.a new file mode 100755 index 0000000..9e5e808 --- /dev/null +++ b/plasma3/test.a @@ -0,0 +1,177 @@ +; ACME COMPATIBLE OUTPUT +_SEGBEGIN + !WORD _SEGEND-_SEGBEGIN ; LENGTH OF HEADER + CODE/DATA + BYTECODE SEGMENT + !WORD $DA7E ; MAGIC # + !WORD _SUBSEG ; BYTECODE SUB-SEGMENT +; 001: ; +; 002: ; Declare all imported modules and their data/functions. +; 003: ; +; 004: import stdlib + ; DCI STRING: STDLIB + !BYTE $D3,$D4,$C4,$CC,$C9,$42 +; 005: predef cls, gotoxy, puts, putc + ; cls -> X000 + ; gotoxy -> X001 + ; puts -> X002 + ; putc -> X003 +; 006: end +; 007: ; +; 008: ; Predeclare and functions called before defined. +; 009: ; +; 010: predef main + !BYTE $00 ; END OF MODULE DEPENDENCIES +; 011: ; +; 012: ; Declare all global variables for this module. +; 013: ; +; 014: byte hello[] = "Hello, world.\n\n" +_D005 ; hello[] = "Hello, world.\n\n" + !BYTE $0F + !BYTE $48,$65,$6C,$6C,$6F,$2C,$20,$77 + !BYTE $6F,$72,$6C,$64,$2E,$0A,$0A +; 015: word defptr = main +_D006 ; defptr = main +_F000 !WORD _C000 +; 016: ; +; 017: ; Define functions. +; 018: ; +; 019: +; 020: export def ascii +_SUBSEG ; BYTECODE STARTS +_C001 ; ascii() +; 021: byte i + ; i -> [2] +; 022: cls() + !BYTE $58,$03,$00 ; ENTER 3,0 + !BYTE $54 ; CALL _X000 +_F001 !WORD 0 + !BYTE $30 ; DROP +; 023: for i = 32 to 127 + !BYTE $2A,$20 ; CB 32 +_B001 + !BYTE $6C,$02 ; DLB [2] + !BYTE $2A,$7F ; CB 127 + !BYTE $3A ; BRGT _B000 + !WORD _B000-* + !BYTE $0C ; INCR +; 024: putc(i) + !BYTE $64,$02 ; LLB [2] + !BYTE $54 ; CALL _X003 +_F002 !WORD 0 + !BYTE $30 ; DROP +; 025: next + !BYTE $50 ; BRNCH _B001 + !WORD _B001-* +_B000 + !BYTE $30 ; DROP +; 026: end + !BYTE $00 ; ZERO + !BYTE $5A ; LEAVE +; 027: +; 028: export def main +_C000 ; main() +; 029: cls() + !BYTE $54 ; CALL _X000 +_F003 !WORD 0 + !BYTE $30 ; DROP +; 030: gotoxy(35,15) + !BYTE $2A,$23 ; CB 35 + !BYTE $2A,$0F ; CB 15 + !BYTE $54 ; CALL _X001 +_F004 !WORD 0 + !BYTE $30 ; DROP +; 031: return puts(@hello) + !BYTE $26 ; LA _D005 +_F005 !WORD _D005 + !BYTE $54 ; CALL _X002 +_F006 !WORD 0 + !BYTE $5C ; RET +; 032: end +; 033: +; 034: export def indirect +_C002 ; indirect() +; 035: word mainptr + ; mainptr -> [2] +; 036: mainptr = @main + !BYTE $58,$04,$00 ; ENTER 4,0 + !BYTE $26 ; LA _C000 +_F007 !WORD _C000 + !BYTE $76,$02 ; SLW [2] +; 037: mainptr() + !BYTE $28,$02 ; LLA [2] + !BYTE $56 ; ICAL + !BYTE $30 ; DROP +; 038: end + !BYTE $00 ; ZERO + !BYTE $5A ; LEAVE +; 039: +; 040: done +_SEGEND +; +; RE-LOCATEABLE DICTIONARY +; + !BYTE $02 ; CODE TABLE FIXUP + !WORD _C000 + !BYTE $00 + !BYTE $02 ; CODE TABLE FIXUP + !WORD _C001 + !BYTE $00 + !BYTE $02 ; CODE TABLE FIXUP + !WORD _C002 + !BYTE $00 + !BYTE $81 ; INTERNAL FIXUP + !WORD _F000 + !BYTE $00 + !BYTE $91 ; EXTERNAL FIXUP + !WORD _F001 + !BYTE 0 ; ESD INDEX + !BYTE $91 ; EXTERNAL FIXUP + !WORD _F002 + !BYTE 3 ; ESD INDEX + !BYTE $91 ; EXTERNAL FIXUP + !WORD _F003 + !BYTE 0 ; ESD INDEX + !BYTE $91 ; EXTERNAL FIXUP + !WORD _F004 + !BYTE 1 ; ESD INDEX + !BYTE $81 ; INTERNAL FIXUP + !WORD _F005 + !BYTE $00 + !BYTE $91 ; EXTERNAL FIXUP + !WORD _F006 + !BYTE 2 ; ESD INDEX + !BYTE $81 ; INTERNAL FIXUP + !WORD _F007 + !BYTE $00 + !BYTE $00 ; END OF RLD +; +; EXTERNAL/ENTRY SYMBOL DICTIONARY +; + ; DCI STRING: CLS + !BYTE $C3,$CC,$53 + !BYTE $10 ; EXTERNAL SYMBOL FLAG + !WORD 0 ; ESD INDEX + ; DCI STRING: GOTOXY + !BYTE $C7,$CF,$D4,$CF,$D8,$59 + !BYTE $10 ; EXTERNAL SYMBOL FLAG + !WORD 1 ; ESD INDEX + ; DCI STRING: PUTS + !BYTE $D0,$D5,$D4,$53 + !BYTE $10 ; EXTERNAL SYMBOL FLAG + !WORD 2 ; ESD INDEX + ; DCI STRING: PUTC + !BYTE $D0,$D5,$D4,$43 + !BYTE $10 ; EXTERNAL SYMBOL FLAG + !WORD 3 ; ESD INDEX + ; DCI STRING: MAIN + !BYTE $CD,$C1,$C9,$4E + !BYTE $08 ; ENTRY SYMBOL FLAG + !WORD _C000 + ; DCI STRING: ASCII + !BYTE $C1,$D3,$C3,$C9,$49 + !BYTE $08 ; ENTRY SYMBOL FLAG + !WORD _C001 + ; DCI STRING: INDIRECT + !BYTE $C9,$CE,$C4,$C9,$D2,$C5,$C3,$54 + !BYTE $08 ; ENTRY SYMBOL FLAG + !WORD _C002 + !BYTE $00 ; END OF ESD diff --git a/plasma3/test.bin b/plasma3/test.bin new file mode 100755 index 0000000..7ab83d3 Binary files /dev/null and b/plasma3/test.bin differ diff --git a/plasma3/test.pla b/plasma3/test.pla new file mode 100755 index 0000000..e795c02 --- /dev/null +++ b/plasma3/test.pla @@ -0,0 +1,40 @@ +; +; Declare all imported modules and their data/functions. +; +import stdlib + predef cls, gotoxy, puts, putc +end +; +; Predeclare and functions called before defined. +; +predef main +; +; Declare all global variables for this module. +; +byte hello[] = "Hello, world.\n\n" +word defptr = main +; +; Define functions. +; + +export def ascii + byte i + cls() + for i = 32 to 127 + putc(i) + next +end + +export def main + cls() + gotoxy(35,15) + return puts(@hello) +end + +export def indirect + word mainptr + mainptr = @main + mainptr() +end + +done diff --git a/plasma3/test.pla~ b/plasma3/test.pla~ new file mode 100755 index 0000000..e6a9c95 --- /dev/null +++ b/plasma3/test.pla~ @@ -0,0 +1,40 @@ +; +; Declare all imported modules and their data/functions. +; +import stdlib + predef cls, gotoxy, puts, putc +end +; +; Predeclare and functions called before defined. +; +predef main +; +; Declare all global variables for this module. +; +byte hello[] = "Hello, world.\n\n" +word defptr = main +; +; Define functions. +; + +export def ascii + byte i + cls() + for i = 32 to 127 + putc(i) + next +end + +export def main + cls() + gotoxy(35,15) + return puts(@hello) +end + +export def indirect + word mainptr + mainptr = main + mainptr() +end + +done diff --git a/plasma3/tokens.h b/plasma3/tokens.h new file mode 100755 index 0000000..afe259a --- /dev/null +++ b/plasma3/tokens.h @@ -0,0 +1,106 @@ + +#define TOKEN(c) (0x80|(c)) +#define IS_TOKEN(c) (0x80&(c)) +/* + * Identifier and constant tokens. + */ +#define ID_TOKEN TOKEN('V') +#define CHAR_TOKEN TOKEN('Y') +#define INT_TOKEN TOKEN('Z') +#define FLOAT_TOKEN TOKEN('F') +#define STRING_TOKEN TOKEN('S') +/* + * Keyword tokens. + */ +#define CONST_TOKEN TOKEN(1) +#define BYTE_TOKEN TOKEN(2) +#define WORD_TOKEN TOKEN(3) +#define IF_TOKEN TOKEN(4) +#define ELSEIF_TOKEN TOKEN(5) +#define ELSE_TOKEN TOKEN(6) +#define FIN_TOKEN TOKEN(7) +#define END_TOKEN TOKEN(8) +#define WHILE_TOKEN TOKEN(9) +#define LOOP_TOKEN TOKEN(10) +#define CASE_TOKEN TOKEN(11) +#define OF_TOKEN TOKEN(12) +#define DEFAULT_TOKEN TOKEN(13) +#define ENDCASE_TOKEN TOKEN(14) +#define FOR_TOKEN TOKEN(15) +#define TO_TOKEN TOKEN(16) +#define DOWNTO_TOKEN TOKEN(17) +#define STEP_TOKEN TOKEN(18) +#define NEXT_TOKEN TOKEN(19) +#define REPEAT_TOKEN TOKEN(20) +#define UNTIL_TOKEN TOKEN(21) +#define PREDEF_TOKEN TOKEN(22) +#define DEF_TOKEN TOKEN(23) +#define ASM_TOKEN TOKEN(24) +#define IMPORT_TOKEN TOKEN(25) +#define EXPORT_TOKEN TOKEN(26) +#define DONE_TOKEN TOKEN(27) +#define RETURN_TOKEN TOKEN(28) +#define BREAK_TOKEN TOKEN(29) +#define START_TOKEN TOKEN(30) +#define EXIT_TOKEN TOKEN(31) +#define EVAL_TOKEN TOKEN(32) +/* + * Double operand operators. + */ +#define SET_TOKEN TOKEN('=') +#define ADD_TOKEN TOKEN('+') +#define ADD_SELF_TOKEN TOKEN('a') +#define SUB_TOKEN TOKEN('-') +#define SUB_SELF_TOKEN TOKEN('u') +#define MUL_TOKEN TOKEN('*') +#define MUL_SELF_TOKEN TOKEN('m') +#define DIV_TOKEN TOKEN('/') +#define DIV_SELF_TOKEN TOKEN('d') +#define MOD_TOKEN TOKEN('%') +#define OR_TOKEN TOKEN('|') +#define OR_SELF_TOKEN TOKEN('o') +#define EOR_TOKEN TOKEN('^') +#define EOR_SELF_TOKEN TOKEN('x') +#define AND_TOKEN TOKEN('&') +#define AND_SELF_TOKEN TOKEN('n') +#define SHR_TOKEN TOKEN('R') +#define SHR_SELF_TOKEN TOKEN('r') +#define SHL_TOKEN TOKEN('L') +#define SHL_SELF_TOKEN TOKEN('l') +#define GT_TOKEN TOKEN('>') +#define GE_TOKEN TOKEN('H') +#define LT_TOKEN TOKEN('<') +#define LE_TOKEN TOKEN('B') +#define NE_TOKEN TOKEN('U') +#define EQ_TOKEN TOKEN('E') +#define LOGIC_AND_TOKEN TOKEN('N') +#define LOGIC_OR_TOKEN TOKEN('O') +/* + * Single operand operators. + */ +#define NEG_TOKEN TOKEN('-') +#define COMP_TOKEN TOKEN('~') +#define LOGIC_NOT_TOKEN TOKEN('!') +#define INC_TOKEN TOKEN('P') +#define DEC_TOKEN TOKEN('K') +#define BPTR_TOKEN TOKEN('^') +#define WPTR_TOKEN TOKEN('*') +#define POST_INC_TOKEN TOKEN('p') +#define POST_DEC_TOKEN TOKEN('k') +#define OPEN_PAREN_TOKEN TOKEN('(') +#define CLOSE_PAREN_TOKEN TOKEN(')') +#define OPEN_BRACKET_TOKEN TOKEN('[') +#define CLOSE_BRACKET_TOKEN TOKEN(']') +/* + * Misc. tokens. + */ +#define AT_TOKEN TOKEN('@') +#define DOT_TOKEN TOKEN('.') +#define COLON_TOKEN TOKEN(':') +#define POUND_TOKEN TOKEN('#') +#define COMMA_TOKEN TOKEN(',') +#define COMMENT_TOKEN TOKEN(';') +#define EOL_TOKEN TOKEN(0) +#define EOF_TOKEN TOKEN(0x7F) + +typedef unsigned char t_token; diff --git a/src/ArrayObj.s b/src/ArrayObj.s new file mode 100755 index 0000000..db367cf --- /dev/null +++ b/src/ArrayObj.s @@ -0,0 +1,52 @@ +;* +;* DUMMY CLASS FILE ARRAY OBJCT +;* + .BYTE $CA,$FE,$BA,$BE ; MAGIC + .BYTE $00,$00 ; MINOR 0 + .BYTE $00,$31 ; MAJOR 49 +;* +;* CONSTANT POOL +;* + .BYTE $00,$05 ; CONST POOL COUNT 5 +;* CONST POOL INDEX 1 + .BYTE 07 ; CLASS + .BYTE $00,$03 ; #3 +;* CONST POOL INDEX 2 + .BYTE 07 ; CLASS + .BYTE $00,$04 ; #4 +;* CONST POOL INDEX 3 + .BYTE $01 ; UTF8 + .BYTE $00,$01 ; STRLEN + .BYTE "]" +;* CONST POOL INDEX 4 + .BYTE $01 ; UTF8 + .BYTE $00,$10 ; STRLEN + .BYTE "java/lang/Object" +;* +;* ACCESS FLAGS +;* + .BYTE $00,$21 ; 0x0021 +;* +;* THIS CLASS +;* + .BYTE $00,$01 ; #1 +;* +;* SUPER CLASS +;* + .BYTE $00,$02 ; #2 +;* +;* INTERFACES +;* + .BYTE $00,$00 ; IFACE COUNT 0 +;* +;* FIELDS +;* + .BYTE $00,$00 ; FIELD COUNT 0 +;* +;* METHODS +;* + .BYTE $00,$00 ; METHOD COUNT 0 +;* +;* GLOBAL ATTRIBUTES +;* + .BYTE $00,$00 ; ATTRIB COUNT 0 diff --git a/src/ObjectObj.s b/src/ObjectObj.s new file mode 100755 index 0000000..d6b2c34 --- /dev/null +++ b/src/ObjectObj.s @@ -0,0 +1,396 @@ +;* +;* DUMMY JAVA OBJECT CLASSE FOR 6502 +;* +;* +;* CLASS FILE Object.class +;* + .BYTE $CA,$FE,$BA,$BE ; MAGIC + .BYTE $00,$00 ; MINOR 0 + .BYTE $00,$31 ; MAJOR 49 +;* +;* CONSTANT POOL +;* + .BYTE $00,$1A ; CONST POOL COUNT 26 +;* CONST POOL INDEX 1 + .BYTE $0A ; METHODREF + .BYTE $00,$03 ; CLASS #3 + .BYTE $00,$17 ; NAME AND TYPE #23 +;* CONST POOL INDEX 2 + .BYTE 07 ; CLASS + .BYTE $00,$19 ; #25 +;* CONST POOL INDEX 3 + .BYTE 07 ; CLASS + .BYTE $00,$00 ; #0 +;* CONST POOL INDEX 4 + .BYTE $01 ; UTF8 + .BYTE $00,$06 ; STRLEN + .BYTE "" +;* CONST POOL INDEX 5 + .BYTE $01 ; UTF8 + .BYTE $00,$03 ; STRLEN + .BYTE "()V" +;* CONST POOL INDEX 6 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "Code" +;* CONST POOL INDEX 7 + .BYTE $01 ; UTF8 + .BYTE $00,$05 ; STRLEN + .BYTE "clone" +;* CONST POOL INDEX 8 + .BYTE $01 ; UTF8 + .BYTE $00,$14 ; STRLEN + .BYTE "()Ljava/lang/Object;" +;* CONST POOL INDEX 9 + .BYTE $01 ; UTF8 + .BYTE $00,$06 ; STRLEN + .BYTE "equals" +;* CONST POOL INDEX 10 + .BYTE $01 ; UTF8 + .BYTE $00,$15 ; STRLEN + .BYTE "(Ljava/lang/Object;)Z" +;* CONST POOL INDEX 11 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "finalize" +;* CONST POOL INDEX 12 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "getClass" +;* CONST POOL INDEX 13 + .BYTE $01 ; UTF8 + .BYTE $00,$13 ; STRLEN + .BYTE "()Ljava/lang/Class;" +;* CONST POOL INDEX 14 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "hashCode" +;* CONST POOL INDEX 15 + .BYTE $01 ; UTF8 + .BYTE $00,$03 ; STRLEN + .BYTE "()I" +;* CONST POOL INDEX 16 + .BYTE $01 ; UTF8 + .BYTE $00,$06 ; STRLEN + .BYTE "notify" +;* CONST POOL INDEX 17 + .BYTE $01 ; UTF8 + .BYTE $00,$09 ; STRLEN + .BYTE "notifyAll" +;* CONST POOL INDEX 18 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "toString" +;* CONST POOL INDEX 19 + .BYTE $01 ; UTF8 + .BYTE $00,$14 ; STRLEN + .BYTE "()Ljava/lang/String;" +;* CONST POOL INDEX 20 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "wait" +;* CONST POOL INDEX 21 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "(J)V" +;* CONST POOL INDEX 22 + .BYTE $01 ; UTF8 + .BYTE $00,$05 ; STRLEN + .BYTE "(JI)V" +;* CONST POOL INDEX 23 + .BYTE $0C ; NAME AND TYPE + .BYTE $00,$04 ; NAME #4 + .BYTE $00,$05 ; DESC #5 +;* CONST POOL INDEX 24 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "6502" +;* CONST POOL INDEX 25 + .BYTE $01 ; UTF8 + .BYTE $00,$10 ; STRLEN + .BYTE "java/lang/Object" +;* +;* ACCESS FLAGS +;* + .BYTE $00,$21 ; 0x0021 +;* +;* THIS CLASS +;* + .BYTE $00,$02 ; #2 +;* +;* SUPER CLASS +;* + .BYTE $00,$00 ; #0 +;* +;* INTERFACES +;* + .BYTE $00,$00 ; IFACE COUNT 0 +;* +;* FIELDS +;* + .BYTE $00,$00 ; FIELD COUNT 0 +;* +;* METHODS +;* + .BYTE $00,$0C ; METHOD COUNT 12 +;******* METHOD INDEX 0 ******** + .BYTE $01,$01 ; ACCESS FLAGS 0x0101 + .BYTE $00,$04 ; NAME #4 + .BYTE $00,$05 ; DESC #5 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,24 ; NAME #24 + .BYTE $00,$00,>(M0A0END-M0A0BGN),<(M0A0END-M0A0BGN) +M0A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M0C0END-M0C0BGN),<(M0C0END-M0C0BGN) +M0C0BGN: + RTS +M0C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M0A0END: +;******* METHOD INDEX 1 ******** + .BYTE $00,$04 ; ACCESS FLAGS 0x0004 + .BYTE $00,$07 ; NAME #7 + .BYTE $00,$08 ; DESC #8 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$00,>(M1A0END-M1A0BGN),<(M1A0END-M1A0BGN) +M1A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M1C0END-M1C0BGN),<(M1C0END-M1C0BGN) +M1C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M1C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M1A0END: +;******* METHOD INDEX 2 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$09 ; NAME #9 + .BYTE $00,$0A ; DESC #10 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$00,>(M2A0END-M2A0BGN),<(M2A0END-M2A0BGN) +M2A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M2C0END-M2C0BGN),<(M2C0END-M2C0BGN) +M2C0BGN: + .BYTE $04 ; 00000: iconst_1 + .BYTE $AC ; 00001: ireturn +M2C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M2A0END: +;******* METHOD INDEX 3 - finalize ******** + .BYTE $01,$04 ; ACCESS FLAGS 0x0104 + .BYTE $00,$0B ; NAME #11 + .BYTE $00,$05 ; DESC #5 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,24 ; NAME #24 + .BYTE $00,$00,>(M3A0END-M3A0BGN),<(M3A0END-M3A0BGN) +M3A0BGN: +;* CODE: + .BYTE $00,$00 ; MAX STACK 0 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M3C0END-M3C0BGN),<(M3C0END-M3C0BGN) +M3C0BGN: + RTS +M3C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M3A0END: +;******* METHOD INDEX 4 ******** + .BYTE $00,$11 ; ACCESS FLAGS 0x0011 + .BYTE $00,$0C ; NAME #12 + .BYTE $00,$0D ; DESC #13 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$00,>(M4A0END-M4A0BGN),<(M4A0END-M4A0BGN) +M4A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M4C0END-M4C0BGN),<(M4C0END-M4C0BGN) +M4C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M4C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M4A0END: +;******* METHOD INDEX 5 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$0E ; NAME #14 + .BYTE $00,$0F ; DESC #15 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$00,>(M5A0END-M5A0BGN),<(M5A0END-M5A0BGN) +M5A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M5C0END-M5C0BGN),<(M5C0END-M5C0BGN) +M5C0BGN: + .BYTE $03 ; 00000: iconst_0 + .BYTE $AC ; 00001: ireturn +M5C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M5A0END: +;******* METHOD INDEX 6 ******** + .BYTE $00,$11 ; ACCESS FLAGS 0x0011 + .BYTE $00,$10 ; NAME #16 + .BYTE $00,$05 ; DESC #5 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$00,>(M6A0END-M6A0BGN),<(M6A0END-M6A0BGN) +M6A0BGN: +;* CODE: + .BYTE $00,$00 ; MAX STACK 0 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M6C0END-M6C0BGN),<(M6C0END-M6C0BGN) +M6C0BGN: + .BYTE $B1 ; 00000: return +M6C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M6A0END: +;******* METHOD INDEX 7 ******** + .BYTE $00,$11 ; ACCESS FLAGS 0x0011 + .BYTE $00,$11 ; NAME #17 + .BYTE $00,$05 ; DESC #5 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$00,>(M7A0END-M7A0BGN),<(M7A0END-M7A0BGN) +M7A0BGN: +;* CODE: + .BYTE $00,$00 ; MAX STACK 0 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M7C0END-M7C0BGN),<(M7C0END-M7C0BGN) +M7C0BGN: + .BYTE $B1 ; 00000: return +M7C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M7A0END: +;******* METHOD INDEX 8 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$12 ; NAME #18 + .BYTE $00,$13 ; DESC #19 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$00,>(M8A0END-M8A0BGN),<(M8A0END-M8A0BGN) +M8A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M8C0END-M8C0BGN),<(M8C0END-M8C0BGN) +M8C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M8C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M8A0END: +;******* METHOD INDEX 9 ******** + .BYTE $00,$11 ; ACCESS FLAGS 0x0011 + .BYTE $00,$14 ; NAME #20 + .BYTE $00,$05 ; DESC #5 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$00,>(M9A0END-M9A0BGN),<(M9A0END-M9A0BGN) +M9A0BGN: +;* CODE: + .BYTE $00,$00 ; MAX STACK 0 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M9C0END-M9C0BGN),<(M9C0END-M9C0BGN) +M9C0BGN: + .BYTE $B1 ; 00000: return +M9C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M9A0END: +;******* METHOD INDEX 10 ******** + .BYTE $00,$11 ; ACCESS FLAGS 0x0011 + .BYTE $00,$14 ; NAME #20 + .BYTE $00,$15 ; DESC #21 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$00,>(M10A0END-M10A0BGN),<(M10A0END-M10A0BGN) +M10A0BGN: +;* CODE: + .BYTE $00,$00 ; MAX STACK 0 + .BYTE $00,$03 ; MAX LOCALS 3 + .BYTE $00,$00,>(M10C0END-M10C0BGN),<(M10C0END-M10C0BGN) +M10C0BGN: + .BYTE $B1 ; 00000: return +M10C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M10A0END: +;******* METHOD INDEX 11 ******** + .BYTE $00,$11 ; ACCESS FLAGS 0x0011 + .BYTE $00,$14 ; NAME #20 + .BYTE $00,$16 ; DESC #22 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$00,>(M11A0END-M11A0BGN),<(M11A0END-M11A0BGN) +M11A0BGN: +;* CODE: + .BYTE $00,$00 ; MAX STACK 0 + .BYTE $00,$04 ; MAX LOCALS 4 + .BYTE $00,$00,>(M11C0END-M11C0BGN),<(M11C0END-M11C0BGN) +M11C0BGN: + .BYTE $B1 ; 00000: return +M11C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M11A0END: +;* +;* GLOBAL ATTRIBUTES +;* + .BYTE $00,$00 ; ATTRIB COUNT 0 diff --git a/src/StringObj.s b/src/StringObj.s new file mode 100755 index 0000000..82be6db --- /dev/null +++ b/src/StringObj.s @@ -0,0 +1,1356 @@ +;* +;* CLASS FILE _String.class +;* + .ORG $1000 ; DUMMY ADDRESS + .BYTE $CA,$FE,$BA,$BE ; MAGIC + .BYTE $00,$00 ; MINOR 0 + .BYTE $00,$31 ; MAJOR 49 +;* +;* CONSTANT POOL +;* + .BYTE $00,$46 ; CONST POOL COUNT 70 +;* CONST POOL INDEX 1 + .BYTE $0A ; METHODREF + .BYTE $00,$03 ; CLASS #3 + .BYTE $00,$41 ; NAME AND TYPE #65 +;* CONST POOL INDEX 2 + .BYTE 07 ; CLASS + .BYTE $00,68 ; #68 +;* CONST POOL INDEX 3 + .BYTE 07 ; CLASS + .BYTE $00,67 ; #67 +;* CONST POOL INDEX 4 + .BYTE $01 ; UTF8 + .BYTE $00,$01 ; STRLEN + .BYTE "_" +;* CONST POOL INDEX 5 + .BYTE $01 ; UTF8 + .BYTE $00,$01 ; STRLEN + .BYTE "I" +;* CONST POOL INDEX 6 + .BYTE $01 ; UTF8 + .BYTE $00,$06 ; STRLEN + .BYTE "" +;* CONST POOL INDEX 7 + .BYTE $01 ; UTF8 + .BYTE $00,$03 ; STRLEN + .BYTE "()V" +;* CONST POOL INDEX 8 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "Code" +;* CONST POOL INDEX 9 + .BYTE $01 ; UTF8 + .BYTE $00,$06 ; STRLEN + .BYTE "([BI)V" +;* CONST POOL INDEX 10 + .BYTE $01 ; UTF8 + .BYTE $00,$07 ; STRLEN + .BYTE "([BII)V" +;* CONST POOL INDEX 11 + .BYTE $01 ; UTF8 + .BYTE $00,$05 ; STRLEN + .BYTE "([C)V" +;* CONST POOL INDEX 12 + .BYTE $01 ; UTF8 + .BYTE $00,$07 ; STRLEN + .BYTE "([CII)V" +;* CONST POOL INDEX 13 + .BYTE $01 ; UTF8 + .BYTE $00,$15 ; STRLEN + .BYTE "(Ljava/lang/String;)V" +;* CONST POOL INDEX 14 + .BYTE $01 ; UTF8 + .BYTE $00,$1B ; STRLEN + .BYTE "(Ljava/lang/StringBuffer;)V" +;* CONST POOL INDEX 15 + .BYTE $01 ; UTF8 + .BYTE $00,$06 ; STRLEN + .BYTE "charAt" +;* CONST POOL INDEX 16 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "(I)C" +;* CONST POOL INDEX 17 + .BYTE $01 ; UTF8 + .BYTE $00,$09 ; STRLEN + .BYTE "compareTo" +;* CONST POOL INDEX 18 + .BYTE $01 ; UTF8 + .BYTE $00,$15 ; STRLEN + .BYTE "(Ljava/lang/String;)I" +;* CONST POOL INDEX 19 + .BYTE $01 ; UTF8 + .BYTE $00,$06 ; STRLEN + .BYTE "concat" +;* CONST POOL INDEX 20 + .BYTE $01 ; UTF8 + .BYTE $00,$26 ; STRLEN + .BYTE "(Ljava/lang/String;)Ljava/lang/String;" +;* CONST POOL INDEX 21 + .BYTE $01 ; UTF8 + .BYTE $00,$0B ; STRLEN + .BYTE "copyValueOf" +;* CONST POOL INDEX 22 + .BYTE $01 ; UTF8 + .BYTE $00,$16 ; STRLEN + .BYTE "([C)Ljava/lang/String;" +;* CONST POOL INDEX 23 + .BYTE $01 ; UTF8 + .BYTE $00,$18 ; STRLEN + .BYTE "([CII)Ljava/lang/String;" +;* CONST POOL INDEX 24 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "endsWith" +;* CONST POOL INDEX 25 + .BYTE $01 ; UTF8 + .BYTE $00,$15 ; STRLEN + .BYTE "(Ljava/lang/String;)Z" +;* CONST POOL INDEX 26 + .BYTE $01 ; UTF8 + .BYTE $00,$06 ; STRLEN + .BYTE "equals" +;* CONST POOL INDEX 27 + .BYTE $01 ; UTF8 + .BYTE $00,$15 ; STRLEN + .BYTE "(Ljava/lang/Object;)Z" +;* CONST POOL INDEX 28 + .BYTE $01 ; UTF8 + .BYTE $00,$10 ; STRLEN + .BYTE "equalsIgnoreCase" +;* CONST POOL INDEX 29 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "getBytes" +;* CONST POOL INDEX 30 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "(II[BI)V" +;* CONST POOL INDEX 31 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "getChars" +;* CONST POOL INDEX 32 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "(II[CI)V" +;* CONST POOL INDEX 33 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "hashCode" +;* CONST POOL INDEX 34 + .BYTE $01 ; UTF8 + .BYTE $00,$03 ; STRLEN + .BYTE "()I" +;* CONST POOL INDEX 35 + .BYTE $01 ; UTF8 + .BYTE $00,$07 ; STRLEN + .BYTE "indexOf" +;* CONST POOL INDEX 36 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "(I)I" +;* CONST POOL INDEX 37 + .BYTE $01 ; UTF8 + .BYTE $00,$05 ; STRLEN + .BYTE "(II)I" +;* CONST POOL INDEX 38 + .BYTE $01 ; UTF8 + .BYTE $00,$16 ; STRLEN + .BYTE "(Ljava/lang/String;I)I" +;* CONST POOL INDEX 39 + .BYTE $01 ; UTF8 + .BYTE $00,$06 ; STRLEN + .BYTE "intern" +;* CONST POOL INDEX 40 + .BYTE $01 ; UTF8 + .BYTE $00,$14 ; STRLEN + .BYTE "()Ljava/lang/String;" +;* CONST POOL INDEX 41 + .BYTE $01 ; UTF8 + .BYTE $00,$0B ; STRLEN + .BYTE "lastIndexOf" +;* CONST POOL INDEX 42 + .BYTE $01 ; UTF8 + .BYTE $00,$06 ; STRLEN + .BYTE "length" +;* CONST POOL INDEX 43 + .BYTE $01 ; UTF8 + .BYTE $00,$0D ; STRLEN + .BYTE "regionMathces" +;* CONST POOL INDEX 44 + .BYTE $01 ; UTF8 + .BYTE $00,$19 ; STRLEN + .BYTE "(ZILjava/lang/String;II)Z" +;* CONST POOL INDEX 45 + .BYTE $01 ; UTF8 + .BYTE $00,$18 ; STRLEN + .BYTE "(ILjava/lang/String;II)Z" +;* CONST POOL INDEX 46 + .BYTE $01 ; UTF8 + .BYTE $00,$07 ; STRLEN + .BYTE "replace" +;* CONST POOL INDEX 47 + .BYTE $01 ; UTF8 + .BYTE $00,$16 ; STRLEN + .BYTE "(CC)Ljava/lang/String;" +;* CONST POOL INDEX 48 + .BYTE $01 ; UTF8 + .BYTE $00,$0A ; STRLEN + .BYTE "startsWith" +;* CONST POOL INDEX 49 + .BYTE $01 ; UTF8 + .BYTE $00,$09 ; STRLEN + .BYTE "startWith" +;* CONST POOL INDEX 50 + .BYTE $01 ; UTF8 + .BYTE $00,$16 ; STRLEN + .BYTE "(Ljava/lang/String;I)Z" +;* CONST POOL INDEX 51 + .BYTE $01 ; UTF8 + .BYTE $00,$09 ; STRLEN + .BYTE "subString" +;* CONST POOL INDEX 52 + .BYTE $01 ; UTF8 + .BYTE $00,$15 ; STRLEN + .BYTE "(I)Ljava/lang/String;" +;* CONST POOL INDEX 53 + .BYTE $01 ; UTF8 + .BYTE $00,$16 ; STRLEN + .BYTE "(II)Ljava/lang/String;" +;* CONST POOL INDEX 54 + .BYTE $01 ; UTF8 + .BYTE $00,$0B ; STRLEN + .BYTE "toCharArray" +;* CONST POOL INDEX 55 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "()[C" +;* CONST POOL INDEX 56 + .BYTE $01 ; UTF8 + .BYTE $00,$0B ; STRLEN + .BYTE "toLowerCase" +;* CONST POOL INDEX 57 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "toString" +;* CONST POOL INDEX 58 + .BYTE $01 ; UTF8 + .BYTE $00,$0B ; STRLEN + .BYTE "toUpperCase" +;* CONST POOL INDEX 59 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "trim" +;* CONST POOL INDEX 60 + .BYTE $01 ; UTF8 + .BYTE $00,$07 ; STRLEN + .BYTE "valueOf" +;* CONST POOL INDEX 61 + .BYTE $01 ; UTF8 + .BYTE $00,$15 ; STRLEN + .BYTE "(Z)Ljava/lang/String;" +;* CONST POOL INDEX 62 + .BYTE $01 ; UTF8 + .BYTE $00,$15 ; STRLEN + .BYTE "(C)Ljava/lang/String;" +;* CONST POOL INDEX 63 + .BYTE $01 ; UTF8 + .BYTE $00,$15 ; STRLEN + .BYTE "(F)Ljava/lang/String;" +;* CONST POOL INDEX 64 + .BYTE $01 ; UTF8 + .BYTE $00,$26 ; STRLEN + .BYTE "(Ljava/lang/Object;)Ljava/lang/String;" +;* CONST POOL INDEX 65 + .BYTE $0C ; NAME AND TYPE + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$07 ; DESC #7 +;* CONST POOL INDEX 66 + .BYTE $01 ; UTF8 + .BYTE $00,$06 ; STRLEN + .BYTE "String" +;* CONST POOL INDEX 67 + .BYTE $01 ; UTF8 + .BYTE $00,$10 ; STRLEN + .BYTE "java/lang/Object" +;* CONST POOL INDEX 68 + .BYTE $01 ; UTF8 + .BYTE $00,$10 ; STRLEN + .BYTE "java/lang/String" +;* CONST POOL INDEX 69 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "6502" +;* +;* ACCESS FLAGS +;* + .BYTE $00,$31 ; 0x0031 +;* +;* THIS CLASS +;* + .BYTE $00,$02 ; #2 +;* +;* SUPER CLASS +;* + .BYTE $00,$03 ; #3 +;* +;* INTERFACES +;* + .BYTE $00,$00 ; IFACE COUNT 0 +;* +;* FIELDS +;* +.IF 0 + .BYTE $00,$01 ; FIELD COUNT 1 +;******* FIELD INDEX 0 ******** + .BYTE $00,$02 ; ACCESS FLAGS 0x0002 + .BYTE $00,$04 ; NAME #4 + .BYTE $00,$05 ; DESC #5 + .BYTE $00,$00 ; ATTRIB COUNT 0 +.ELSE + .BYTE $00,$00 ; FIELDS COUNT 0 +.ENDIF +;* +;* METHODS +;* +; .BYTE $00,$2F ; METHOD COUNT 47 + .BYTE $00,5 ; METHOD COUNT 5 +;******* METHOD INDEX 0 - String() ******** + .BYTE $01,$01 ; ACCESS FLAGS 0x0101 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$07 ; DESC #7 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,69 ; NAME #69 + .BYTE $00,$00,>(M0A0END-M0A0BGN),<(M0A0END-M0A0BGN) +M0A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M0C0END-M0C0BGN),<(M0C0END-M0C0BGN) +M0C0BGN: + RTS +M0C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M0A0END: +;******* METHOD INDEX 1 - String(byte ascii[], int hibyte) ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$09 ; DESC #9 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M1A0END-M1A0BGN),<(M1A0END-M1A0BGN) +M1A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$03 ; MAX LOCALS 3 + .BYTE $00,$00,>(M1C0END-M1C0BGN),<(M1C0END-M1C0BGN) +M1C0BGN: + .BYTE $2A ; 00000: aload_0 + .BYTE $B7,$00,$01 ; 00001: invokespecial #1 + .BYTE $B1 ; 00004: return +M1C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M1A0END: +;******* METHOD INDEX 2 - String(byte ascii[], int offset, int count) ******** + .BYTE $01,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$0A ; DESC #10 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,69 ; NAME #69 + .BYTE $00,$00,>(M2A0END-M2A0BGN),<(M2A0END-M2A0BGN) +M2A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$05 ; MAX LOCALS 5 + .BYTE $00,$00,>(M2C0END-M2C0BGN),<(M2C0END-M2C0BGN) +M2C0BGN: + RTS +M2C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M2A0END: +;******* METHOD INDEX 3 - charAt ******** + .BYTE $01,$01 ; ACCESS FLAGS 0x0101 + .BYTE $00,$0F ; NAME #15 + .BYTE $00,$10 ; DESC #16 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,69 ; NAME #69 + .BYTE $00,$00,>(M7A0END-M7A0BGN),<(M7A0END-M7A0BGN) +M7A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M7C0END-M7C0BGN),<(M7C0END-M7C0BGN) +M7C0BGN: + RTS +M7C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M7A0END: +;******* METHOD INDEX 4 - length ******** + .BYTE $01,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$2A ; NAME #42 + .BYTE $00,$22 ; DESC #34 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,69 ; NAME #69 + .BYTE $00,$00,>(M27A0END-M27A0BGN),<(M27A0END-M27A0BGN) +M27A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M27C0END-M27C0BGN),<(M27C0END-M27C0BGN) +M27C0BGN: + RTS +M27C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M27A0END: +;******* METHOD INDEX 5 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$0B ; DESC #11 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M3A0END-M3A0BGN),<(M3A0END-M3A0BGN) +M3A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M3C0END-M3C0BGN),<(M3C0END-M3C0BGN) +M3C0BGN: + .BYTE $2A ; 00000: aload_0 + .BYTE $B7,$00,$01 ; 00001: invokespecial #1 + .BYTE $B1 ; 00004: return +M3C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M3A0END: +;******* METHOD INDEX 6 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$0C ; DESC #12 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M4A0END-M4A0BGN),<(M4A0END-M4A0BGN) +M4A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$04 ; MAX LOCALS 4 + .BYTE $00,$00,>(M4C0END-M4C0BGN),<(M4C0END-M4C0BGN) +M4C0BGN: + .BYTE $2A ; 00000: aload_0 + .BYTE $B7,$00,$01 ; 00001: invokespecial #1 + .BYTE $B1 ; 00004: return +M4C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M4A0END: +;******* METHOD INDEX 7 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$0D ; DESC #13 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M5A0END-M5A0BGN),<(M5A0END-M5A0BGN) +M5A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M5C0END-M5C0BGN),<(M5C0END-M5C0BGN) +M5C0BGN: + .BYTE $2A ; 00000: aload_0 + .BYTE $B7,$00,$01 ; 00001: invokespecial #1 + .BYTE $B1 ; 00004: return +M5C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M5A0END: +;******* METHOD INDEX 8 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$0E ; DESC #14 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M6A0END-M6A0BGN),<(M6A0END-M6A0BGN) +M6A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M6C0END-M6C0BGN),<(M6C0END-M6C0BGN) +M6C0BGN: + .BYTE $2A ; 00000: aload_0 + .BYTE $B7,$00,$01 ; 00001: invokespecial #1 + .BYTE $B1 ; 00004: return +M6C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M6A0END: +;******* METHOD INDEX 9 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$11 ; NAME #17 + .BYTE $00,$12 ; DESC #18 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M8A0END-M8A0BGN),<(M8A0END-M8A0BGN) +M8A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M8C0END-M8C0BGN),<(M8C0END-M8C0BGN) +M8C0BGN: + .BYTE $03 ; 00000: iconst_0 + .BYTE $AC ; 00001: ireturn +M8C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M8A0END: +;******* METHOD INDEX 10 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$13 ; NAME #19 + .BYTE $00,$14 ; DESC #20 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M9A0END-M9A0BGN),<(M9A0END-M9A0BGN) +M9A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M9C0END-M9C0BGN),<(M9C0END-M9C0BGN) +M9C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M9C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M9A0END: +;******* METHOD INDEX 11 ******** + .BYTE $00,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$15 ; NAME #21 + .BYTE $00,$16 ; DESC #22 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M10A0END-M10A0BGN),<(M10A0END-M10A0BGN) +M10A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M10C0END-M10C0BGN),<(M10C0END-M10C0BGN) +M10C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M10C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M10A0END: +;******* METHOD INDEX 12 ******** + .BYTE $00,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$15 ; NAME #21 + .BYTE $00,$17 ; DESC #23 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M11A0END-M11A0BGN),<(M11A0END-M11A0BGN) +M11A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$03 ; MAX LOCALS 3 + .BYTE $00,$00,>(M11C0END-M11C0BGN),<(M11C0END-M11C0BGN) +M11C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M11C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M11A0END: +;******* METHOD INDEX 13 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$18 ; NAME #24 + .BYTE $00,$19 ; DESC #25 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M12A0END-M12A0BGN),<(M12A0END-M12A0BGN) +M12A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M12C0END-M12C0BGN),<(M12C0END-M12C0BGN) +M12C0BGN: + .BYTE $04 ; 00000: iconst_1 + .BYTE $AC ; 00001: ireturn +M12C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M12A0END: +;******* METHOD INDEX 14 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$1A ; NAME #26 + .BYTE $00,$1B ; DESC #27 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M13A0END-M13A0BGN),<(M13A0END-M13A0BGN) +M13A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M13C0END-M13C0BGN),<(M13C0END-M13C0BGN) +M13C0BGN: + .BYTE $04 ; 00000: iconst_1 + .BYTE $AC ; 00001: ireturn +M13C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M13A0END: +;******* METHOD INDEX 15 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$1C ; NAME #28 + .BYTE $00,$19 ; DESC #25 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M14A0END-M14A0BGN),<(M14A0END-M14A0BGN) +M14A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M14C0END-M14C0BGN),<(M14C0END-M14C0BGN) +M14C0BGN: + .BYTE $04 ; 00000: iconst_1 + .BYTE $AC ; 00001: ireturn +M14C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M14A0END: +;******* METHOD INDEX 16 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$1D ; NAME #29 + .BYTE $00,$1E ; DESC #30 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M15A0END-M15A0BGN),<(M15A0END-M15A0BGN) +M15A0BGN: +;* CODE: + .BYTE $00,$00 ; MAX STACK 0 + .BYTE $00,$05 ; MAX LOCALS 5 + .BYTE $00,$00,>(M15C0END-M15C0BGN),<(M15C0END-M15C0BGN) +M15C0BGN: + .BYTE $B1 ; 00000: return +M15C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M15A0END: +;******* METHOD INDEX 17 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$1F ; NAME #31 + .BYTE $00,$20 ; DESC #32 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M16A0END-M16A0BGN),<(M16A0END-M16A0BGN) +M16A0BGN: +;* CODE: + .BYTE $00,$00 ; MAX STACK 0 + .BYTE $00,$05 ; MAX LOCALS 5 + .BYTE $00,$00,>(M16C0END-M16C0BGN),<(M16C0END-M16C0BGN) +M16C0BGN: + .BYTE $B1 ; 00000: return +M16C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M16A0END: +;******* METHOD INDEX 18 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$21 ; NAME #33 + .BYTE $00,$22 ; DESC #34 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M17A0END-M17A0BGN),<(M17A0END-M17A0BGN) +M17A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M17C0END-M17C0BGN),<(M17C0END-M17C0BGN) +M17C0BGN: + .BYTE $03 ; 00000: iconst_0 + .BYTE $AC ; 00001: ireturn +M17C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M17A0END: +;******* METHOD INDEX 19 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$23 ; NAME #35 + .BYTE $00,$24 ; DESC #36 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M18A0END-M18A0BGN),<(M18A0END-M18A0BGN) +M18A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M18C0END-M18C0BGN),<(M18C0END-M18C0BGN) +M18C0BGN: + .BYTE $03 ; 00000: iconst_0 + .BYTE $AC ; 00001: ireturn +M18C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M18A0END: +;******* METHOD INDEX 20 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$23 ; NAME #35 + .BYTE $00,$25 ; DESC #37 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M19A0END-M19A0BGN),<(M19A0END-M19A0BGN) +M19A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$03 ; MAX LOCALS 3 + .BYTE $00,$00,>(M19C0END-M19C0BGN),<(M19C0END-M19C0BGN) +M19C0BGN: + .BYTE $03 ; 00000: iconst_0 + .BYTE $AC ; 00001: ireturn +M19C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M19A0END: +;******* METHOD INDEX 21 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$23 ; NAME #35 + .BYTE $00,$12 ; DESC #18 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M20A0END-M20A0BGN),<(M20A0END-M20A0BGN) +M20A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M20C0END-M20C0BGN),<(M20C0END-M20C0BGN) +M20C0BGN: + .BYTE $03 ; 00000: iconst_0 + .BYTE $AC ; 00001: ireturn +M20C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M20A0END: +;******* METHOD INDEX 22 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$23 ; NAME #35 + .BYTE $00,$26 ; DESC #38 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M21A0END-M21A0BGN),<(M21A0END-M21A0BGN) +M21A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$03 ; MAX LOCALS 3 + .BYTE $00,$00,>(M21C0END-M21C0BGN),<(M21C0END-M21C0BGN) +M21C0BGN: + .BYTE $03 ; 00000: iconst_0 + .BYTE $AC ; 00001: ireturn +M21C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M21A0END: +;******* METHOD INDEX 23 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$27 ; NAME #39 + .BYTE $00,$28 ; DESC #40 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M22A0END-M22A0BGN),<(M22A0END-M22A0BGN) +M22A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M22C0END-M22C0BGN),<(M22C0END-M22C0BGN) +M22C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M22C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M22A0END: +;******* METHOD INDEX 24 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$29 ; NAME #41 + .BYTE $00,$24 ; DESC #36 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M23A0END-M23A0BGN),<(M23A0END-M23A0BGN) +M23A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M23C0END-M23C0BGN),<(M23C0END-M23C0BGN) +M23C0BGN: + .BYTE $03 ; 00000: iconst_0 + .BYTE $AC ; 00001: ireturn +M23C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M23A0END: +;******* METHOD INDEX 25 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$29 ; NAME #41 + .BYTE $00,$25 ; DESC #37 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M24A0END-M24A0BGN),<(M24A0END-M24A0BGN) +M24A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$03 ; MAX LOCALS 3 + .BYTE $00,$00,>(M24C0END-M24C0BGN),<(M24C0END-M24C0BGN) +M24C0BGN: + .BYTE $03 ; 00000: iconst_0 + .BYTE $AC ; 00001: ireturn +M24C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M24A0END: +;******* METHOD INDEX 26 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$29 ; NAME #41 + .BYTE $00,$12 ; DESC #18 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M25A0END-M25A0BGN),<(M25A0END-M25A0BGN) +M25A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M25C0END-M25C0BGN),<(M25C0END-M25C0BGN) +M25C0BGN: + .BYTE $03 ; 00000: iconst_0 + .BYTE $AC ; 00001: ireturn +M25C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M25A0END: +;******* METHOD INDEX 27 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$29 ; NAME #41 + .BYTE $00,$26 ; DESC #38 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M26A0END-M26A0BGN),<(M26A0END-M26A0BGN) +M26A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$03 ; MAX LOCALS 3 + .BYTE $00,$00,>(M26C0END-M26C0BGN),<(M26C0END-M26C0BGN) +M26C0BGN: + .BYTE $03 ; 00000: iconst_0 + .BYTE $AC ; 00001: ireturn +M26C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M26A0END: +;******* METHOD INDEX 28 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$2B ; NAME #43 + .BYTE $00,$2C ; DESC #44 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M28A0END-M28A0BGN),<(M28A0END-M28A0BGN) +M28A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$06 ; MAX LOCALS 6 + .BYTE $00,$00,>(M28C0END-M28C0BGN),<(M28C0END-M28C0BGN) +M28C0BGN: + .BYTE $04 ; 00000: iconst_1 + .BYTE $AC ; 00001: ireturn +M28C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M28A0END: +;******* METHOD INDEX 29 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$2B ; NAME #43 + .BYTE $00,$2D ; DESC #45 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M29A0END-M29A0BGN),<(M29A0END-M29A0BGN) +M29A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$05 ; MAX LOCALS 5 + .BYTE $00,$00,>(M29C0END-M29C0BGN),<(M29C0END-M29C0BGN) +M29C0BGN: + .BYTE $04 ; 00000: iconst_1 + .BYTE $AC ; 00001: ireturn +M29C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M29A0END: +;******* METHOD INDEX 30 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$2E ; NAME #46 + .BYTE $00,$2F ; DESC #47 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M30A0END-M30A0BGN),<(M30A0END-M30A0BGN) +M30A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$03 ; MAX LOCALS 3 + .BYTE $00,$00,>(M30C0END-M30C0BGN),<(M30C0END-M30C0BGN) +M30C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M30C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M30A0END: +;******* METHOD INDEX 31 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$30 ; NAME #48 + .BYTE $00,$19 ; DESC #25 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M31A0END-M31A0BGN),<(M31A0END-M31A0BGN) +M31A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M31C0END-M31C0BGN),<(M31C0END-M31C0BGN) +M31C0BGN: + .BYTE $04 ; 00000: iconst_1 + .BYTE $AC ; 00001: ireturn +M31C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M31A0END: +;******* METHOD INDEX 32 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$31 ; NAME #49 + .BYTE $00,$32 ; DESC #50 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M32A0END-M32A0BGN),<(M32A0END-M32A0BGN) +M32A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$03 ; MAX LOCALS 3 + .BYTE $00,$00,>(M32C0END-M32C0BGN),<(M32C0END-M32C0BGN) +M32C0BGN: + .BYTE $04 ; 00000: iconst_1 + .BYTE $AC ; 00001: ireturn +M32C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M32A0END: +;******* METHOD INDEX 33 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$33 ; NAME #51 + .BYTE $00,$34 ; DESC #52 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M33A0END-M33A0BGN),<(M33A0END-M33A0BGN) +M33A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M33C0END-M33C0BGN),<(M33C0END-M33C0BGN) +M33C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M33C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M33A0END: +;******* METHOD INDEX 34 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$33 ; NAME #51 + .BYTE $00,$35 ; DESC #53 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M34A0END-M34A0BGN),<(M34A0END-M34A0BGN) +M34A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$03 ; MAX LOCALS 3 + .BYTE $00,$00,>(M34C0END-M34C0BGN),<(M34C0END-M34C0BGN) +M34C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M34C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M34A0END: +;******* METHOD INDEX 35 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$36 ; NAME #54 + .BYTE $00,$37 ; DESC #55 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M35A0END-M35A0BGN),<(M35A0END-M35A0BGN) +M35A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M35C0END-M35C0BGN),<(M35C0END-M35C0BGN) +M35C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M35C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M35A0END: +;******* METHOD INDEX 36 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$38 ; NAME #56 + .BYTE $00,$28 ; DESC #40 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M36A0END-M36A0BGN),<(M36A0END-M36A0BGN) +M36A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M36C0END-M36C0BGN),<(M36C0END-M36C0BGN) +M36C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M36C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M36A0END: +;******* METHOD INDEX 37 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$39 ; NAME #57 + .BYTE $00,$28 ; DESC #40 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M37A0END-M37A0BGN),<(M37A0END-M37A0BGN) +M37A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M37C0END-M37C0BGN),<(M37C0END-M37C0BGN) +M37C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M37C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M37A0END: +;******* METHOD INDEX 38 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$3A ; NAME #58 + .BYTE $00,$28 ; DESC #40 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M38A0END-M38A0BGN),<(M38A0END-M38A0BGN) +M38A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M38C0END-M38C0BGN),<(M38C0END-M38C0BGN) +M38C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M38C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M38A0END: +;******* METHOD INDEX 39 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$3B ; NAME #59 + .BYTE $00,$28 ; DESC #40 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M39A0END-M39A0BGN),<(M39A0END-M39A0BGN) +M39A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M39C0END-M39C0BGN),<(M39C0END-M39C0BGN) +M39C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M39C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M39A0END: +;******* METHOD INDEX 40 ******** + .BYTE $00,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$3C ; NAME #60 + .BYTE $00,$3D ; DESC #61 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M40A0END-M40A0BGN),<(M40A0END-M40A0BGN) +M40A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M40C0END-M40C0BGN),<(M40C0END-M40C0BGN) +M40C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M40C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M40A0END: +;******* METHOD INDEX 41 ******** + .BYTE $00,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$3C ; NAME #60 + .BYTE $00,$3E ; DESC #62 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M41A0END-M41A0BGN),<(M41A0END-M41A0BGN) +M41A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M41C0END-M41C0BGN),<(M41C0END-M41C0BGN) +M41C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M41C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M41A0END: +;******* METHOD INDEX 42 ******** + .BYTE $00,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$3C ; NAME #60 + .BYTE $00,$16 ; DESC #22 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M42A0END-M42A0BGN),<(M42A0END-M42A0BGN) +M42A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M42C0END-M42C0BGN),<(M42C0END-M42C0BGN) +M42C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M42C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M42A0END: +;******* METHOD INDEX 43 ******** + .BYTE $00,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$3C ; NAME #60 + .BYTE $00,$17 ; DESC #23 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M43A0END-M43A0BGN),<(M43A0END-M43A0BGN) +M43A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$03 ; MAX LOCALS 3 + .BYTE $00,$00,>(M43C0END-M43C0BGN),<(M43C0END-M43C0BGN) +M43C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M43C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M43A0END: +;******* METHOD INDEX 44 ******** + .BYTE $00,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$3C ; NAME #60 + .BYTE $00,$3F ; DESC #63 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M44A0END-M44A0BGN),<(M44A0END-M44A0BGN) +M44A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M44C0END-M44C0BGN),<(M44C0END-M44C0BGN) +M44C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M44C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M44A0END: +;******* METHOD INDEX 45 ******** + .BYTE $00,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$3C ; NAME #60 + .BYTE $00,$34 ; DESC #52 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M45A0END-M45A0BGN),<(M45A0END-M45A0BGN) +M45A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M45C0END-M45C0BGN),<(M45C0END-M45C0BGN) +M45C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M45C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M45A0END: +;******* METHOD INDEX 46 ******** + .BYTE $00,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$3C ; NAME #60 + .BYTE $00,$40 ; DESC #64 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M46A0END-M46A0BGN),<(M46A0END-M46A0BGN) +M46A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M46C0END-M46C0BGN),<(M46C0END-M46C0BGN) +M46C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M46C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M46A0END: +;* +;* GLOBAL ATTRIBUTES +;* + .BYTE $00,$00 ; ATTRIB COUNT 0 diff --git a/src/_Object.java b/src/_Object.java new file mode 100755 index 0000000..516d8e9 --- /dev/null +++ b/src/_Object.java @@ -0,0 +1,16 @@ +public class _Object +{ + public _Object(){}; + + protected Object clone(){return null;}; + public boolean equals(Object obj){return true;}; + protected void finalize(){}; + public final Class _getClass(){return null;}; + public int hashCode(){return 0;}; + public final void _notify(){}; + public final void _notifyAll(){}; + public String toString(){return null;}; + public final void _wait(){}; + public final void _wait(long timeout){}; +// public final void _wait(long timeout, int nanos){}; +} diff --git a/src/_String.java b/src/_String.java new file mode 100755 index 0000000..8d5e913 --- /dev/null +++ b/src/_String.java @@ -0,0 +1,53 @@ +public final class _String +{ + private int hStrConst; + + public _String(){} + public _String(byte ascii[], int hibyte){} + public _String(byte ascii[], int hibyte, int offset, int count){} + public _String(char value[]){} + public _String(char value[], int offset, int count){} + public _String(String value){} + public _String(StringBuffer buffer){} + + public char charAt(int Index){return ' ';} + public int compareTo(String anotherString){return 0;} + public String concat(String str){return null;} + public static String copyValueOf(char data[]){return null;} + public static String copyValueOf(char data[], int offset, int count){return null;} + public boolean endsWith(String suffix){return true;} + public boolean equals(Object anObject){return true;} + public boolean equalsIgnoreCase(String anotherString){return true;} + public void getBytes(int srcBegin, int srcEnd, byte dst[], int dstEnd){} + public void getChars(int srcBegin, int srcEnd, char dst[], int dstEnd){} + public int hashCode(){return 0;} + public int indexOf(int ch){return 0;} + public int indexOf(int ch, int fromIndex){return 0;} + public int indexOf(String str){return 0;} + public int indexOf(String str, int fromIndex){return 0;} + public String intern(){return null;} + public int lastIndexOf(int ch){return 0;} + public int lastIndexOf(int ch, int fromIndex){return 0;} + public int lastIndexOf(String str){return 0;} + public int lastIndexOf(String str, int fromIndex){return 0;} + public int length(){return 0;} + public boolean regionMathces(boolean ignoreCase, int toffset, String other, int ooffset, int len){return true;} + public boolean regionMathces(int toffset, String other, int ooffset, int len){return true;} + public String replace(char oldChar, char newChar){return null;} + public boolean startsWith(String prefix){return true;} + public boolean startWith(String prefix, int toffset){return true;} + public String subString(int beginIndex){return null;} + public String subString(int beginIndex, int endIndex){return null;} + public char[] toCharArray(){return null;} + public String toLowerCase(){return null;} + public String toString(){return null;} + public String toUpperCase(){return null;} + public String trim(){return null;} + public static String valueOf(boolean b){return null;} + public static String valueOf(char c){return null;} + public static String valueOf(char data[]){return null;} + public static String valueOf(char data[], int offset, int count){return null;} + public static String valueOf(float f){return null;} + public static String valueOf(int i){return null;} + public static String valueOf(Object obj){return null;} +} \ No newline at end of file diff --git a/src/apple2/AppleStuff.clasm b/src/apple2/AppleStuff.clasm new file mode 100755 index 0000000..d629054 --- /dev/null +++ b/src/apple2/AppleStuff.clasm @@ -0,0 +1,910 @@ +;* +;* CLASS FILE AppleStuff.class +;* + .ORG $1000 ; DUMMY ADDRESS + .BYTE $CA,$FE,$BA,$BE ; MAGIC + .BYTE $00,$00 ; MINOR 0 + .BYTE $00,$31 ; MAJOR 49 +;* +;* CONSTANT POOL +;* + .BYTE $00,$47 ; CONST POOL COUNT 71 +;* CONST POOL INDEX 1 + .BYTE $0A ; METHODREF + .BYTE $00,$17 ; CLASS #23 + .BYTE $00,$37 ; NAME AND TYPE #55 +;* CONST POOL INDEX 2 + .BYTE $09 ; FIELDREF + .BYTE $00,$16 ; CLASS #22 + .BYTE $00,$38 ; NAME AND TYPE #56 +;* CONST POOL INDEX 3 + .BYTE $03 ; INT + .BYTE $00,$00,$00,$0C ; 12 +;* CONST POOL INDEX 4 + .BYTE $0A ; METHODREF + .BYTE $00,$39 ; CLASS #57 + .BYTE $00,$3A ; NAME AND TYPE #58 +;* CONST POOL INDEX 5 + .BYTE $03 ; INT + .BYTE $00,$00,$C0,$51 ; 49233 +;* CONST POOL INDEX 6 + .BYTE $0A ; METHODREF + .BYTE $00,$39 ; CLASS #57 + .BYTE $00,$3B ; NAME AND TYPE #59 +;* CONST POOL INDEX 7 + .BYTE $03 ; INT + .BYTE $00,$00,$C0,$54 ; 49236 +;* CONST POOL INDEX 8 + .BYTE $0A ; METHODREF + .BYTE $00,$39 ; CLASS #57 + .BYTE $00,$3C ; NAME AND TYPE #60 +;* CONST POOL INDEX 9 + .BYTE $03 ; INT + .BYTE $00,$00,$FC,$58 ; 64600 +;* CONST POOL INDEX 10 + .BYTE $03 ; INT + .BYTE $00,$00,$C0,$56 ; 49238 +;* CONST POOL INDEX 11 + .BYTE $03 ; INT + .BYTE $00,$00,$C0,$53 ; 49235 +;* CONST POOL INDEX 12 + .BYTE $03 ; INT + .BYTE $00,$00,$C0,$50 ; 49232 +;* CONST POOL INDEX 13 + .BYTE $03 ; INT + .BYTE $00,$00,$F8,$36 ; 63542 +;* CONST POOL INDEX 14 + .BYTE $03 ; INT + .BYTE $00,$00,$C0,$52 ; 49234 +;* CONST POOL INDEX 15 + .BYTE $03 ; INT + .BYTE $00,$00,$F8,$32 ; 63538 +;* CONST POOL INDEX 16 + .BYTE $03 ; INT + .BYTE $00,$01,$40,$20 ; 81952 +;* CONST POOL INDEX 17 + .BYTE $03 ; INT + .BYTE $01,$00,$00,$00 ; 16777216 +;* CONST POOL INDEX 18 + .BYTE $03 ; INT + .BYTE $00,$00,$FF,$FF ; 65535 +;* CONST POOL INDEX 19 + .BYTE $03 ; INT + .BYTE $00,$00,$C0,$57 ; 49239 +;* CONST POOL INDEX 20 + .BYTE $03 ; INT + .BYTE $00,$00,$C0,$55 ; 49237 +;* CONST POOL INDEX 21 + .BYTE $0A ; METHODREF + .BYTE $00,$16 ; CLASS #22 + .BYTE $00,$3D ; NAME AND TYPE #61 +;* CONST POOL INDEX 22 + .BYTE 07 ; CLASS + .BYTE $00,$3E ; #62 +;* CONST POOL INDEX 23 + .BYTE 07 ; CLASS + .BYTE $00,$3F ; #63 +;* CONST POOL INDEX 24 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "hrHandle" +;* CONST POOL INDEX 25 + .BYTE $01 ; UTF8 + .BYTE $00,$01 ; STRLEN + .BYTE "I" +;* CONST POOL INDEX 26 + .BYTE $01 ; UTF8 + .BYTE $00,$06 ; STRLEN + .BYTE "" +;* CONST POOL INDEX 27 + .BYTE $01 ; UTF8 + .BYTE $00,$03 ; STRLEN + .BYTE "()V" +;* CONST POOL INDEX 28 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "Code" +;* CONST POOL INDEX 29 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "text" +;* CONST POOL INDEX 30 + .BYTE $01 ; UTF8 + .BYTE $00,$0A ; STRLEN + .BYTE "keyPressed" +;* CONST POOL INDEX 31 + .BYTE $01 ; UTF8 + .BYTE $00,$03 ; STRLEN + .BYTE "()Z" +;* CONST POOL INDEX 32 + .BYTE $01 ; UTF8 + .BYTE $00,$06 ; STRLEN + .BYTE "getKey" +;* CONST POOL INDEX 33 + .BYTE $01 ; UTF8 + .BYTE $00,$03 ; STRLEN + .BYTE "()C" +;* CONST POOL INDEX 34 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "loResMix" +;* CONST POOL INDEX 35 + .BYTE $01 ; UTF8 + .BYTE $00,$05 ; STRLEN + .BYTE "loRes" +;* CONST POOL INDEX 36 + .BYTE $01 ; UTF8 + .BYTE $00,$07 ; STRLEN + .BYTE "lrColor" +;* CONST POOL INDEX 37 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "(I)V" +;* CONST POOL INDEX 38 + .BYTE $01 ; UTF8 + .BYTE $00,$07 ; STRLEN + .BYTE "lrHLine" +;* CONST POOL INDEX 39 + .BYTE $01 ; UTF8 + .BYTE $00,$07 ; STRLEN + .BYTE "(IIII)V" +;* CONST POOL INDEX 40 + .BYTE $01 ; UTF8 + .BYTE $00,$06 ; STRLEN + .BYTE "(III)V" +;* CONST POOL INDEX 41 + .BYTE $01 ; UTF8 + .BYTE $00,$07 ; STRLEN + .BYTE "lrVLine" +;* CONST POOL INDEX 42 + .BYTE $01 ; UTF8 + .BYTE $00,$06 ; STRLEN + .BYTE "lrPlot" +;* CONST POOL INDEX 43 + .BYTE $01 ; UTF8 + .BYTE $00,$05 ; STRLEN + .BYTE "(II)V" +;* CONST POOL INDEX 44 + .BYTE $01 ; UTF8 + .BYTE $00,$05 ; STRLEN + .BYTE "hiRes" +;* CONST POOL INDEX 45 + .BYTE $01 ; UTF8 + .BYTE $00,$07 ; STRLEN + .BYTE "hrColor" +;* CONST POOL INDEX 46 + .BYTE $01 ; UTF8 + .BYTE $00,$06 ; STRLEN + .BYTE "hrPlot" +;* CONST POOL INDEX 47 + .BYTE $01 ; UTF8 + .BYTE $00,$06 ; STRLEN + .BYTE "hrLine" +;* CONST POOL INDEX 48 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "hrLineTo" +;* CONST POOL INDEX 49 + .BYTE $01 ; UTF8 + .BYTE $00,$06 ; STRLEN + .BYTE "paddle" +;* CONST POOL INDEX 50 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "(I)I" +;* CONST POOL INDEX 51 + .BYTE $01 ; UTF8 + .BYTE $00,$06 ; STRLEN + .BYTE "button" +;* CONST POOL INDEX 52 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "(I)Z" +;* CONST POOL INDEX 53 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "tone" +;* CONST POOL INDEX 54 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "" +;* CONST POOL INDEX 55 + .BYTE $0C ; NAME AND TYPE + .BYTE $00,$1A ; NAME #26 + .BYTE $00,$1B ; DESC #27 +;* CONST POOL INDEX 56 + .BYTE $0C ; NAME AND TYPE + .BYTE $00,$18 ; NAME #24 + .BYTE $00,$19 ; DESC #25 +;* CONST POOL INDEX 57 + .BYTE 07 ; CLASS + .BYTE $00,$40 ; #64 +;* CONST POOL INDEX 58 + .BYTE $0C ; NAME AND TYPE + .BYTE $00,$41 ; NAME #65 + .BYTE $00,$42 ; DESC #66 +;* CONST POOL INDEX 59 + .BYTE $0C ; NAME AND TYPE + .BYTE $00,$43 ; NAME #67 + .BYTE $00,$32 ; DESC #50 +;* CONST POOL INDEX 60 + .BYTE $0C ; NAME AND TYPE + .BYTE $00,$44 ; NAME #68 + .BYTE $00,$45 ; DESC #69 +;* CONST POOL INDEX 61 + .BYTE $0C ; NAME AND TYPE + .BYTE $00,$35 ; NAME #53 + .BYTE $00,$28 ; DESC #40 +;* CONST POOL INDEX 62 + .BYTE $01 ; UTF8 + .BYTE $00,$11 ; STRLEN + .BYTE "apple2/AppleStuff" +;* CONST POOL INDEX 63 + .BYTE $01 ; UTF8 + .BYTE $00,$10 ; STRLEN + .BYTE "java/lang/Object" +;* CONST POOL INDEX 64 + .BYTE $01 ; UTF8 + .BYTE $00,$0B ; STRLEN + .BYTE "apple2/vm02" +;* CONST POOL INDEX 65 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "call" +;* CONST POOL INDEX 66 + .BYTE $01 ; UTF8 + .BYTE $00,$05 ; STRLEN + .BYTE "(II)I" +;* CONST POOL INDEX 67 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "peekByte" +;* CONST POOL INDEX 68 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "pokeByte" +;* CONST POOL INDEX 69 + .BYTE $01 ; UTF8 + .BYTE $00,$05 ; STRLEN + .BYTE "(IB)V" +;* CONST POOL INDEX 70 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "6502" +;* +;* ACCESS FLAGS +;* + .BYTE $00,$21 ; 0x0021 +;* +;* THIS CLASS +;* + .BYTE $00,$16 ; #22 +;* +;* SUPER CLASS +;* + .BYTE $00,$17 ; #23 +;* +;* INTERFACES +;* + .BYTE $00,$00 ; IFACE COUNT 0 +;* +;* FIELDS +;* + .BYTE $00,$01 ; FIELD COUNT 1 +;******* FIELD INDEX 0 ******** + .BYTE $00,$0A ; ACCESS FLAGS 0x000A + .BYTE $00,$18 ; NAME #24 + .BYTE $00,$19 ; DESC #25 + .BYTE $00,$00 ; ATTRIB COUNT 0 +;* +;* METHODS +;* + .BYTE $00,$17 ; METHOD COUNT 23 +;******* METHOD INDEX 0 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$1A ; NAME #26 + .BYTE $00,$1B ; DESC #27 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$1C ; NAME #28 + .BYTE $00,$00,>(M0A0END-M0A0BGN),<(M0A0END-M0A0BGN) +M0A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M0C0END-M0C0BGN),<(M0C0END-M0C0BGN) +M0C0BGN: + .BYTE $2A ; 00000: aload_0 + .BYTE $B7,$00,$01 ; 00001: invokespecial #1 + .BYTE $B1 ; 00004: return +M0C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M0A0END: +;******* METHOD INDEX 1 ******** + .BYTE $00,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$1D ; NAME #29 + .BYTE $00,$1B ; DESC #27 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$1C ; NAME #28 + .BYTE $00,$00,>(M1A0END-M1A0BGN),<(M1A0END-M1A0BGN) +M1A0BGN: +;* CODE: + .BYTE $00,$02 ; MAX STACK 2 + .BYTE $00,$00 ; MAX LOCALS 0 + .BYTE $00,$00,>(M1C0END-M1C0BGN),<(M1C0END-M1C0BGN) +M1C0BGN: + .BYTE $B2,$00,$02 ; 00000: getstatic #2 + .BYTE $99,$00,$10 ; 00003: ifeq +16 (000019) + .BYTE $B2,$00,$02 ; 00006: getstatic #2 + .BYTE $12,$03 ; 00009: ldc #3 + .BYTE $B8,$00,$04 ; 00011: invokestatic #4 + .BYTE $57 ; 00014: pop + .BYTE $03 ; 00015: iconst_0 + .BYTE $B3,$00,$02 ; 00016: putstatic #2 + .BYTE $12,$05 ; 00019: ldc #5 + .BYTE $B8,$00,$06 ; 00021: invokestatic #6 + .BYTE $57 ; 00024: pop + .BYTE $12,$07 ; 00025: ldc #7 + .BYTE $B8,$00,$06 ; 00027: invokestatic #6 + .BYTE $57 ; 00030: pop + .BYTE $10,$22 ; 00031: bipush 34 + .BYTE $03 ; 00033: iconst_0 + .BYTE $B8,$00,$08 ; 00034: invokestatic #8 + .BYTE $03 ; 00037: iconst_0 + .BYTE $12,$09 ; 00038: ldc #9 + .BYTE $B8,$00,$04 ; 00040: invokestatic #4 + .BYTE $57 ; 00043: pop + .BYTE $B1 ; 00044: return +M1C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M1A0END: +;******* METHOD INDEX 2 ******** + .BYTE $00,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$1E ; NAME #30 + .BYTE $00,$1F ; DESC #31 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$1C ; NAME #28 + .BYTE $00,$00,>(M2A0END-M2A0BGN),<(M2A0END-M2A0BGN) +M2A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$00 ; MAX LOCALS 0 + .BYTE $00,$00,>(M2C0END-M2C0BGN),<(M2C0END-M2C0BGN) +M2C0BGN: + .BYTE $11,$02,$80 ; 00000: sipush 640 + .BYTE $B8,$00,$06 ; 00003: invokestatic #6 + .BYTE $9E,$00,$07 ; 00006: ifle +7 (000013) + .BYTE $04 ; 00009: iconst_1 + .BYTE $A7,$00,$04 ; 00010: goto +4 (000014) + .BYTE $03 ; 00013: iconst_0 + .BYTE $AC ; 00014: ireturn +M2C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M2A0END: +;******* METHOD INDEX 3 ******** + .BYTE $00,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$20 ; NAME #32 + .BYTE $00,$21 ; DESC #33 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$1C ; NAME #28 + .BYTE $00,$00,>(M3A0END-M3A0BGN),<(M3A0END-M3A0BGN) +M3A0BGN: +;* CODE: + .BYTE $00,$02 ; MAX STACK 2 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M3C0END-M3C0BGN),<(M3C0END-M3C0BGN) +M3C0BGN: + .BYTE $03 ; 00000: iconst_0 + .BYTE $10,$76 ; 00001: bipush $76 + .BYTE $B8,$00,$04 ; 00003: invokestatic #4 + .BYTE $3B ; 00006: istore_0 + .BYTE $1A ; 00007: iload_0 + .BYTE $10,$7F ; 00008: bipush 127 + .BYTE $7E ; 00010: iand + .BYTE $92 ; 00011: i2c + .BYTE $AC ; 00012: ireturn +M3C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M3A0END: +;******* METHOD INDEX 4 ******** + .BYTE $00,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$22 ; NAME #34 + .BYTE $00,$1B ; DESC #27 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$1C ; NAME #28 + .BYTE $00,$00,>(M4A0END-M4A0BGN),<(M4A0END-M4A0BGN) +M4A0BGN: +;* CODE: + .BYTE $00,$02 ; MAX STACK 2 + .BYTE $00,$00 ; MAX LOCALS 0 + .BYTE $00,$00,>(M4C0END-M4C0BGN),<(M4C0END-M4C0BGN) +M4C0BGN: + .BYTE $12,$0A ; 00000: ldc #10 + .BYTE $B8,$00,$06 ; 00002: invokestatic #6 + .BYTE $57 ; 00005: pop + .BYTE $12,$0B ; 00006: ldc #11 + .BYTE $B8,$00,$06 ; 00008: invokestatic #6 + .BYTE $57 ; 00011: pop + .BYTE $12,$0C ; 00012: ldc #12 + .BYTE $B8,$00,$06 ; 00014: invokestatic #6 + .BYTE $57 ; 00017: pop + .BYTE $03 ; 00018: iconst_0 + .BYTE $12,$0D ; 00019: ldc #13 + .BYTE $B8,$00,$04 ; 00021: invokestatic #4 + .BYTE $57 ; 00024: pop + .BYTE $10,$22 ; 00025: bipush 34 + .BYTE $10,$14 ; 00027: bipush 20 + .BYTE $B8,$00,$08 ; 00029: invokestatic #8 + .BYTE $03 ; 00032: iconst_0 + .BYTE $12,$09 ; 00033: ldc #9 + .BYTE $B8,$00,$04 ; 00035: invokestatic #4 + .BYTE $57 ; 00038: pop + .BYTE $B1 ; 00039: return +M4C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M4A0END: +;******* METHOD INDEX 5 ******** + .BYTE $00,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$23 ; NAME #35 + .BYTE $00,$1B ; DESC #27 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$1C ; NAME #28 + .BYTE $00,$00,>(M5A0END-M5A0BGN),<(M5A0END-M5A0BGN) +M5A0BGN: +;* CODE: + .BYTE $00,$02 ; MAX STACK 2 + .BYTE $00,$00 ; MAX LOCALS 0 + .BYTE $00,$00,>(M5C0END-M5C0BGN),<(M5C0END-M5C0BGN) +M5C0BGN: + .BYTE $12,$0A ; 00000: ldc #10 + .BYTE $B8,$00,$06 ; 00002: invokestatic #6 + .BYTE $57 ; 00005: pop + .BYTE $12,$0E ; 00006: ldc #14 + .BYTE $B8,$00,$06 ; 00008: invokestatic #6 + .BYTE $57 ; 00011: pop + .BYTE $12,$0C ; 00012: ldc #12 + .BYTE $B8,$00,$06 ; 00014: invokestatic #6 + .BYTE $57 ; 00017: pop + .BYTE $03 ; 00018: iconst_0 + .BYTE $12,$0F ; 00019: ldc #15 + .BYTE $B8,$00,$04 ; 00021: invokestatic #4 + .BYTE $57 ; 00024: pop + .BYTE $B1 ; 00025: return +M5C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M5A0END: +;******* METHOD INDEX 6 - lrColor ******** + .BYTE $01,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$24 ; NAME #36 + .BYTE $00,$25 ; DESC #37 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,70 ; NAME #70 + .BYTE $00,$00,>(M6A0END-M6A0BGN),<(M6A0END-M6A0BGN) +M6A0BGN: +;* CODE: + .BYTE $00,$00 ; MAX STACK 0 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M6C0END-M6C0BGN),<(M6C0END-M6C0BGN) +M6C0BGN: + .INCLUDE "apple2/lrColor.s" +M6C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M6A0END: +;******* METHOD INDEX 7 - lrHLine(x1, x2, y, c) ******** + .BYTE $01,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$26 ; NAME #38 + .BYTE $00,$27 ; DESC #39 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,70 ; NAME #70 + .BYTE $00,$00,>(M7A0END-M7A0BGN),<(M7A0END-M7A0BGN) +M7A0BGN: +;* CODE: + .BYTE $00,$00 ; MAX STACK 0 + .BYTE $00,$04 ; MAX LOCALS 4 + .BYTE $00,$00,>(M7C0END-M7C0BGN),<(M7C0END-M7C0BGN) +M7C0BGN: + .INCLUDE "apple2/lrClrHLine.s" +M7C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M7A0END: +;******* METHOD INDEX 8 - lrHLine(x1, x2, y) ******** + .BYTE $01,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$26 ; NAME #38 + .BYTE $00,$28 ; DESC #40 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,70 ; NAME #70 + .BYTE $00,$00,>(M8A0END-M8A0BGN),<(M8A0END-M8A0BGN) +M8A0BGN: +;* CODE: + .BYTE $00,$00 ; MAX STACK 0 + .BYTE $00,$03 ; MAX LOCALS 3 + .BYTE $00,$00,>(M8C0END-M8C0BGN),<(M8C0END-M8C0BGN) +M8C0BGN: + .INCLUDE "apple2/lrHLine.s" +M8C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M8A0END: +;******* METHOD INDEX 9 - lrVLine(x, y1, y2, c) ******** + .BYTE $01,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$29 ; NAME #41 + .BYTE $00,$27 ; DESC #39 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,70 ; NAME #70 + .BYTE $00,$00,>(M9A0END-M9A0BGN),<(M9A0END-M9A0BGN) +M9A0BGN: +;* CODE: + .BYTE $00,$00 ; MAX STACK 0 + .BYTE $00,$04 ; MAX LOCALS 4 + .BYTE $00,$00,>(M9C0END-M9C0BGN),<(M9C0END-M9C0BGN) +M9C0BGN: + .INCLUDE "apple2/lrClrVLine.s" +M9C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M9A0END: +;******* METHOD INDEX 10 - lrVLine(x, y1, y2) ******** + .BYTE $01,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$29 ; NAME #41 + .BYTE $00,$28 ; DESC #40 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,70 ; NAME #70 + .BYTE $00,$00,>(M10A0END-M10A0BGN),<(M10A0END-M10A0BGN) +M10A0BGN: +;* CODE: + .BYTE $00,$00 ; MAX STACK 0 + .BYTE $00,$03 ; MAX LOCALS 3 + .BYTE $00,$00,>(M10C0END-M10C0BGN),<(M10C0END-M10C0BGN) +M10C0BGN: + .INCLUDE "apple2/lrVLine.s" +M10C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M10A0END: +;******* METHOD INDEX 11 - lrPlot(x, y, c) ******** + .BYTE $01,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$2A ; NAME #42 + .BYTE $00,$28 ; DESC #40 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,70 ; NAME #70 + .BYTE $00,$00,>(M11A0END-M11A0BGN),<(M11A0END-M11A0BGN) +M11A0BGN: +;* CODE: + .BYTE $00,$00 ; MAX STACK 0 + .BYTE $00,$03 ; MAX LOCALS 3 + .BYTE $00,$00,>(M11C0END-M11C0BGN),<(M11C0END-M11C0BGN) +M11C0BGN: + .INCLUDE "apple2/lrClrPlot.s" +M11C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M11A0END: +;******* METHOD INDEX 12 - lrPlot(x,y) ******** + .BYTE $01,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$2A ; NAME #42 + .BYTE $00,$2B ; DESC #43 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,70 ; NAME #70 + .BYTE $00,$00,>(M12A0END-M12A0BGN),<(M12A0END-M12A0BGN) +M12A0BGN: +;* CODE: + .BYTE $00,$00 ; MAX STACK 0 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M12C0END-M12C0BGN),<(M12C0END-M12C0BGN) +M12C0BGN: + .INCLUDE "apple2/lrPlot.s" +M12C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M12A0END: +;******* METHOD INDEX 13 - hiRes ******** + .BYTE $00,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$2C ; NAME #44 + .BYTE $00,$1F ; DESC #31 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$1C ; NAME #28 + .BYTE $00,$00,>(M13A0END-M13A0BGN),<(M13A0END-M13A0BGN) +M13A0BGN: +;* CODE: + .BYTE $00,$02 ; MAX STACK 2 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M13C0END-M13C0BGN),<(M13C0END-M13C0BGN) +M13C0BGN: + .BYTE $12,$10 ; 00000: ldc #16 + .BYTE $10,$0A ; 00002: bipush 10 + .BYTE $B8,$00,$04 ; 00004: invokestatic #4 + .BYTE $3B ; 00007: istore_0 + .BYTE $1A ; 00008: iload_0 + .BYTE $12,$11 ; 00009: ldc #17 + .BYTE $7E ; 00011: iand + .BYTE $9A,$00,$36 ; 00012: ifne +54 (000066) + .BYTE $1A ; 00015: iload_0 + .BYTE $12,$12 ; 00016: ldc #18 + .BYTE $7E ; 00018: iand + .BYTE $B3,$00,$02 ; 00019: putstatic #2 + .BYTE $12,$0E ; 00022: ldc #14 + .BYTE $B8,$00,$06 ; 00024: invokestatic #6 + .BYTE $57 ; 00027: pop + .BYTE $12,$13 ; 00028: ldc #19 + .BYTE $B8,$00,$06 ; 00030: invokestatic #6 + .BYTE $57 ; 00033: pop + .BYTE $12,$14 ; 00034: ldc #20 + .BYTE $B8,$00,$06 ; 00036: invokestatic #6 + .BYTE $57 ; 00039: pop + .BYTE $12,$0C ; 00040: ldc #12 + .BYTE $B8,$00,$06 ; 00042: invokestatic #6 + .BYTE $57 ; 00045: pop + .BYTE $11,$40,$00 ; 00046: sipush 16384 + .BYTE $10,$40 ; 00049: bipush 64 + .BYTE $B8,$00,$04 ; 00051: invokestatic #4 + .BYTE $57 ; 00054: pop + .BYTE $11,$20,$00 ; 00055: sipush 8192 + .BYTE $10,$44 ; 00058: bipush 68 + .BYTE $B8,$00,$04 ; 00060: invokestatic #4 + .BYTE $57 ; 00063: pop + .BYTE $04 ; 00064: iconst_1 + .BYTE $AC ; 00065: ireturn + .BYTE $10,$64 ; 00066: bipush 100 + .BYTE $10,$64 ; 00068: bipush 100 + .BYTE $B8,$00,$04 ; 00070: invokestatic #4 + .BYTE $3B ; 00073: istore_0 + .BYTE $1A ; 00074: iload_0 + .BYTE $12,$11 ; 00075: ldc #17 + .BYTE $7E ; 00077: iand + .BYTE $99,$FF,$B2 ; 00078: ifeq -78 (000000) + .BYTE $03 ; 00081: iconst_0 + .BYTE $AC ; 00082: ireturn +M13C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M13A0END: +;******* METHOD INDEX 14 - hrColor ******** + .BYTE $01,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$2D ; NAME #45 + .BYTE $00,$25 ; DESC #37 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,70 ; NAME #70 + .BYTE $00,$00,>(M14A0END-M14A0BGN),<(M14A0END-M14A0BGN) +M14A0BGN: +;* CODE: + .BYTE $00,$00 ; MAX STACK 0 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M14C0END-M14C0BGN),<(M14C0END-M14C0BGN) +M14C0BGN: + .INCLUDE "apple2/hrColor.s" +M14C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M14A0END: +;******* METHOD INDEX 15 - hrPlot ******** + .BYTE $01,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$2E ; NAME #46 + .BYTE $00,$2B ; DESC #43 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,70 ; NAME #70 + .BYTE $00,$00,>(M15A0END-M15A0BGN),<(M15A0END-M15A0BGN) +M15A0BGN: +;* CODE: + .BYTE $00,$00 ; MAX STACK 0 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M15C0END-M15C0BGN),<(M15C0END-M15C0BGN) +M15C0BGN: + .INCLUDE "apple2/hrPlot.s" +M15C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M15A0END: +;******* METHOD INDEX 16 - hrLine ******** + .BYTE $01,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$2F ; NAME #47 + .BYTE $00,$27 ; DESC #39 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,70 ; NAME #70 + .BYTE $00,$00,>(M16A0END-M16A0BGN),<(M16A0END-M16A0BGN) +M16A0BGN: +;* CODE: + .BYTE $00,$00 ; MAX STACK 0 + .BYTE $00,$04 ; MAX LOCALS 4 + .BYTE $00,$00,>(M16C0END-M16C0BGN),<(M16C0END-M16C0BGN) +M16C0BGN: + .INCLUDE "apple2/hrLine.s" +M16C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M16A0END: +;******* METHOD INDEX 17 - hrLineTo ******** + .BYTE $01,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$30 ; NAME #48 + .BYTE $00,$2B ; DESC #43 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,70 ; NAME #70 + .BYTE $00,$00,>(M17A0END-M17A0BGN),<(M17A0END-M17A0BGN) +M17A0BGN: +;* CODE: + .BYTE $00,$00 ; MAX STACK 0 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M17C0END-M17C0BGN),<(M17C0END-M17C0BGN) +M17C0BGN: + .INCLUDE "apple2/hrLineTo.s" +M17C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M17A0END: +;******* METHOD INDEX 18 - paddle ******** + .BYTE $01,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$31 ; NAME #49 + .BYTE $00,$32 ; DESC #50 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,70 ; NAME #70 + .BYTE $00,$00,>(M18A0END-M18A0BGN),<(M18A0END-M18A0BGN) +M18A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M18C0END-M18C0BGN),<(M18C0END-M18C0BGN) +M18C0BGN: + .INCLUDE "apple2/paddle.s" +M18C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M18A0END: +;******* METHOD INDEX 19 24 - button ******** + .BYTE $01,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$33 ; NAME #51 + .BYTE $00,$34 ; DESC #52 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,70 ; NAME #70 + .BYTE $00,$00,>(M19A0END-M19A0BGN),<(M19A0END-M19A0BGN) +M19A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M19C0END-M19C0BGN),<(M19C0END-M19C0BGN) +M19C0BGN: + .INCLUDE "apple2/button.s" +M19C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M19A0END: +;******* METHOD INDEX 20 - tone(II) ******** + .BYTE $00,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$35 ; NAME #53 + .BYTE $00,$2B ; DESC #43 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$1C ; NAME #28 + .BYTE $00,$00,>(M20A0END-M20A0BGN),<(M20A0END-M20A0BGN) +M20A0BGN: +;* CODE: + .BYTE $00,$03 ; MAX STACK 3 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M20C0END-M20C0BGN),<(M20C0END-M20C0BGN) +M20C0BGN: + .BYTE $1A ; 00000: iload_0 + .BYTE $1A ; 00001: iload_0 + .BYTE $04 ; 00002: iconst_1 + .BYTE $7A ; 00003: ishr + .BYTE $1B ; 00004: iload_1 + .BYTE $B8,$00,$15 ; 00005: invokestatic #21 + .BYTE $B1 ; 00008: return +M20C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M20A0END: +;******* METHOD INDEX 21- tone(III) ******** + .BYTE $01,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$35 ; NAME #53 + .BYTE $00,$28 ; DESC #40 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,70 ; NAME #70 + .BYTE $00,$00,>(M21A0END-M21A0BGN),<(M21A0END-M21A0BGN) +M21A0BGN: +;* CODE: + .BYTE $00,$00 ; MAX STACK 0 + .BYTE $00,$03 ; MAX LOCALS 3 + .BYTE $00,$00,>(M21C0END-M21C0BGN),<(M21C0END-M21C0BGN) +M21C0BGN: + .INCLUDE "apple2/tone.s" +M21C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M21A0END: +;******* METHOD INDEX 22 ******** + .BYTE $00,$08 ; ACCESS FLAGS 0x0008 + .BYTE $00,$36 ; NAME #54 + .BYTE $00,$1B ; DESC #27 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$1C ; NAME #28 + .BYTE $00,$00,>(M22A0END-M22A0BGN),<(M22A0END-M22A0BGN) +M22A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$00 ; MAX LOCALS 0 + .BYTE $00,$00,>(M22C0END-M22C0BGN),<(M22C0END-M22C0BGN) +M22C0BGN: + .BYTE $03 ; 00000: iconst_0 + .BYTE $B3,$00,$02 ; 00001: putstatic #2 + .BYTE $B1 ; 00004: return +M22C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M22A0END: +;* +;* GLOBAL ATTRIBUTES +;* + .BYTE $00,$00 ; ATTRIB COUNT 0 diff --git a/src/apple2/AppleStuff.java b/src/apple2/AppleStuff.java new file mode 100755 index 0000000..d34d031 --- /dev/null +++ b/src/apple2/AppleStuff.java @@ -0,0 +1,136 @@ +package apple2; + +public class AppleStuff { + private static int hrHandle = 0; + + public static void text() + { + if (hrHandle != 0) + { + // Free hires memory + vm02.call(hrHandle, 0x0C); + hrHandle = 0; + } + vm02.peekByte(0xC051); + vm02.peekByte(0xC054); + vm02.pokeByte(0x22, (byte)0); + vm02.call(0, 0xFC58); + } + public static boolean keyPressed() + { + return (vm02.peekByte(0x0280) > 0); + } + public static char getKey() + { + int key = vm02.call(0, 0x76) & 0x7F; // CONSOLE READ + return ((char)key); + } + public static void loResMix() + { + vm02.peekByte(0xC056); + vm02.peekByte(0xC053); + vm02.peekByte(0xC050); + vm02.call(0, 0xF836); + vm02.pokeByte(0x22, (byte)20); + vm02.call(0, 0xFC58); + } + public static void loRes() + { + vm02.peekByte(0xC056); + vm02.peekByte(0xC052); + vm02.peekByte(0xC050); + vm02.call(0, 0xF832); + } + public static void lrColor(int color) + { + //vm02.call(color, 0xF864); + } + public static void lrHLine(int xLeft, int xRight, int y, int color) + { + //vm02.call(color, 0xF864); + //vm02.pokeByte(0x2C, (byte)xRight); + //vm02.call((xLeft << 16) | y, 0xF819); + } + public static void lrHLine(int xLeft, int xRight, int y) + { + //vm02.pokeByte(0x2C, (byte)xRight); + //vm02.call((xLeft << 16) | y, 0xF819); + } + public static void lrVLine(int x, int yTop, int yBottom, int color) + { + //vm02.call(color, 0xF864); + //vm02.pokeByte(0x2D, (byte)yBottom); + //vm02.call((x << 16) | yTop, 0xF828); + } + public static void lrVLine(int x, int yTop, int yBottom) + { + //vm02.pokeByte(0x2D, (byte)yBottom); + //vm02.call((x << 16) | yTop, 0xF828); + } + public static void lrPlot(int x, int y, int color) + { + //vm02.call(color, 0xF864); + //vm02.call((x << 16) | y, 0xF800); + } + public static void lrPlot(int x, int y) + { + //vm02.call((x << 16) | y, 0xF800); + } + public static boolean hiRes() + { + int result; + + // Allocate hires page2 memory + do + { + result = vm02.call(0x014020, 0x0A); // HMEM_ALLOC_FIXED + if ((result & 0x01000000) == 0) // CARRY CLEAR == ALLOCED + { + hrHandle = result & 0xFFFF; + vm02.peekByte(0xC052); + vm02.peekByte(0xC057); + vm02.peekByte(0xC055); + vm02.peekByte(0xC050); + vm02.call(0x4000, 0x40); // SETDST + vm02.call(0x2000, 0x44); // MEMCLR + return true; + } + result = vm02.call(100, 0x64); // GC - MAX 100 ITERATIONS + } while ((result & 0x01000000) == 0); + return false; + } + public static void hrColor(int color) + { + //vm02.call(color << 8, 0xF6F0); // HCOLOR + } + public static void hrPlot(int x, int y) + { + //vm02.call((x << 8) | y, 0xF457); // HPLOT + } + public static void hrLine(int x1, int y1, int x2, int y2) + { + //vm02.call((x1 << 8) | y1, 0xF411); // HPOSN + //vm02.call(x2 | (y2 << 16), 0xF53A); // HLINE + } + public static void hrLineTo(int x, int y) + { + //vm02.call(x | (y << 16), 0xF53A); // HLINE + } + public static int paddle(int num) + { + //return ((vm02.call(num << 8, 0xFB1E) >> 16) & 0xFF); + return 0; + } + public static boolean button(int num) + { + //return (vm02.peekByte(0xC061+num) >= 128); + return false; + } + public static void tone(int pitch, int duration) + { + tone(pitch, pitch >> 1, duration); + } + public static void tone(int pitch, int timbre, int duration) + { + } +} \ No newline at end of file diff --git a/src/apple2/Ethernet.java b/src/apple2/Ethernet.java new file mode 100755 index 0000000..96189c3 --- /dev/null +++ b/src/apple2/Ethernet.java @@ -0,0 +1,204 @@ +package apple2; +/* + * This class interfaces to the ethernet device. + */ +public class Ethernet extends java.net.NetworkDevice +{ + static private int ethSlot, ethOutputBuff, ethInputBuff, ethRecvPacket, ethSendPacket, ethHeaderLen, ethPacketDone, ethCtrl, ethWrite, ethRead; + static private byte[] MAC = {(byte)0x00,(byte)0x0a,(byte)0x99,(byte)0x1e,(byte)0x02,(byte)0x00}; + static final int MIN_DATA_SIZE = 46; + static final int MAX_DATA_SIZE = 1500; + + private static void copyBytes(byte[] src, int srcOfst, byte[] dst, int dstOfst, int count) + { + while (count-- != 0) + dst[dstOfst++] = src[srcOfst++]; + } + public static boolean enable() + { + // + // Search for ethernet card. + // + for (int slot = 1; slot < 8; slot++) + { + // + // ID device + // + if (((vm02.call((1 << 19), 0x90 + (slot << 1))) & 0x010000FF) == 0xE1) // CARRY clear == valid device IOCTL, 0xE1 == ethernet card ID + { + ethCtrl = 0x90 + (slot << 1); + ethWrite = 0x80 + (slot << 1); + ethRead = 0x70 + (slot << 1); + ethSlot = slot << 16; + ethInputBuff = ethSlot | ( 7 << 19); + ethOutputBuff = ethSlot | ( 9 << 19); + ethRecvPacket = ethSlot | (16 << 19); + ethSendPacket = ethSlot | (17 << 19); + ethPacketDone = ethSlot | (18 << 19); + ethHeaderLen = ethSlot | 14; + for (int oct = 0; oct < 3; oct++) + vm02.call(ethSlot + | ((19 + oct) << 19) + | ( MAC[oct*2] & 0x00FF) + | ((MAC[oct*2 + 1] << 8) & 0xFF00), ethCtrl); // set MAC address + if ((vm02.call(ethSlot | (3 << 19), ethCtrl) & 0x01000000) == 0) // open port + return true; + } + } + return false; + } + public static void disable() + { + vm02.call(ethSlot | 4, ethCtrl); // close port + } + public static byte[] localAddr() + { + return MAC; + } + public static byte[] broadcastAddr() + { + byte[] addr = new byte[6]; + addr[0] = (byte)0xFF; + addr[1] = (byte)0xFF; + addr[2] = (byte)0xFF; + addr[3] = (byte)0xFF; + addr[4] = (byte)0xFF; + addr[5] = (byte)0xFF; + return addr; + } + public static byte[] newAddr() + { + return new byte[6]; + } + public static boolean isEqualAddr(byte[] addr1, byte[] addr2) + { + return ((addr1[5] == addr2[5]) + && (addr1[4] == addr2[4]) + && (addr1[3] == addr2[3]) + && (addr1[2] == addr2[2]) + && (addr1[1] == addr2[1]) + && (addr1[0] == addr2[0])); + } + public static void copyAddr(byte[] src, byte[] dst) + { + copyBytes(src, 0, dst, 0, 6); + } + public static byte[] newHeader() + { + return new byte[14]; + } + public static void setHeaderSrcAddr(byte[] header, byte[] addr) + { + copyBytes(addr, 0, header, 6, 6); + } + public static void setHeaderDstAddr(byte[] header, byte[] addr) + { + copyBytes(addr, 0, header, 0, 6); + } + public static void copyHeaderSrcAddr(byte[] header, byte[] addr) + { + copyBytes(header, 6, addr, 0, 6); + } + public static void copyHeaderDstAddr(byte[] header, byte[] addr) + { + copyBytes(header, 0, addr, 0, 6); + } + public static byte[] getHeaderSrcAddr(byte[] header) + { + byte[] addr = new byte[6]; + copyBytes(header, 6, addr, 0, 6); + return addr; + } + public static byte[] getHeaderDstAddr(byte[] header) + { + byte[] addr = new byte[6]; + copyBytes(header, 0, addr, 0, 6); + return addr; + } + public static int getHeaderType(byte[] header) + { + if (header == null || header.length < 14) + { + System.out.println("Bad header in getHeaderType!"); + return 0; + } + return ((header[12] << 8) & 0xFF00) | (header[13] & 0x00FF); + } + public static void setHeaderType(byte[] header, int type) + { + header[12] = (byte)(type >> 8); + header[13] = (byte)type; + } + public static boolean sendHeader(byte[] header, int dataSize) + { + boolean success; + int hmem = vm02.refAsBits((Object)header) & 0xFFFF; + vm02.call(ethOutputBuff | (vm02.call(hmem, 0x0E) & 0xFFFF) + 2, ethCtrl); // HMEM_LOCK header IOCTL_OUTBUFF + success = (vm02.call(ethSendPacket | dataSize + 14, ethCtrl) & 0x01000000) == 0; + if (success) // prepare to write packet of length len + vm02.call(ethHeaderLen, ethWrite); // write 14 byte ethernet header + vm02.call(hmem, 0x10); // HMEM_UNLOCK header + return success; + } + public static boolean sendHeader(byte[] dst, int type, int dataSize) + { + byte[] header = new byte[14]; + copyBytes(dst, 0, header, 0, 6); + copyBytes(MAC, 0, header, 6, 6); + header[12] = (byte)(type >> 8); + header[13] = (byte)type; + return sendHeader(header, dataSize); + } + public static void sendData(byte[] data, int offset, int size) + { + int hmem = vm02.refAsBits((Object)data) & 0xFFFF; + vm02.call(ethOutputBuff | (vm02.call(hmem, 0x0E) & 0xFFFF) + 2 + offset, ethCtrl); // HMEM_LOCK data IOCTL_OUTBUFF + vm02.call(ethSlot | size, ethWrite); // write data + vm02.call(hmem, 0x10); // HMEM_UNLOCK data + } + public static void sendData(byte[] data) + { + int hmem = vm02.refAsBits((Object)data) & 0xFFFF; + vm02.call(ethOutputBuff | (vm02.call(hmem, 0x0E) & 0xFFFF) + 2, ethCtrl); // HMEM_LOCK data IOCTL_OUTBUFF + vm02.call(ethSlot | data.length, ethWrite); // write data + vm02.call(hmem, 0x10); // HMEM_UNLOCK data + } + public static int recvHeader(byte[] header) + { + int len; + + if (header == null || header.length < 14) + { + System.out.println("Bad header in recvHeader!"); + return 0; + } + int hmem = vm02.refAsBits((Object)header) & 0xFFFF; + vm02.call(ethInputBuff | (vm02.call(hmem, 0x0E) & 0xFFFF) + 2, ethCtrl); // HMEM_LOCK header IOCTL_INBUFF + if ((len = vm02.call(ethRecvPacket, ethCtrl) & 0xFFFF) >= 14) // ETHRCTRL_RECVPKT + { + vm02.call(ethHeaderLen, ethRead); // read 14 byte ethernet header + vm02.call(hmem, 0x10); // HMEM_UNLOCK header + return len - 14; + } + vm02.call(hmem, 0x10); // HMEM_UNLOCK header + return 0; + } + public static void recvData(byte[] data, int offset, int size) + { + int hmem = vm02.refAsBits((Object)data) & 0xFFFF; + vm02.call(ethInputBuff | (vm02.call(hmem, 0x0E) & 0xFFFF) + 2 + offset, ethCtrl); // HMEM_LOCK data IOCTL_OUTBUFF + vm02.call(ethSlot | size, ethRead); // write data + vm02.call(hmem, 0x10); // HMEM_UNLOCK data + } + public static void recvData(byte[] data) + { + int hmem = vm02.refAsBits((Object)data) & 0xFFFF; + vm02.call(ethInputBuff | (vm02.call(hmem, 0x0E) & 0xFFFF) + 2, ethCtrl); // HMEM_LOCK data IOCTL_OUTBUFF + vm02.call(ethSlot | data.length, ethRead); // write data + vm02.call(hmem, 0x10); // HMEM_UNLOCK data + } + public static void xferComplete() + { + vm02.call(ethPacketDone, ethCtrl); // ETHRCRL_DONEPKT + } +} \ No newline at end of file diff --git a/src/apple2/InputConsole.java b/src/apple2/InputConsole.java new file mode 100755 index 0000000..b55d666 --- /dev/null +++ b/src/apple2/InputConsole.java @@ -0,0 +1,50 @@ +package apple2; + +public class InputConsole extends java.io.InputStream { + public int available() + { + return vm02.call((5 << 19), 0x96) & 0xFF; // INPUT AVAIL + } + public void close(){} + public void mark(int readLimit){} + public boolean markSupported(){return false;} + public int read() + { + int key; + vm02.pokeByte(0x32, (byte)0x7F); // FLASH + vm02.call(0x20, 0x86); // PRINT PROMPT + vm02.pokeByte(0x32, (byte)0xFF); // NORMAL + vm02.call(0x08, 0x86); // BS + key = vm02.call(0, 0x76) & 0x7F; // KEYBD_READ + if (key < 0x20 || key == 0x7F) + { + vm02.call(0x20, 0x86); // SPACE + vm02.call(0x08, 0x86); // BS + } + else + vm02.call(key, 0x86); + return (key); + } + public int read(byte b[]) + { + return read(b, 0, b.length); + } + public int read(byte b[], int off, int len) + { + int i, l = off + len; + + if (b == null) + skip(len); + else + for (i = off; i < l; i++) + b[i] = (byte)read(); + return len; + } + public void reset(){}; + public long skip(long n) + { + int s = (int)n; + while ((s-- != 0) && (read() > 0)); + return n; + } +} \ No newline at end of file diff --git a/src/apple2/InputSSC.java b/src/apple2/InputSSC.java new file mode 100755 index 0000000..a1a2af0 --- /dev/null +++ b/src/apple2/InputSSC.java @@ -0,0 +1,32 @@ +package apple2; + +public class InputSSC extends java.io.InputStream +{ + private int numSlot, sscSlot, sscRead, sscCtrl; + private byte inBuff[]; + + public InputSSC(int slot) + { + int bufferptr; + inBuff = new byte[256]; + sscRead = 0x70 + (slot << 1); + sscCtrl = 0x90 + (slot << 1); + numSlot = slot; + sscSlot = slot << 16; + vm02.call(sscSlot | (7 << 19) | (vm02.call(vm02.refAsBits((Object)inBuff), 0x0E) & 0xFFFF) + 2, sscCtrl); // HMEM_LOCK IOCTL_INBUFF + } + + public int available() + { + return vm02.call(sscSlot | (5 << 19), sscCtrl) & 0xFF; + } + public int read() + { + return vm02.call(sscSlot, sscRead) & 0xFF; + } + public void close() + { + vm02.call(sscSlot | (7 << 19), sscCtrl); // IOCTL_INBUFF + inBuff = null; + } +} \ No newline at end of file diff --git a/src/apple2/Mouse.java b/src/apple2/Mouse.java new file mode 100755 index 0000000..b49982a --- /dev/null +++ b/src/apple2/Mouse.java @@ -0,0 +1,61 @@ +package apple2; +/* + * This class interfaces directly with the mouse device driver. + */ +public class Mouse +{ + static private int slot, mouseSlot, mouseCtrl, ctrlRead, addrXPos, addrYPos; + static public int xPos, yPos, status; + + public static boolean enable() + { + // + // Search for mouse card and disable VBL interrupts + // + for (slot = 1; slot < 8; slot++) + { + int mouse = vm02.call((1 << 19), 0x90 + (slot << 1)); // ID device + if ((mouse & 0x010000FF) == 0x20) // CARRY clear == valid device IOCTL, 0x20 == mouse card ID + { + mouseCtrl = 0x90 + (slot << 1); + mouseSlot = slot << 16; + ctrlRead = mouseSlot | 0x801400; + addrXPos = vm02.peekWord(0x0370 + (slot << 1)) + 2; + addrYPos = addrXPos + 2; + return (vm02.call(mouseSlot | (3 << 19), mouseCtrl) & 0x01000000) == 0; // open port + } + } + slot = 0; + return false; + } + public static void disable() + { + vm02.call(mouseSlot | (4<<19), mouseCtrl); // close port + } + public static void disableIRQ() + { + int vblSlot, vbl; + // + // Search for mouse card and disable/remove interrupts + // + for (vblSlot = 1; vblSlot < 8; vblSlot++) + { + vbl = vm02.call((1 << 19), 0x90 + (vblSlot << 1)); // ID device + if ((vbl & 0x010000FF) == 0x20) // CARRY clear == valid device IOCTL, 0x20 == mouse card ID + { + vm02.call((vblSlot << 16) | (17 << 19), 0x90 + (vblSlot << 1)); // MOUSECTL_UNVBL + break; + } + } + } + public static int slotMask() + { + return (1 << slot); + } + public static void update() + { + status = vm02.call(ctrlRead, mouseCtrl) & 0xFF; // CALL_FW ReadMouse + xPos = vm02.peekWord(addrXPos); + yPos = vm02.peekWord(addrYPos); + } +} \ No newline at end of file diff --git a/src/apple2/OutputConsole.java b/src/apple2/OutputConsole.java new file mode 100755 index 0000000..b06b258 --- /dev/null +++ b/src/apple2/OutputConsole.java @@ -0,0 +1,45 @@ +package apple2; + +public class OutputConsole extends java.io.OutputStream { + public void write(byte b) + { + int h; + switch (b) + { + case '\n': + vm02.call('\r', 0X86); + break; + case 9: // TAB + h = vm02.peekByte(0x0024); + do { + vm02.call(0x20, 0x86); + } while (((++h) & 0x07) != 0); + break; + default: + vm02.call(b, 0x86); + } + } + public void write(byte b[], int off, int len) + { + int i, h, c, l = off + len; + for (i = off; i < l; i++) + { + c = b[i]; + switch (c) + { + case '\n': + vm02.call('\r', 0x86); + break; + case 9: // TAB + h = vm02.peekByte(0x0024); + do { + vm02.call(0x20, 0x86); + } while (((++h) & 0x07) != 0); + break; + default: + vm02.call(c, 0x86); + } + } + } + +} \ No newline at end of file diff --git a/src/apple2/OutputSSC.java b/src/apple2/OutputSSC.java new file mode 100755 index 0000000..cca6656 --- /dev/null +++ b/src/apple2/OutputSSC.java @@ -0,0 +1,17 @@ +package apple2; + +public class OutputSSC extends java.io.OutputStream +{ + private int sscSlot, sscWrite; + + public OutputSSC(int slot) + { + sscWrite = 0x80 + (slot << 1); + sscSlot = slot << 16; + } + + public void write(byte b) + { + vm02.call(sscSlot | b , sscWrite); + } +} \ No newline at end of file diff --git a/src/apple2/PrintConsole.java b/src/apple2/PrintConsole.java new file mode 100755 index 0000000..d11459c --- /dev/null +++ b/src/apple2/PrintConsole.java @@ -0,0 +1,19 @@ +package apple2; + +public class PrintConsole extends java.io.PrintStream { + + public PrintConsole() + { + super(new OutputConsole()); + vm02.call(20 << 19, 0x96); // CONCTL_TEXT80 on slot #3 + } + + public void print(String s) + { + vm02.call(vm02.refAsBits(s), 0x50); + } + public void println(String s) + { + vm02.call(vm02.refAsBits(s), 0x52); + } +} \ No newline at end of file diff --git a/src/apple2/ProDOS.java b/src/apple2/ProDOS.java new file mode 100755 index 0000000..718584b --- /dev/null +++ b/src/apple2/ProDOS.java @@ -0,0 +1,324 @@ +package apple2; + +public class ProDOS +{ + private static String makeString(int addr) + { + int hndlStr = vm02.call(addr, 0x46); // HSTRPL_ADD + return (String)vm02.bitsAsRef((hndlStr & 0xFFFF) | 0x00830000 | ((hndlStr & 0x00FF0000) << 8)); // Create String reference + } + /* + * Housekeeping calls + */ + public static int create(String pathname, int access, int file_type, int aux_type, int storage_type) + { + int create_time = getTime(); + byte params[] = new byte[12]; + int hmem = vm02.refAsBits((Object)pathname) & 0xFFFF; + int stringptr = vm02.call(hmem, 0x0E); // HMEM_LOCK + params[0] = 7; // param_count + params[1] = (byte)stringptr; // pathname + params[2] = (byte)(stringptr >> 8); // pathname + params[3] = (byte)access; + params[4] = (byte)file_type; + params[5] = (byte)aux_type; + params[6] = (byte)(aux_type >> 8); + params[7] = (byte)storage_type; + params[8] = (byte)create_time; + params[9] = (byte)(create_time >> 8); + params[10] = (byte)(create_time >> 16); + params[11] = (byte)(create_time >> 24); + int result = vm02.call(0xC00000 | (vm02.refAsBits((Object)params) & 0xFFFF), 0x54) & 0xFF; // PRODOS + vm02.call(hmem, 0x10); // HMEM_UNLOCK + return -result; + } + public static int destroy(String pathname) + { + byte params[] = new byte[3]; + int hmem = vm02.refAsBits((Object)pathname) & 0xFFFF; + int stringptr = vm02.call(hmem, 0x0E); // HMEM_LOCK + params[0] = 1; // param_count + params[1] = (byte)stringptr; // pathname + params[2] = (byte)(stringptr >> 8); // pathname + int result = vm02.call(0xC10000 | (vm02.refAsBits((Object)params) & 0xFFFF), 0x54) & 0xFF; // PRODOS + vm02.call(vm02.refAsBits((Object)pathname) & 0xFFFF, 0x10); // HMEM_UNLOCK + return -result; + } + public static int rename(String pathname, String new_pathname) + { + byte params[] = new byte[5]; + int hmemOld = vm02.refAsBits((Object)pathname) & 0xFFFF; + int hmemNew = vm02.refAsBits((Object)new_pathname) & 0xFFFF; + int string1ptr = vm02.call(hmemOld, 0x0E); // HMEM_LOCK + int string2ptr = vm02.call(hmemNew, 0x0E); // HMEM_LOCK + params[0] = 2; // param_count + params[1] = (byte)string1ptr; // pathname + params[2] = (byte)(string1ptr >> 8); // pathname + params[3] = (byte)string2ptr; // new_pathname + params[4] = (byte)(string2ptr >> 8); // new_pathname + int result = vm02.call(0xC20000 | (vm02.refAsBits((Object)params) & 0xFFFF), 0x54) & 0xFF; // PRODOS + vm02.call(hmemOld, 0x10); // HMEM_UNLOCK + vm02.call(hmemNew, 0x10); // HMEM_UNLOCK + return -result; + } + public static int setFileInfo(String pathname, byte[] params) + { + if (params.length < 14) + return -256; + int hmem = vm02.refAsBits((Object)pathname) & 0xFFFF; + int stringptr = vm02.call(hmem, 0x0E); // HMEM_LOCK + params[0] = 7; + params[1] = (byte)stringptr; // pathname + params[2] = (byte)(stringptr >> 8); // pathname + int result = vm02.call(0xC30000 | (vm02.refAsBits((Object)params) & 0xFFFF), 0x54) & 0xFF; // PRODOS + vm02.call(hmem, 0x10); // HMEM_UNLOCK + return -result; + } + public static byte[] getFileInfo(String pathname) + { + byte params[] = new byte[18]; + int hmem = vm02.refAsBits((Object)pathname) & 0xFFFF; + int stringptr = vm02.call(hmem, 0x0E); // HMEM_LOCK + params[0] = 10; + params[1] = (byte)stringptr; // pathname + params[2] = (byte)(stringptr >> 8); // pathname + params[0] = (byte)vm02.call(0xC40000 | (vm02.refAsBits((Object)params) & 0xFFFF), 0x54); // PRODOS + vm02.call(hmem, 0x10); // HMEM_UNLOCK + return params; + } + public static String[] online() + { + String nameVols[] = new String[14]; + byte params[] = new byte[4]; + byte buffer[] = new byte[256]; + int hmem = vm02.refAsBits((Object)buffer) & 0xFFFF; + int bufferptr = (vm02.call(hmem, 0x0E) & 0xFFFF) + 2; // HMEM_LOCK + params[0] = 2; // param_count + params[1] = 0; // unit_num + params[2] = (byte)bufferptr; // data_buffer + params[3] = (byte)(bufferptr >> 8); // data_buffer + vm02.call(0xC50000 | (vm02.refAsBits((Object)params) & 0xFFFF), 0x54); // PRODOS + int numVols = 0; + for (int i = 0; i < 256; i += 16) + { + // dev = buffer[i] >> 4; + buffer[i] &= 0x0F; + if (buffer[i] != 0) + nameVols[numVols++] = makeString(bufferptr+i); + } + vm02.call(hmem, 0x10); // HMEM_UNLOCK + String onlineVols[] = new String[numVols]; + while (--numVols >= 0) + onlineVols[numVols] = nameVols[numVols]; + return onlineVols; + } + public static int setPrefix(String pathname) + { + byte params[] = new byte[3]; + int hmem = vm02.refAsBits((Object)pathname) & 0xFFFF; + int stringptr = vm02.call(hmem, 0x0E); // HMEM_LOCK + params[0] = 1; // param_count + params[1] = (byte)stringptr; // pathname + params[2] = (byte)(stringptr >> 8); // pathname + int result = vm02.call(0xC60000 | (vm02.refAsBits((Object)params) & 0xFFFF), 0x54) & 0xFF; // PRODOS + vm02.call(hmem, 0x10); // HMEM_UNLOCK + return -result; + } + public static String getPrefix() + { + String pathname = null; + byte params[] = new byte[3]; + byte buffer[] = new byte[65]; + int hmem = vm02.refAsBits((Object)buffer) & 0xFFFF; + int bufferptr = (vm02.call(hmem, 0x0E) & 0xFFFF) + 2; // HMEM_LOCK + params[0] = 1; // param_count + params[1] = (byte)bufferptr; // pathname + params[2] = (byte)(bufferptr >> 8); // pathname + int result = vm02.call(0xC70000 | (vm02.refAsBits((Object)params) & 0xFFFF), 0x54) & 0xFF; // PRODOS + if (result == 0) + pathname = makeString(bufferptr); + vm02.call(hmem, 0x10); // HMEM_UNLOCK + return pathname; + } + public static int allocIOBuffer() + { + int page, result; + + do + { + for (page = 0x40; page < 0xBB; page++) + { + result = vm02.call(0x010004 | (page << 8), 0x0A); // HMEM_ALLOC_FIXED + if ((result & 0x01000000) == 0) + return result & 0xFFFF; + } + result = vm02.call(0x00FF0100, 0x64); // GC - MAX 256 ITERATIONS + } while ((result & 0x01000000) == 0); + return 0; + } + public static void freeIOBuffer(int io_buffer) + { + if (io_buffer != 0) + vm02.call(io_buffer, 0x0C); // HMEM_FREE + } + /* + * Filing calls + */ + public static int open(String pathname, int io_buffer) + { + byte params[] = new byte[6]; + int hmem = vm02.refAsBits((Object)pathname) & 0xFFFF; + int stringptr = vm02.call(hmem, 0x0E); // HMEM_LOCK + int bufferptr = ((vm02.call(io_buffer, 0x06) & 0xFFFF) | 0x0F) + 1; // HMEM_PTR + params[0] = 3; // param_count + params[1] = (byte)stringptr; // pathname + params[2] = (byte)(stringptr >> 8); // pathname + params[3] = (byte)bufferptr; // io_buffer + params[4] = (byte)(bufferptr >> 8); // io_buffer + int result = vm02.call(0xC80000 | (vm02.refAsBits((Object)params) & 0xFFFF), 0x54) & 0xFF; // PRODOS + vm02.call(hmem, 0x10); // HMEM_UNLOCK + if (result == 0) + for (int i = 5; i >= 0; i--) + if (vm02.peekByte(0x036A + i) == 0) + { + vm02.pokeByte(0x036A + i, params[5]); + break; + } + return (result != 0) ? -result : ((int)params[5] & 0xFF); + } +// public static int newline(){} + public static int read(int ref_num, byte data_buffer[]) + { + return readwrite(0xCA0000, ref_num, data_buffer, 0, data_buffer.length); + } + public static int read(int ref_num, byte data_buffer[], int offset, int len) + { + return readwrite(0xCA0000, ref_num, data_buffer, offset, len); + } + public static int write(int ref_num, byte data_buffer[]) + { + return readwrite(0xCB0000, ref_num, data_buffer, 0, data_buffer.length); + } + public static int write(int ref_num, byte data_buffer[], int offset, int len) + { + return readwrite(0xCB0000, ref_num, data_buffer, offset, len); + } + public static int readwrite(int cmd, int ref_num, byte data_buffer[], int offset, int len) + { + byte params[] = new byte[8]; + if ((offset + len) > data_buffer.length) + return -256; // buffer overflow + int hmem = vm02.refAsBits((Object)data_buffer) & 0xFFFF; + int bufferptr = (vm02.call(hmem, 0x0E) & 0xFFFF) + 2 + offset; // HMEM_LOCK + params[0] = 4; // param_count + params[1] = (byte)ref_num; // ref_num + params[2] = (byte)bufferptr; // pathname + params[3] = (byte)(bufferptr >> 8); // pathname + params[4] = (byte)len; // io_buffer + params[5] = (byte)(len >> 8); // io_buffer + int result = vm02.call(cmd | (vm02.refAsBits((Object)params) & 0xFFFF), 0x54) & 0xFF; // PRODOS + vm02.call(hmem, 0x10); // HMEM_UNLOCK + return (result != 0) ? -result : (((int)params[6] & 0x00FF) | (((int)params[7] << 8) & 0xFF00)); + } + public static int close(int ref_num) + { + byte params[] = new byte[2]; + params[0] = 1; // param_count + params[1] = (byte)ref_num; // ref_num + int result = vm02.call(0xCC0000 | (vm02.refAsBits((Object)params) & 0xFFFF), 0x54) & 0xFF; // PRODOS + for (int i = 5; i >= 0; i--) + if (vm02.peekByte(0x036A + i) == ref_num) + { + vm02.pokeByte(0x036A + i, (byte)0); + break; + } + return -result; + } + public static int flush(int ref_num) + { + byte params[] = new byte[2]; + params[0] = 1; // param_count + params[1] = (byte)ref_num; // ref_num + int result = vm02.call(0xCD0000 | (vm02.refAsBits((Object)params) & 0xFFFF), 0x54) & 0xFF; // PRODOS + return -result; + } + public static int setMark(int ref_num, int position) + { + return setPos(0xCE0000, ref_num, position); + } + public static int setEOF(int ref_num, int eof) + { + return setPos(0xD00000, ref_num, eof); + } + public static int setPos(int cmd, int ref_num, int pos) + { + byte params[] = new byte[5]; + params[0] = 2; // param_count + params[1] = (byte)ref_num; // ref_num + params[2] = (byte)pos; + params[3] = (byte)(pos >> 8); + params[4] = (byte)(pos >> 16); + int result = vm02.call(cmd | (vm02.refAsBits((Object)params) & 0xFFFF), 0x54) & 0xFF; // PRODOS + return -result; + } + public static int getMark(int ref_num) + { + return getPos(0xCF0000, ref_num); + } + public static int getEOF(int ref_num) + { + return getPos(0xD10000, ref_num); + } + public static int getPos(int cmd, int ref_num) + { + byte params[] = new byte[5]; + params[0] = 2; // param_count + params[1] = (byte)ref_num; // ref_num + int result = vm02.call(cmd | (vm02.refAsBits((Object)params) & 0xFFFF), 0x54) & 0xFF; // PRODOS + int pos = (int)params[2] & 0xFF; + pos |= ((int)params[3] & 0xFF) << 8; + pos |= ((int)params[4] & 0xFF) << 16; + return (result != 0) ? -result : pos; + } + /* + * System calls + */ + public static int readBlock(int unit_num, int block_num, byte data_buffer[]) + { + return readwriteBlock(0x800000, unit_num, block_num, data_buffer, 0); + } + public static int readBlock(int unit_num, int block_num, byte data_buffer[], int offset) + { + return readwriteBlock(0x800000, unit_num, block_num, data_buffer, offset); + } + public static int writeBlock(int unit_num, int block_num, byte data_buffer[]) + { + return readwriteBlock(0x810000, unit_num, block_num, data_buffer, 0); + } + public static int writeBlock(int unit_num, int block_num, byte data_buffer[], int offset) + { + return readwriteBlock(0x810000, unit_num, block_num, data_buffer, offset); + } + public static int readwriteBlock(int cmd, int unit_num, int block_num, byte data_buffer[], int offset) + { + byte params[] = new byte[6]; + if ((offset + 512) < data_buffer.length) + return -256; // buffer overflow + int hmem = vm02.refAsBits((Object)data_buffer) & 0xFFFF; + int bufferptr = vm02.call(hmem, 0x0E) + 2 + offset; // HMEM_LOCK + params[0] = 3; // param_count + params[1] = (byte)unit_num; // unit_num + params[2] = (byte)bufferptr; // data_buffer + params[3] = (byte)(bufferptr >> 8); // data_buffer + params[4] = (byte)block_num; + params[5] = (byte)(block_num >> 8); // io_buffer + int result = vm02.call(cmd | (vm02.refAsBits((Object)params) & 0xFFFF), 0x54) & 0xFF; // PRODOS + vm02.call(hmem, 0x10); // HMEM_UNLOCK + return -result; + } + public static int getTime() + { + vm02.call(0x820000, 0x54); // PRODOS + return vm02.peekWord(0xBF90) | (vm02.peekWord(0xBF92) << 16); + } +} diff --git a/src/apple2/SystemException.java b/src/apple2/SystemException.java new file mode 100755 index 0000000..0ba3e5d --- /dev/null +++ b/src/apple2/SystemException.java @@ -0,0 +1,35 @@ +package apple2; + +public class SystemException +{ + private static void throwSystemException(int exception) throws Exception + { + switch (exception) + { + case 1: throw new Error(); + case 2: throw new ThreadDeath(); + case 3: throw new InternalError(); + case 4: throw new OutOfMemoryError(); + case 5: throw new StackOverflowError(); + case 6: throw new NoClassDefFoundError(); + case 7: throw new ClassFormatError(); + case 8: throw new IncompatibleClassChangeError(); + case 9: throw new NoSuchMethodError(); + case 10: throw new NoSuchFieldError(); + case 11: throw new Exception(); + case 12: throw new IllegalMonitorStateException(); + case 13: throw new IllegalThreadStateException(); + case 14: throw new InterruptedException(); + case 15: throw new ClassNotFoundException(); + case 16: throw new RuntimeException(); + case 17: throw new NullPointerException(); + case 18: throw new IndexOutOfBoundsException(); + case 19: throw new ArrayIndexOutOfBoundsException(); + case 20: throw new StringIndexOutOfBoundsException(); + case 21: throw new NegativeArraySizeException(); + case 22: throw new ArrayStoreException(); + case 23: throw new ArithmeticException(); + case 24: throw new ClassCastException(); + } + } +} \ No newline at end of file diff --git a/src/apple2/button.s b/src/apple2/button.s new file mode 100755 index 0000000..04160b2 --- /dev/null +++ b/src/apple2/button.s @@ -0,0 +1,26 @@ +; +; READ BUTTON +; + PLA + STA $A0 + PLA + STA $A1 + PLA + AND #$03 + TAX + PLA + PLA + PLA + LDA $C061,X ; READ BUTTONS + ASL + LDA #$00 + PHA + PHA + PHA + ROL + PHA + LDA $A1 + PHA + LDA $A0 + PHA + RTS diff --git a/src/apple2/conio.java b/src/apple2/conio.java new file mode 100755 index 0000000..06b4865 --- /dev/null +++ b/src/apple2/conio.java @@ -0,0 +1,134 @@ +package apple2; + +public class conio { + public static void print(char c) + { + vm02.call(c, 0x86); + + } + private static void putdigit(int i) + { + if (i > 9) + putdigit(i / 10); + print((char)('0' + i % 10)); + } + public static void print(int i) + { + if (i < 0) + { + print('-'); + i = -i; + } + putdigit(i); + } + public static void println(int i) + { + print(i); + print('\r'); + } + public static void print(String s) + { + vm02.call(vm02.refAsBits(s), 0x50); + } + public static void println(String s) + { + vm02.call(vm02.refAsBits(s), 0x52); + } + public static void print(byte text[], int offset, int len) + { + while (--len >= 0) + vm02.call(text[offset++], 0x86); + } + public static void clreol() + { + vm02.call(0, 0xFC9C); // CLREOL + } + public static void fill(char c, int len) + { + while (--len >= 0) + vm02.call(c, 0x86); + } + public static void text80() + { + vm02.call((20 << 19), 0x96); // CONCTL_TEXT80 on slot #3 + } + public static void home() + { + vm02.call(0, 0xFC58); + } + public static void gotoXY(int x, int y) + { + vm02.pokeByte(0x24, (byte)x); + vm02.pokeByte(0x25, (byte)y); + vm02.call(y, 0xFBC1); + } + public static void window(int left, int right, int top, int bottom) + { + vm02.pokeByte(0x20, (byte)left); + vm02.pokeByte(0x21, (byte)(right - left)); + vm02.pokeByte(0x22, (byte)top); + vm02.pokeByte(0x23, (byte)bottom); + } + public static void normal() + { + vm02.pokeByte(0x32, (byte)0xFF); + } + public static void inverse() + { + vm02.pokeByte(0x32, (byte)0x3F); + } + public static void flash() + { + vm02.pokeByte(0x32, (byte)0x7F); + } + public static boolean keyPressed() + { + return ((vm02.call((5 << 19), 0x96) & 0xFF) > 0); + } + public static char getKey() + { + int key = vm02.call(0, 0x76) & 0x7F; // KEYBD_READ + return ((char)key); + } + public static int getLine(byte line[]) + { + int key,i = 0; + + while (i < line.length) + { + vm02.pokeByte(0x32, (byte)0x7F); // FLASH + vm02.call(0x20, 0x86); // PRINT PROMPT + vm02.pokeByte(0x32, (byte)0xFF); // NORMAL + vm02.call(0x08, 0x86); // BS + key = vm02.call(0, 0x76) & 0x7F; // KEYBD_READ + if (key < 0x20 || key == 0x7F) + { + vm02.call(0x20, 0x86); // SPACE - ERASE PROMPT + vm02.call(0x08, 0x86); // BS + } + else + vm02.call(key, 0x86); + switch (key) + { + case -1: + case '\r': + case '\n': + return i; + case 0x08: // BS + case 0x7F: // DEL + if (i > 0) + { + i--; + vm02.call(0x08, 0x86); // BS + } + else + vm02.call(0x07, 0x86); // BELL + break; + default: + line[i++] = (byte)key; + } + } + return i; + } + +} \ No newline at end of file diff --git a/src/apple2/hrColor.s b/src/apple2/hrColor.s new file mode 100755 index 0000000..2f7a63b --- /dev/null +++ b/src/apple2/hrColor.s @@ -0,0 +1,54 @@ +; +; HIRES COLOR +; + LDY #$07 ; SAVE VM02, RESTORE HGR +: LDA $E0,Y + STA $40F8,Y + LDA $4078,Y + STA $E0,Y + DEY + BPL :- + LDA $1C + STA $41FE + LDA $417E + STA $1C + LDA $1D + STA $41FF + LDA $417F + STA $1D + BIT $C081 + PLA ; SAVE RETURN ADDRESS + STA $A0 + PLA + STA $A1 + PLA + TAX + PLA + PLA + PLA + TXA + JSR $F6F0 ; SET COLOR + LDA #$40 ; SET PAGE2 + STA $E6 + LDA $A1 ; RESTORE RETURN ADDRESS + PHA + LDA $A0 + PHA + BIT $C083 + BIT $C083 + LDY #$07 ; SAVE HGR, RESTORE VM02 +: LDA $E0,Y + STA $4078,Y + LDA $40F8,Y + STA $E0,Y + DEY + BPL :- + LDA $1C + STA $417E + LDA $41FE + STA $1C + LDA $1D + STA $417F + LDA $41FF + STA $1D + RTS diff --git a/src/apple2/hrLine.s b/src/apple2/hrLine.s new file mode 100755 index 0000000..62124de --- /dev/null +++ b/src/apple2/hrLine.s @@ -0,0 +1,73 @@ +; +; HIRES COLOR HLINE +; + LDY #$07 ; SAVE VM02, RESTORE HGR +: LDA $E0,Y + STA $40F8,Y + LDA $4078,Y + STA $E0,Y + DEY + BPL :- + LDA $1C + STA $41FE + LDA $417E + STA $1C + LDA $1D + STA $41FF + LDA $417F + STA $1D + BIT $C081 + PLA ; SAVE RETURN ADDRESS + STA $A0 + PLA + STA $A1 + PLA + STA $A2 ; VERTICAL POSITION 2 + PLA + PLA + PLA + PLA + STA $A3 ; HORIZ POSITION 2 + PLA + STA $A4 + PLA + PLA + PLA + STA $A5 ; VERTICAL POSITION 1 + PLA + PLA + PLA + PLA + TAX ; HORIZ POSITION 1 + PLA + TAY + PLA + PLA + LDA $A5 + JSR $F411 ; vm02.call((x1 << 8) | y1, 0xF411); // HPOSN + LDY $A2 + LDX $A4 + LDA $A3 + JSR $F53A ; vm02.call(x2 | (y2 << 16), 0xF53A); // HLINE + LDA $A1 ; RESTORE RETURN ADDRESS + PHA + LDA $A0 + PHA + BIT $C083 + BIT $C083 + LDY #$07 ; SAVE HGR, RESTORE VM02 +: LDA $E0,Y + STA $4078,Y + LDA $40F8,Y + STA $E0,Y + DEY + BPL :- + LDA $1C + STA $417E + LDA $41FE + STA $1C + LDA $1D + STA $417F + LDA $41FF + STA $1D + RTS diff --git a/src/apple2/hrLineTo.s b/src/apple2/hrLineTo.s new file mode 100755 index 0000000..94906e5 --- /dev/null +++ b/src/apple2/hrLineTo.s @@ -0,0 +1,58 @@ +; +; HIRES COLOR HLINE +; + LDY #$07 ; SAVE VM02, RESTORE HGR +: LDA $E0,Y + STA $40F8,Y + LDA $4078,Y + STA $E0,Y + DEY + BPL :- + LDA $1C + STA $41FE + LDA $417E + STA $1C + LDA $1D + STA $41FF + LDA $417F + STA $1D + BIT $C081 + PLA ; SAVE RETURN ADDRESS + STA $A0 + PLA + STA $A1 + PLA + TAY ; VERTICAL POSITION 2 + PLA + PLA + PLA + PLA + STA $A3 ; HORIZ POSITION 2 + PLA + TAX + PLA + PLA + LDA $A3 + JSR $F53A ; vm02.call(x2 | (y2 << 16), 0xF53A); // HLINE + LDA $A1 ; RESTORE RETURN ADDRESS + PHA + LDA $A0 + PHA + BIT $C083 + BIT $C083 + LDY #$07 ; SAVE HGR, RESTORE VM02 +: LDA $E0,Y + STA $4078,Y + LDA $40F8,Y + STA $E0,Y + DEY + BPL :- + LDA $1C + STA $417E + LDA $41FE + STA $1C + LDA $1D + STA $417F + LDA $41FF + STA $1D + RTS diff --git a/src/apple2/hrPlot.s b/src/apple2/hrPlot.s new file mode 100755 index 0000000..8396831 --- /dev/null +++ b/src/apple2/hrPlot.s @@ -0,0 +1,58 @@ +; +; HIRES PLOT +; + LDY #$07 ; SAVE VM02, RESTORE HGR +: LDA $E0,Y + STA $40F8,Y + LDA $4078,Y + STA $E0,Y + DEY + BPL :- + LDA $1C + STA $41FE + LDA $417E + STA $1C + LDA $1D + STA $41FF + LDA $417F + STA $1D + BIT $C081 ; SWAP IN ROM + PLA ; SAVE RETURN ADDRESS + STA $A0 + PLA + STA $A1 + PLA + STA $A2 ; VERTICAL POSITION + PLA + PLA + PLA + PLA + TAX ; HORIZ POSITION + PLA + TAY + PLA + PLA + LDA $A2 + JSR $F457 ; HPLOT + LDA $A1 ; RESTORE RETURN ADDRESS + PHA + LDA $A0 + PHA +; BIT $C083 ; SWAP IN LC BANK2 +; BIT $C083 ; WRITE ENABLE + LDY #$07 ; SAVE HGR, RESTORE VM02 +: LDA $E0,Y + STA $4078,Y + LDA $40F8,Y + STA $E0,Y + DEY + BPL :- + LDA $1C + STA $417E + LDA $41FE + STA $1C + LDA $1D + STA $417F + LDA $41FF + STA $1D + RTS diff --git a/src/apple2/lrClrHLine.s b/src/apple2/lrClrHLine.s new file mode 100755 index 0000000..da543ec --- /dev/null +++ b/src/apple2/lrClrHLine.s @@ -0,0 +1,39 @@ +; +; LORES COLOR HLINE +; + BIT $C081 + PLA + STA $A0 + PLA + STA $A1 + PLA + TAX + PLA + PLA + PLA + TXA + JSR $F864 ; SET COLOR + PLA + STA $A2 ; VERTICAL POSITION + PLA + PLA + PLA + PLA + STA $2C ; HORIZ POSITION RIGHT + PLA + PLA + PLA + PLA + TAY ; HORIZ POSITION LEFT + PLA + PLA + PLA + LDA $A2 + JSR $F819 + LDA $A1 + PHA + LDA $A0 + PHA + BIT $C083 + BIT $C083 + RTS diff --git a/src/apple2/lrClrPlot.s b/src/apple2/lrClrPlot.s new file mode 100755 index 0000000..80b7411 --- /dev/null +++ b/src/apple2/lrClrPlot.s @@ -0,0 +1,34 @@ +; +; LORES PLOT W/ COLOR +; + BIT $C081 ; SWAP IN ROM + PLA + STA $A0 + PLA + STA $A1 + PLA + TAX + PLA + PLA + PLA + TXA + JSR $F864 ; SET COLOR + PLA + STA $A2 ; VERTICAL POSITION + PLA + PLA + PLA + PLA + TAY ; HORIZ POSITION + PLA + PLA + PLA + LDA $A2 + JSR $F800 + LDA $A1 + PHA + LDA $A0 + PHA +; BIT $C083 ; SWAP IN LC BANK2 +; BIT $C083 ; WRITE ENABLE + RTS diff --git a/src/apple2/lrClrVLine.s b/src/apple2/lrClrVLine.s new file mode 100755 index 0000000..6f11cf1 --- /dev/null +++ b/src/apple2/lrClrVLine.s @@ -0,0 +1,39 @@ +; +; LORES VLINE +; + BIT $C081 + PLA + STA $A0 + PLA + STA $A1 + PLA + TAX + PLA + PLA + PLA + TXA + JSR $F864 ; SET COLOR + PLA + STA $2D ; VERTICAL POSITION BOTTOM + PLA + PLA + PLA + PLA + STA $A2 ; VERTICAL POSITION TOP + PLA + PLA + PLA + PLA + TAY ; HORIZ POSITION + PLA + PLA + PLA + LDA $A2 + JSR $F828 + LDA $A1 + PHA + LDA $A0 + PHA + BIT $C083 + BIT $C083 + RTS diff --git a/src/apple2/lrColor.s b/src/apple2/lrColor.s new file mode 100755 index 0000000..75843e0 --- /dev/null +++ b/src/apple2/lrColor.s @@ -0,0 +1,22 @@ +; +; LORES COLOR +; + BIT $C081 + PLA + STA $A0 + PLA + STA $A1 + PLA + TAX + PLA + PLA + PLA + TXA + JSR $F864 ; SET COLOR + LDA $A1 + PHA + LDA $A0 + PHA + BIT $C083 + BIT $C083 + RTS diff --git a/src/apple2/lrHLine.s b/src/apple2/lrHLine.s new file mode 100755 index 0000000..aecc2b8 --- /dev/null +++ b/src/apple2/lrHLine.s @@ -0,0 +1,32 @@ +; +; LORES COLOR HLINE +; + BIT $C081 + PLA + STA $A0 + PLA + STA $A1 + PLA + STA $A2 ; VERTICAL POSITION + PLA + PLA + PLA + PLA + STA $2C ; HORIZ POSITION RIGHT + PLA + PLA + PLA + PLA + TAY ; HORIZ POSITION LEFT + PLA + PLA + PLA + LDA $A2 + JSR $F819 + LDA $A1 + PHA + LDA $A0 + PHA + BIT $C083 + BIT $C083 + RTS diff --git a/src/apple2/lrPlot.s b/src/apple2/lrPlot.s new file mode 100755 index 0000000..ec38888 --- /dev/null +++ b/src/apple2/lrPlot.s @@ -0,0 +1,27 @@ +; +; LORES PLOT +; + BIT $C081 ; SWAP IN ROM + PLA + STA $A0 + PLA + STA $A1 + PLA + STA $A2 ; VERTICAL POSITION + PLA + PLA + PLA + PLA + TAY ; HORIZ POSITION + PLA + PLA + PLA + LDA $A2 + JSR $F800 + LDA $A1 + PHA + LDA $A0 + PHA +; BIT $C083 ; SWAP IN LC BANK2 +; BIT $C083 ; WRITE ENABLE + RTS diff --git a/src/apple2/lrVLine.s b/src/apple2/lrVLine.s new file mode 100755 index 0000000..f369263 --- /dev/null +++ b/src/apple2/lrVLine.s @@ -0,0 +1,32 @@ +; +; LORES VLINE +; + BIT $C081 + PLA + STA $A0 + PLA + STA $A1 + PLA + STA $2D ; VERTICAL POSITION BOTTOM + PLA + PLA + PLA + PLA + STA $A2 ; VERTICAL POSITION TOP + PLA + PLA + PLA + PLA + TAY ; HORIZ POSITION + PLA + PLA + PLA + LDA $A2 + JSR $F828 + LDA $A1 + PHA + LDA $A0 + PHA + BIT $C083 + BIT $C083 + RTS diff --git a/src/apple2/paddle.s b/src/apple2/paddle.s new file mode 100755 index 0000000..af054f0 --- /dev/null +++ b/src/apple2/paddle.s @@ -0,0 +1,29 @@ +; +; READ PADDLE +; + BIT $C081 + PLA + STA $A0 + PLA + STA $A1 + PLA + AND #$03 + TAX + PLA + PLA + PLA + SEI ; TURN OFF INTS FOR ACCURATE READING + JSR $FB1E ; READ PADDLE + LDA #$00 + PHA + PHA + PHA + TYA + PHA + LDA $A1 + PHA + LDA $A0 + PHA + BIT $C083 + BIT $C083 + RTS diff --git a/src/apple2/tone.s b/src/apple2/tone.s new file mode 100755 index 0000000..eb71c10 --- /dev/null +++ b/src/apple2/tone.s @@ -0,0 +1,47 @@ +; +; TONE W/ PITCH AND DURATION +; + PLA + STA $A0 + PLA + STA $A1 + PLA + STA $A2 ; DURATION + PLA + PLA + PLA + PLA + STA $A3 ; TIMBRE + PLA + PLA + PLA + PLA + STA $A4 ; TONE + EOR #$FF + STA $A5 + PLA + PLA + PLA + LDA $A4 + SEC + SBC $A3 + STA $A4 + SEI ; DISABLE INTERRUPTS +TONELOOPOUTR: LDX $A5 +TONELOOP: LDY $A3 + BIT $C030 +TONEDELAY1: DEY + BNE TONEDELAY1 + BIT $C030 + LDY $A4 +TONEDELAY2: DEY + BNE TONEDELAY2 + DEX + BNE TONELOOP + DEC $A2 + BNE TONELOOPOUTR + LDA $A1 + PHA + LDA $A0 + PHA + JMP ($300) ; RETURN THROUGH YIELD diff --git a/src/apple2/vm02.clasm b/src/apple2/vm02.clasm new file mode 100755 index 0000000..73222af --- /dev/null +++ b/src/apple2/vm02.clasm @@ -0,0 +1,755 @@ +;* FROM GLOBAL.INC: +SRCADDR = $DC +DSTADDR = $DE +;* +;* CLASS FILE vm02.class +;* + .ORG $1000 ; DUMMY ADDRESS + .BYTE $CA,$FE,$BA,$BE ; MAGIC + .BYTE $00,$00 ; MINOR 0 + .BYTE $00,$31 ; MAJOR 49 +;* +;* CONSTANT POOL +;* + .BYTE $00,31 ; CONST POOL COUNT 31 +;* CONST POOL INDEX 1 + .BYTE $0A ; METHODREF + .BYTE $00,$03 ; CLASS #3 + .BYTE $00,$18 ; NAME AND TYPE #24 +;* CONST POOL INDEX 2 + .BYTE 07 ; CLASS + .BYTE $00,$19 ; #25 +;* CONST POOL INDEX 3 + .BYTE 07 ; CLASS + .BYTE $00,$1A ; #26 +;* CONST POOL INDEX 4 + .BYTE $01 ; UTF8 + .BYTE $00,$06 ; STRLEN + .BYTE "" +;* CONST POOL INDEX 5 + .BYTE $01 ; UTF8 + .BYTE $00,$03 ; STRLEN + .BYTE "()V" +;* CONST POOL INDEX 6 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "Code" +;* CONST POOL INDEX 7 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "pokeByte" +;* CONST POOL INDEX 8 + .BYTE $01 ; UTF8 + .BYTE $00,$05 ; STRLEN + .BYTE "(IB)V" +;* CONST POOL INDEX 9 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "pokeWord" +;* CONST POOL INDEX 10 + .BYTE $01 ; UTF8 + .BYTE $00,$05 ; STRLEN + .BYTE "(IS)V" +;* CONST POOL INDEX 11 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "peekByte" +;* CONST POOL INDEX 12 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "(I)I" +;* CONST POOL INDEX 13 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "peekWord" +;* CONST POOL INDEX 14 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "call" +;* CONST POOL INDEX 15 + .BYTE $01 ; UTF8 + .BYTE $00,$05 ; STRLEN + .BYTE "(II)I" +;* CONST POOL INDEX 16 + .BYTE $01 ; UTF8 + .BYTE $00,$0B ; STRLEN + .BYTE "floatAsBits" +;* CONST POOL INDEX 17 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "(F)I" +;* CONST POOL INDEX 18 + .BYTE $01 ; UTF8 + .BYTE $00,$0B ; STRLEN + .BYTE "bitsAsFloat" +;* CONST POOL INDEX 19 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "(I)F" +;* CONST POOL INDEX 20 + .BYTE $01 ; UTF8 + .BYTE $00,$09 ; STRLEN + .BYTE "refAsBits" +;* CONST POOL INDEX 21 + .BYTE $01 ; UTF8 + .BYTE $00,$15 ; STRLEN + .BYTE "(Ljava/lang/Object;)I" +;* CONST POOL INDEX 22 + .BYTE $01 ; UTF8 + .BYTE $00,$09 ; STRLEN + .BYTE "bitsAsRef" +;* CONST POOL INDEX 23 + .BYTE $01 ; UTF8 + .BYTE $00,$15 ; STRLEN + .BYTE "(I)Ljava/lang/Object;" +;* CONST POOL INDEX 24 + .BYTE $0C ; NAME AND TYPE + .BYTE $00,$04 ; NAME #4 + .BYTE $00,$05 ; DESC #5 +;* CONST POOL INDEX 25 + .BYTE $01 ; UTF8 + .BYTE $00,$0B ; STRLEN + .BYTE "apple2/vm02" +;* CONST POOL INDEX 26 + .BYTE $01 ; UTF8 + .BYTE $00,$10 ; STRLEN + .BYTE "java/lang/Object" +;* CONST POOL INDEX 27 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "6502" +;* CONST POOL INDEX 28 + .BYTE $01 ; UTF8 + .BYTE $00,$09 ; STRLEN + .BYTE "pokeBytes" +;* CONST POOL INDEX 29 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "(I[BII)V" +;* CONST POOL INDEX 30 + .BYTE $01 ; UTF8 + .BYTE $00,$09 ; STRLEN + .BYTE "peekBytes" +;* +;* ACCESS FLAGS +;* + .BYTE $00,$21 ; 0x0021 +;* +;* THIS CLASS +;* + .BYTE $00,$02 ; #2 +;* +;* SUPER CLASS +;* + .BYTE $00,$03 ; #3 +;* +;* INTERFACES +;* + .BYTE $00,$00 ; IFACE COUNT 0 +;* +;* FIELDS +;* + .BYTE $00,$00 ; FIELD COUNT 0 +;* +;* METHODS +;* + .BYTE $00,$0C ; METHOD COUNT 12 +;******* METHOD INDEX 0 - ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$04 ; NAME #4 + .BYTE $00,$05 ; DESC #5 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$00,>(M0A0END-M0A0BGN),<(M0A0END-M0A0BGN) +M0A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M0C0END-M0C0BGN),<(M0C0END-M0C0BGN) +M0C0BGN: + .BYTE $2A ; 00000: aload_0 + .BYTE $B7,$00,$01 ; 00001: invokespecial #1 + .BYTE $B1 ; 00004: return +M0C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M0A0END: +;******* METHOD INDEX 1 - pokeByte ******** + .BYTE $01,$09 ; ACCESS FLAGS 0x0109 + .BYTE $00,$07 ; NAME #7 + .BYTE $00,$08 ; DESC #8 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,27 ; NAME #27 + .BYTE $00,$00,>(M1A0END-M1A0BGN),<(M1A0END-M1A0BGN) +M1A0BGN: +;* CODE: + .BYTE $00,$00 ; MAX STACK 0 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M1C0END-M1C0BGN),<(M1C0END-M1C0BGN) +M1C0BGN: + PLA ; SAVE RETURN ADDRESS + STA $A4 + PLA + STA $A5 + PLA ; PULL POKE DATA + STA $A6 + PLA + PLA + PLA + PLA ; PULL POKE ADDRESS + STA $A8 + PLA + STA $A9 + PLA + PLA + SEI + BIT $C081 ; SELECT ROM + LDY #$00 + LDA $A6 + STA ($A8),Y + LDA $A5 + PHA + LDA $A4 + PHA + RTS +M1C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M1A0END: +;******* METHOD INDEX 2 - pokeWord ******** + .BYTE $01,$09 ; ACCESS FLAGS 0x0109 + .BYTE $00,$09 ; NAME #9 + .BYTE $00,$0A ; DESC #10 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,27 ; NAME #27 + .BYTE $00,$00,>(M2A0END-M2A0BGN),<(M2A0END-M2A0BGN) +M2A0BGN: +;* CODE: + .BYTE $00,$00 ; MAX STACK 0 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M2C0END-M2C0BGN),<(M2C0END-M2C0BGN) +M2C0BGN: + PLA ; SAVE RETURN ADDRESS + STA $A4 + PLA + STA $A5 + PLA ; PULL POKE DATA + STA $A6 + PLA + STA $A7 + PLA + PLA + PLA ; PULL POKE ADDRESS + STA $A8 + PLA + STA $A9 + PLA + PLA + SEI + BIT $C081 ; SELECT ROM + LDY #$00 + LDA $A6 + STA ($A8),Y + INY + LDA $A7 + STA ($A8),Y + LDA $A5 + PHA + LDA $A4 + PHA + RTS +M2C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M2A0END: +;******* METHOD INDEX 3 - peekByte ******** + .BYTE $01,$09 ; ACCESS FLAGS 0x0109 + .BYTE $00,$0B ; NAME #11 + .BYTE $00,$0C ; DESC #12 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,27 ; NAME #27 + .BYTE $00,$00,>(M3A0END-M3A0BGN),<(M3A0END-M3A0BGN) +M3A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M3C0END-M3C0BGN),<(M3C0END-M3C0BGN) +M3C0BGN: + PLA ; SAVE RETURN ADDRESS + STA $A4 + PLA + STA $A5 + PLA ; PULL PEEK ADDRESS + STA $A6 + PLA + STA $A7 + PLA + PLA + SEI + BIT $C081 ; SELECT ROM + LDA #$00 ; PUSH HIWORD = 0 + PHA + PHA + PHA ; PUSH HIBYTE = 0 + TAY + LDA ($A6),Y + PHA + LDA $A5 + PHA + LDA $A4 + PHA + RTS +M3C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M3A0END: +;******* METHOD INDEX 4 - peekWord ******** + .BYTE $01,$09 ; ACCESS FLAGS 0x0109 + .BYTE $00,$0D ; NAME #13 + .BYTE $00,$0C ; DESC #12 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,27 ; NAME #27 + .BYTE $00,$00,>(M4A0END-M4A0BGN),<(M4A0END-M4A0BGN) +M4A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M4C0END-M4C0BGN),<(M4C0END-M4C0BGN) +M4C0BGN: + PLA ; SAVE RETURN ADDRESS + STA $A4 + PLA + STA $A5 + PLA ; PULL PEEK ADDRESS + STA $A6 + PLA + STA $A7 + PLA + PLA + SEI + BIT $C081 ; SELECT ROM + LDA #$00 ; PUSH HIWORD = 0 + PHA + PHA + LDY #$01 + LDA ($A6),Y + DEY + PHA + LDA ($A6),Y + PHA + LDA $A5 + PHA + LDA $A4 + PHA + RTS +M4C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M4A0END: +;******* METHOD INDEX 5 - call ******** + .BYTE $01,$09 ; ACCESS FLAGS 0x0109 + .BYTE $00,$0E ; NAME #14 + .BYTE $00,$0F ; DESC #15 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,27 ; NAME #27 + .BYTE $00,$00,>(M5A0END-M5A0BGN),<(M5A0END-M5A0BGN) +M5A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M5C0END-M5C0BGN),<(M5C0END-M5C0BGN) +M5C0BGN: +.IF 1 + JMP ($0390) ; NATIVE_CALL +.ELSE + BCC :+ +M5C0LCKCNT: .BYTE $00 ; LOCK/UNLOCK COUNT +: PLA ; PULL RETURN ADDRESS + STA $A4 + PLA + STA $A5 + PLA ; PULL CALL ADDRESS + STA $A6 + PLA + STA $A7 + PLA + PLA + TSX + LDA $0101,X ; GET REG VALS + STA $A8 ; BUT LEAVE ON STACK FOR RETUN VALS + LDA $0102,X + STA $A9 + LDA $0103,X + STA $AA + LDA $A5 ; PUSH RETURN ADDRESS + PHA + LDA $A4 + PHA + LDA $A7 + BNE M5C0ROMCALL + LDY $A6 ; CONVERT SYSCALL INTO ADDRESS + LDA $0300,Y + STA $A6 + LDA $0301,Y + STA $A7 + LDY #$02 + LDA ($A0),Y ; INCREMENT LOCK COUNT + CLC + ADC #$01 + STA ($A0),Y + CMP #$01 + BNE M5C0SYSCALL ; SKIP LOCK IF ALREADY LOCKED + LDA #<(M5C0SYSCALL-M5C0BGN-1) + CLC + ADC $A0 + TAX + LDA #>(M5C0SYSCALL-M5C0BGN-1) + ADC $A1 + PHA + TXA + PHA + LDA $A2 + LDX $A3 + JMP ($30E) ; LOCK IT +M5C0ROMCALL: BIT $C081 ; SELECT ROM + LDA #<(M5C0RET-M5C0BGN-1) + CLC + ADC $A0 + TAX + LDA #>(M5C0RET-M5C0BGN-1) + ADC $A1 + PHA + TXA + PHA + LDA $A8 + LDX $A9 + LDY $AA + JMP ($A6) +M5C0RET: PHP + STA $A8 + STX $A9 + PLA + TSX + STA $0106,X + TYA + STA $0105,X + LDA $A9 + STA $0104,X + LDA $A8 + STA $0103,X + RTS +M5C0SYSCALL: LDA $A2 ; SAVE MEMORY HANDLE FOR METHOD + PHA + LDA $A3 + PHA + LDA $A0 ; SAVE MEMORY ADDRESS FOR METHOD + PHA + LDA $A1 + PHA + LDA #<(M5C0SYSRET-M5C0BGN-1) + CLC + ADC $A0 + TAX + LDA #>(M5C0SYSRET-M5C0BGN-1) + ADC $A1 + PHA + TXA + PHA + LDA $A8 + LDX $A9 + LDY $AA + JMP ($A6) ; CALL SYSTEM FUNC +M5C0SYSRET: PHP ; SAVE REGISTERS IN STACK PARAM + STA $A8 + STX $A9 + PLA + TSX + STA $010A,X + TYA + STA $0109,X + LDA $A9 + STA $0108,X + LDA $A8 + STA $0107,X + PLA ; RESTORE METHOD ADDRESS + STA $A1 + PLA + STA $A0 + LDY #$02 + LDA ($A0),Y ; DECREMENT LOCK COUNT + SEC + SBC #$01 + STA ($A0),Y + BNE :+ ; SKIP UNLOCK IF COUNT > 0 + PLA ; RETRIEVE SAVED HANDLE + TAX + PLA + JMP ($310) ; UNLOCK METHOD, RETURN TO CALLER +: PLA ; DISCARD SAVED HANDLE + PLA + RTS +.ENDIF +M5C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M5A0END: +;******* METHOD INDEX 6 - floatAsBits ******** + .BYTE $01,$09 ; ACCESS FLAGS 0x0109 + .BYTE $00,$10 ; NAME #16 + .BYTE $00,$11 ; DESC #17 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,27 ; NAME #27 + .BYTE $00,$00,>(M6A0END-M6A0BGN),<(M6A0END-M6A0BGN) +M6A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M6C0END-M6C0BGN),<(M6C0END-M6C0BGN) +M6C0BGN: + RTS +M6C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M6A0END: +;******* METHOD INDEX 7 bitsAsFloat ******** + .BYTE $01,$09 ; ACCESS FLAGS 0x0109 + .BYTE $00,$12 ; NAME #18 + .BYTE $00,$13 ; DESC #19 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,27 ; NAME #27 + .BYTE $00,$00,>(M7A0END-M7A0BGN),<(M7A0END-M7A0BGN) +M7A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M7C0END-M7C0BGN),<(M7C0END-M7C0BGN) +M7C0BGN: + RTS +M7C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M7A0END: +;******* METHOD INDEX 8 - refAsBits ******** + .BYTE $01,$09 ; ACCESS FLAGS 0x0109 + .BYTE $00,$14 ; NAME #20 + .BYTE $00,$15 ; DESC #21 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,27 ; NAME #27 + .BYTE $00,$00,>(M8A0END-M8A0BGN),<(M8A0END-M8A0BGN) +M8A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M8C0END-M8C0BGN),<(M8C0END-M8C0BGN) +M8C0BGN: + RTS +M8C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M8A0END: +;******* METHOD INDEX 9 - bitsAsRef ******** + .BYTE $01,$09 ; ACCESS FLAGS 0x0109 + .BYTE $00,$16 ; NAME #22 + .BYTE $00,$17 ; DESC #23 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,27 ; NAME #27 + .BYTE $00,$00,>(M9A0END-M9A0BGN),<(M9A0END-M9A0BGN) +M9A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M9C0END-M9C0BGN),<(M9C0END-M9C0BGN) +M9C0BGN: + RTS +M9C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M9A0END: +;******* METHOD INDEX 10 - pokeBytes ******** + .BYTE $01,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,28 ; NAME #28 + .BYTE $00,29 ; DESC #29 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,27 ; NAME #27 + .BYTE $00,$00,>(M10A0END-M10A0BGN),<(M10A0END-M10A0BGN) +M10A0BGN: +;* CODE: + .BYTE $00,$00 ; MAX STACK 0 + .BYTE $00,$04 ; MAX LOCALS 4 + .BYTE $00,$00,>(M10C0END-M10C0BGN),<(M10C0END-M10C0BGN) +M10C0BGN: + PLA + STA $A2 + PLA + STA $A3 + PLA ; POP LEN PARAM + STA $A4 + PLA + STA $A5 + PLA + PLA + PLA ; POP OFFSET PARAM + STA SRCADDR + PLA + STA SRCADDR+1 + PLA + PLA + PLA ; POP BYTE ARRAY + TAY + PLA + STA $A6 + PLA + PLA + LDA #<(M10C0HMEMCALL-M10C0BGN-1) + CLC + ADC $A0 + TAX + LDA #>(M10C0HMEMCALL-M10C0BGN-1) + ADC $A1 + PHA + TXA + PHA + TYA + LDX $A6 + JMP ($306) ; GET POINTER TO ARRAY +M10C0HMEMCALL: CLC + ADC #$02 ; SKIP LENGTH WORD + BCC :+ + INX + CLC +: ADC SRCADDR ; ADD TO OFFSET + STA SRCADDR + TXA + ADC SRCADDR+1 + STA SRCADDR+1 + PLA ; POP MEMORY ADDRESS + STA DSTADDR + PLA + STA DSTADDR+1 + PLA + PLA + LDA $A3 ; PUSH RETURN ADDRESS + PHA + LDA $A2 + PHA + LDA $A4 ; LOAD LEN + LDX $A5 + JMP ($342) ; MEMCPY +M10C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M10A0END: +;******* METHOD INDEX 11 - peekBytes ******** + .BYTE $01,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,30 ; NAME #30 + .BYTE $00,29 ; DESC #29 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,27 ; NAME #27 + .BYTE $00,$00,>(M11A0END-M11A0BGN),<(M11A0END-M11A0BGN) +M11A0BGN: +;* CODE: + .BYTE $00,$00 ; MAX STACK 0 + .BYTE $00,$04 ; MAX LOCALS 4 + .BYTE $00,$00,>(M11C0END-M11C0BGN),<(M11C0END-M11C0BGN) +M11C0BGN: + PLA + STA $A2 + PLA + STA $A3 + PLA ; POP LEN PARAM + STA $A4 + PLA + STA $A5 + PLA + PLA + PLA ; POP OFFSET PARAM + STA DSTADDR + PLA + STA DSTADDR+1 + PLA + PLA + PLA ; POP BYTE ARRAY + TAY + PLA + STA $A6 + PLA + PLA + LDA #<(M11C0HMEMCALL-M10C0BGN-1) + CLC + ADC $A0 + TAX + LDA #>(M11C0HMEMCALL-M10C0BGN-1) + ADC $A1 + PHA + TXA + PHA + TYA + LDX $A6 + JMP ($306) ; GET POINTER TO ARRAY +M11C0HMEMCALL: CLC + ADC #$02 ; SKIP LENGTH WORD + BCC :+ + INX + CLC +: ADC DSTADDR ; ADD TO OFFSET + STA DSTADDR + TXA + ADC DSTADDR+1 + STA DSTADDR+1 + PLA ; POP MEMORY ADDRESS + STA SRCADDR + PLA + STA SRCADDR+1 + PLA + PLA + LDA $A3 ; PUSH RETURN ADDRESS + PHA + LDA $A2 + PHA + LDA $A4 ; LOAD LEN + LDX $A5 + JMP ($342) ; MEMCPY +M11C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M11A0END: +;* +;* GLOBAL ATTRIBUTES +;* + .BYTE $00,$00 ; ATTRIB COUNT 0 diff --git a/src/apple2/vm02.java b/src/apple2/vm02.java new file mode 100755 index 0000000..471b358 --- /dev/null +++ b/src/apple2/vm02.java @@ -0,0 +1,45 @@ +package apple2; + +public class vm02 +{ + public static void pokeByte(int address, byte data) + { + } + public static void pokeWord(int address, short data) + { + } + public static int peekByte(int address) + { + return (0); + } + public static int peekWord(int address) + { + return (0); + } + public static int call(int regs, int address) + { + return (0); + } + public static int floatAsBits(float fp) + { + return (0); + } + public static float bitsAsFloat(int bits) + { + return (0); + } + public static int refAsBits(Object o) + { + return (0); + } + public static Object bitsAsRef(int bits) + { + return (null); + } + public static void pokeBytes(int address, byte data[], int offset, int len) + { + } + public static void peekBytes(int address, byte data[], int offset, int len) + { + } +} diff --git a/src/array.clasm b/src/array.clasm new file mode 100755 index 0000000..f68b333 --- /dev/null +++ b/src/array.clasm @@ -0,0 +1,52 @@ +;* +;* CLASS FILE array.class +;* + .BYTE $CA,$FE,$BA,$BE ; MAGIC + .BYTE $00,$00 ; MINOR 0 + .BYTE $00,$31 ; MAJOR 49 +;* +;* CONSTANT POOL +;* + .BYTE $00,$05 ; CONST POOL COUNT 5 +;* CONST POOL INDEX 1 + .BYTE 07 ; CLASS + .BYTE $00,$03 ; #3 +;* CONST POOL INDEX 2 + .BYTE 07 ; CLASS + .BYTE $00,$04 ; #4 +;* CONST POOL INDEX 3 + .BYTE $01 ; UTF8 + .BYTE $00,$01 ; STRLEN + .BYTE "]" +;* CONST POOL INDEX 4 + .BYTE $01 ; UTF8 + .BYTE $00,$10 ; STRLEN + .BYTE "java/lang/Object" +;* +;* ACCESS FLAGS +;* + .BYTE $00,$21 ; 0x0021 +;* +;* THIS CLASS +;* + .BYTE $00,$01 ; #1 +;* +;* SUPER CLASS +;* + .BYTE $00,$02 ; #2 +;* +;* INTERFACES +;* + .BYTE $00,$00 ; IFACE COUNT 0 +;* +;* FIELDS +;* + .BYTE $00,$00 ; FIELD COUNT 0 +;* +;* METHODS +;* + .BYTE $00,$00 ; METHOD COUNT 0 +;* +;* GLOBAL ATTRIBUTES +;* + .BYTE $00,$00 ; ATTRIB COUNT 0 diff --git a/src/clasm.cfg b/src/clasm.cfg new file mode 100755 index 0000000..0f265c0 --- /dev/null +++ b/src/clasm.cfg @@ -0,0 +1,10 @@ +MEMORY { + RAM: start = $1000, size = $BF00, file = %O; +} +SEGMENTS { + CODE: load = RAM, type = rw; + DATA: load = RAM, type = rw; + BSS: load = RAM, type = rw; +} + + diff --git a/src/class.inc b/src/class.inc new file mode 100755 index 0000000..419375d --- /dev/null +++ b/src/class.inc @@ -0,0 +1,56 @@ +;* +;* JAVA CLASS STRUCTURE +;* + +;* +;* CLASS STRUCTURE - 24 BYTES + CONST POOL +;* +.DEFINE CLASSBASESZ 24 ; BASE CLASS SIZE = 24 BYTES +.DEFINE CLASSTHIS $00 ; 2 BYTES - HSTR +.DEFINE CLASSSUPER $02 ; 1 BYTE - CLASS INDEX +.DEFINE CLASSLOADER $03 ; 1 BYTE - CLASS INDEX +.DEFINE CLASSINSTSIZE $04 ; 2 BYTES - U2 +.DEFINE CLASSACCESS $06 ; 2 BYTES - U2 +.DEFINE CLASSCONSTCNT $08 ; 2 BYTES - U2 +.DEFINE CLASSIFACECNT $0A ; 1 BYTE - U1 +.DEFINE CLASSFIELDCNT $0B ; 1 BYTE - U1 +.DEFINE CLASSMETHODCNT $0C ; 1 BYTE - U1 +.DEFINE CLASSVTBLCNT $0D ; 1 BYTE - U1 +.DEFINE CLASSIFACETBL $0E ; 2 BYTES - HMEM +.DEFINE CLASSFIELDTBL $10 ; 2 BYTES - HMEM +.DEFINE CLASSMETHODTBL $12 ; 2 BYTES - HMEM +.DEFINE CLASSVIRTBL $14 ; 2 BYTES - HMEM +.DEFINE CLASSLOCKCNT $16 ; 2 BYTES - U2 +.DEFINE CLASSCONSTPL $18 ; CLASSCONSTCNT * CONSTPLRECSZ BYTES +;* +;* CONSTANT POOL RECORD SIZE - 5 BYTES (1 BYTE TYPE, 4 BYTES VALUE) +;* +.DEFINE CONSTPLRECSZ 5 + .IMPORT MUL5 +.MACRO CALC_CONSTPLRECSZ + JSR MUL5 +.ENDMACRO +;* +;* FIELD TABLE RECORD - 9 BYTES +;* +.DEFINE FIELDRECSZ 10 +.DEFINE FIELDACCESS $00 ; 1 BYTE - U1 +.DEFINE FIELDNAME $01 ; 2 BYTES - HSTR +.DEFINE FIELDDESC $03 ; 2 BYTES - HSTR +.DEFINE FIELDTYPE $05 ; 1 BYTE - U1 +.DEFINE FIELDINSTOFFSET $06 ; 2 BYTES - U2 +.DEFINE FIELDSTATICVAL $06 ; 4 BYTES - U4 (UNION WITH INST OFFSET) +.IMPORT MUL10 +.DEFINE MUL_FIELDRECSZ MUL10 +;* +;* METHOD TABLE RECORD - 9 BYTES +;* +.DEFINE METHODRECSZ 9 +.DEFINE METHODACCESS $00 ; 2 BYTES - U2 +.DEFINE METHODNAME $02 ; 2 BYTES - HSTR +.DEFINE METHODDESC $04 ; 2 BYTES - HSTR +.DEFINE METHODPARAMS $06 ; 1 BYTE - U1 +.DEFINE METHODSTATICODE $07 ; 2 BYTES - HCODE FOR STATIC CODE +.DEFINE METHODVINDEX $07 ; 2 BYTES - INDEX TO VTABLE (UNION WITH HCODE) +.IMPORT MUL9 +.DEFINE MUL_METHODRECSZ MUL9 diff --git a/src/classclass.s b/src/classclass.s new file mode 100755 index 0000000..31d5b15 --- /dev/null +++ b/src/classclass.s @@ -0,0 +1,636 @@ +;* +;* JAVA CLASS CLASS FOR 6502 +;* + .INCLUDE "global.inc" + .INCLUDE "class.inc" + .IMPORT HMEM_LOCK,HMEM_UNLOCK + .IMPORT HMEM_PTR,HMEM_REF_INC,HMEM_REF_DEC + .IMPORT HSTR_HASH,STR_HASH,HSTRPL_ADD,HSTRPL_DEL,PRHSTR + .IMPORT MEMSRC,MEMDST,MEMCLR,MEMCPY + .IMPORT LOADCLASS_FILE + .IMPORT THROW_INTERNALERR + .EXPORT HCLASS_INIT,HCLASS_NAME,HCLASS_HNDL,HCLASS_INDEX,HCLASS_ADD + .EXPORT CLASS_STRING,CLASS_MATCH_NAME,CLASS_MATCH_DESC,CLASS_VIRTCODE + .EXPORT RESOLVE_CLASS,RESOLVE_METHOD,CLASS_METHODPTR,RESOLVE_FIELD,CLASS_FIELDPTR + .EXPORT CLASS_LOCKMETHOD,CLASS_UNLOCKMETHOD,CLASS_LOCK,CLASS_UNLOCK,CLASS_OF + + .SEGMENT "INIT" +;* +;* CLEAR CLASS TABLE +;* +HCLASS_INIT: LDA #HCLASS_TBLL + AUXZP_ACCESS_ON + JSR MEMDST + LDA #$00 + LDX #$01 + JSR MEMCLR + AUXZP_ACCESS_OFF + RTS + + .DATA +;HCLASS_TBLL: .RES 128, $00 +;HCLASS_TBLH: .RES 128, $00 + + .CODE +;* +;* THE CLASS TABLE MATCHES NAMES TO CLASSES +;* +;* FIND A CLASS GIVEN IT'S NAME +;* ENTRY: AX = HSTRNAME +;* EXIT: AX = HCLASS +;* Y = INDEX +;* C = 0 :: SUCCESS +;* C = 1 :: FAILURE +;* +HCLASS_NAME: STA HSTR + STX HSTR+1 + LDY #$01 +FINDSTRLP: AUXZP_ACCESS_ON + LDA HCLASS_TBLL,Y + LDX HCLASS_TBLH,Y + AUXZP_ACCESS_OFF + BEQ FINDSTRNXT ; SKIP NULL HANDLES + STY CCLASSCNT + JSR HMEM_PTR ; CONVERT TO ADDRESS + STA CCLASSPTR + STX CCLASSPTR+1 + LDY #CLASSTHIS + LDA (CCLASSPTR),Y + CMP HSTR + BNE :+ + INY + LDA (CCLASSPTR),Y + CMP HSTR+1 + BNE :+ + LDY CCLASSCNT ; FOUND IT + AUXZP_ACCESS_ON + LDA HCLASS_TBLL,Y + LDX HCLASS_TBLH,Y + AUXZP_ACCESS_OFF + CLC ; RETURN SUCCESS + RTS +: LDY CCLASSCNT +FINDSTRNXT: INY + BPL FINDSTRLP ; KEEP CHECKING + SEC ; NOT FOUND + RTS ; RETURN FAIL +;* +;* FIND A CLASS GIVEN IT'S HANDLE +;* ENTRY: AX = HCLASS +;* EXIT: AX = HCLASS +;* Y = INDEX +;* C = 0 :: SUCCESS +;* C = 1 :: FAILURE +;* +HCLASS_HNDL: LDY #$01 +FINDCLSLP: AUXZP_ACCESS_ON + CMP HCLASS_TBLL,Y + BNE FINDCLSNXT ; SEARCH FOR A MATCH + PHA + TXA + CMP HCLASS_TBLH,Y + BNE :+ + PLA ; FOUND IT + AUXZP_ACCESS_OFF + CLC ; RETURN SUCCESS + RTS +: PLA +FINDCLSNXT: AUXZP_ACCESS_OFF + INY + BPL FINDCLSLP ; KEEP CHECKING + SEC ; NOT FOUND + RTS ; RETURN FAIL +;* +;* RETURN A CLASS HANDLE GIVEN ITS INDEX +;* ENTRY: Y = INDEX +;* EXIT: AX = HANDLE +;* Y = INDEX +;* +HCLASS_INDEX: AUXZP_ACCESS_ON + LDX HCLASS_TBLH,Y + LDA HCLASS_TBLL,Y + AUXZP_ACCESS_OFF + RTS +;* +;* RETURN A CLASS NAME STRING GIVEN ITS INDEX +;* ENTRY: Y = INDEX +;* EXIT: AX = HSTR +;* +CLASS_STRING: AUXZP_ACCESS_ON + LDA HCLASS_TBLL,Y + LDX HCLASS_TBLH,Y + AUXZP_ACCESS_OFF + JSR HMEM_PTR + STA CCINST + STX CCINST+1 + LDY #CLASSTHIS+1 + LDA (CCINST),Y + DEY + TAX + LDA (CCINST),Y + RTS +;* +;* ADD A NEW CLASS GIVEN IT'S HANDLE +;* ENTRY: AX = CLASS HANDLE +;* EXIT: AX = CLASS HANDLE +;* Y = INDEX +;* C = 0 :: SUCCESS +;* C = 1 :: FAILURE +;* +HCLASS_ADD: JSR HCLASS_HNDL + BCS :+ + PERR "ADD CLASS ALREADY PRESENT" + RTS +: PHA +.IFDEF DEBUG + STA CCINST + STX CCINST+1 + JSR HMEM_PTR + STA HSTR + STX HSTR+1 + LDY #CLASSTHIS+1 + LDA (HSTR),Y + DEY + TAX + LDA (HSTR),Y + JSR HCLASS_NAME + BCS :+ + LDA HSTR + LDX HSTR+1 + JSR PRHSTR + PERR " ALREADY EXISTS CLASS IN TABLE" + JMP THROW_INTERNALERR +: LDA CCINST + LDX CCINST+1 +.ENDIF + LDY #$01 + AUXZP_ACCESS_ON +HCLASSADDLP: LDA HCLASS_TBLH,Y + BEQ HCLASSADDIT + INY + BPL HCLASSADDLP + AUXZP_ACCESS_OFF + PERR "FULL CLASS TABLE" + PLA + SEC + RTS +HCLASSADDIT: AUXZP_ACCESS_OFF + PLA + AUXZP_ACCESS_ON + STA HCLASS_TBLL,Y + PHA + TXA + STA HCLASS_TBLH,Y + PLA + AUXZP_ACCESS_OFF + CLC + RTS +.IF 0 +;* +;* DELETE A CLASS +;* ENTRY: AX = HANDLE +;* EXIT: C = 0 :: SUCCESS +;* C = 1 :: FAILURE +;* +HCLASS_DEL: JSR HCLASS_HNDL + BCS :+ +HCLASS_IDEL: LDA #$00 + AUXZP_ACCESS_ON + STA HCLASS_TBLL,Y + STA HCLASS_TBLH,Y + AUXZP_ACCESS_OFF +: RTS +.ENDIF +;* +;* SET HNAMESTR USED IN IFACE/FIELD/METHOD LOOKUPS +;* ENTRY: AX = HNAMESTR +;* +CLASS_MATCH_NAME: STA CCLASSNAME + STX CCLASSNAME+1 + RTS +;* +;* SET HDESCSTR USED IN IFACE/FIELD/METHOD LOOKUPS +;* ENTRY: AX = HNDESCSTR +;* +CLASS_MATCH_DESC: STA CCLASSDESC + STX CCLASSDESC+1 + RTS +;* +;* FIND CLASS GIVEN ITS NAME, LOAD IT IF NECESSARY +;* ENTRY: AX = HNAMESTR +;* EXIT: AX = CLASS HANDLE +;* Y = CLASS INDEX +;* C = 0 :: SUCCESS +;* C = 1 :: FAILURE +;* +RESOLVE_CLASS: JSR HCLASS_NAME ; LOOKUP CLASS IN TABLE + BCS :+ + RTS +: LDA HSTR ; NOT FOUND, LOAD CLASS FROM FILE + LDX HSTR+1 + JMP LOADCLASS_FILE ; LOAD CLASS AND SUPERCLASSES +;* +;* FIND A METHOD GIVEN CLASS INDEX AND DESCRIPTION +;* ENTRY: Y = CLASS INDEX +;* EXIT: AX = METHOD OFFSET +;* Y = CLASS INDEX (COULD BE SUPERCLASS) +;* C = 0 :: SUCCESS +;* C = 1 :: FAILURE +;* +RESOLVE_METHOD: STY CCLASSINDEX +.IF 0 + PSTRLN "RESOLVING " + LDY CCLASSINDEX + JSR CLASS_STRING + JSR PRHSTR + PSTR ":" + LDA CCLASSNAME + LDX CCLASSNAME+1 + JSR PRHSTR + LDA CCLASSDESC + LDX CCLASSDESC+1 + JSR PRHSTR + SEI + .IMPORT KBWAIT + JSR KBWAIT + .IMPORT CROUT + CLI + JSR CROUT + LDY CCLASSINDEX +RESOLVE_METHOD1: +.ENDIF + AUXZP_ACCESS_ON + LDA HCLASS_TBLL,Y + LDX HCLASS_TBLH,Y + AUXZP_ACCESS_OFF + JSR HMEM_PTR + STA CCLASSPTR + STX CCLASSPTR+1 + LDY #CLASSSUPER + LDA (CCLASSPTR),Y + STA CCLASSSUPR + LDY #CLASSMETHODCNT + LDA (CCLASSPTR),Y + BEQ RESLVSUPRMETHD ; NO METHODS DEFINED FOR THIS CLASS, CHECK SUPER + STA CCLASSCNT + LDY #CLASSMETHODTBL+1 + LDA (CCLASSPTR),Y + DEY + TAX + LDA (CCLASSPTR),Y + JSR HMEM_PTR + STA CCTBLPTR + STA TMPTR + STX CCTBLPTR+1 + STX TMPTR+1 + LDX CCLASSCNT +FINDMETHODLP: LDY #METHODNAME + LDA (TMPTR),Y + CMP CCLASSNAME + BNE NEXTMETHOD + INY + LDA (TMPTR),Y + CMP CCLASSNAME+1 + BNE NEXTMETHOD + INY + LDA (TMPTR),Y + CMP CCLASSDESC + BNE NEXTMETHOD + INY + LDA (TMPTR),Y + CMP CCLASSDESC+1 + BNE NEXTMETHOD + LDA TMPTR ; FOUND MATCH + SEC ; CALC OFFSET INTO TABLE + SBC CCTBLPTR + TAY + LDA TMPTR+1 + SBC CCTBLPTR+1 + TAX + TYA + LDY CCLASSINDEX + CLC + RTS +NEXTMETHOD: LDA TMPTR + CLC + ADC #METHODRECSZ + STA TMPTR + BCC :+ + INC TMPTR+1 +: DEX + BNE FINDMETHODLP +RESLVSUPRMETHD: LDY CCLASSSUPR ; SEARCH SUPERCLASS + BNE RESOLVE_METHOD +.IF 0 + LDY CCLASSINDEX + JSR CLASS_STRING + JSR PRHSTR + PSTR ":" +; PSTR "METHOD " + LDA CCLASSNAME + LDX CCLASSNAME+1 + JSR PRHSTR + LDA CCLASSDESC + LDX CCLASSDESC+1 + JSR PRHSTR + PSTRLN " UNRESOLVED" + .IMPORT KBWAIT + JSR KBWAIT +.ENDIF + SEC ; OUT OF SUPERCLASSES + RTS +;* +;* RETURN POINTER TO METHOD GIVEN INDECES +;* ENTRY: AX = METHOD OFFSET +;* Y = CLASS INDEX +;* EXIT: AX = METHOD POINTER +;* +CLASS_METHODPTR: STA CCTBLOFST + STX CCTBLOFST+1 + AUXZP_ACCESS_ON + LDA HCLASS_TBLL,Y + LDX HCLASS_TBLH,Y + AUXZP_ACCESS_OFF + JSR HMEM_PTR + STA CCLASSPTR + STX CCLASSPTR+1 + LDY #CLASSMETHODTBL+1 + LDA (CCLASSPTR),Y + DEY + TAX + LDA (CCLASSPTR),Y + JSR HMEM_PTR + CLC + ADC CCTBLOFST + TAY + TXA + ADC CCTBLOFST+1 + TAX + TYA + RTS +;* +;* LOCK CLASS METHOD AND RETURN POINTER +;* JUST LIKE CLASS_METHODPTR, BUT LOCK MEMORY +;* ENTRY: AX = METHOD OFFSET +;* Y = CLASS INDEX +;* EXIT: AX = METHOD POINTER +;* +CLASS_LOCKMETHOD: STA CCTBLOFST + STX CCTBLOFST+1 + AUXZP_ACCESS_ON + LDA HCLASS_TBLL,Y + LDX HCLASS_TBLH,Y + AUXZP_ACCESS_OFF + JSR HMEM_PTR + STA CCLASSPTR + STX CCLASSPTR+1 + LDY #CLASSMETHODTBL+1 + LDA (CCLASSPTR),Y + DEY + TAX + LDA (CCLASSPTR),Y + JSR HMEM_LOCK + CLC + ADC CCTBLOFST + TAY + TXA + ADC CCTBLOFST+1 + TAX + TYA + RTS +;* +;* UNLOCK METHOD, CALL AFTER DONE WITH ABOVE +;* ENTRY: Y = CLASSINDEX +;* +CLASS_UNLOCKMETHOD: AUXZP_ACCESS_ON + LDA HCLASS_TBLL,Y + LDX HCLASS_TBLH,Y + AUXZP_ACCESS_OFF + JSR HMEM_PTR + STA CCLASSPTR + STX CCLASSPTR+1 + LDY #CLASSMETHODTBL+1 + LDA (CCLASSPTR),Y + DEY + TAX + LDA (CCLASSPTR),Y + JMP HMEM_UNLOCK +;* +;* FIND A FIELD GIVEN CLASS INDEX AND DESCRIPTION +;* ENTRY: Y = CLASS INDEX +;* EXIT: AX = FIELD OFFSET +;* Y = CLASS INDEX (COULD BE SUPERCLASS) +;* C = 0 :: SUCCESS +;* C = 1 :: FAILURE +;* +RESOLVE_FIELD: STY CCLASSINDEX + AUXZP_ACCESS_ON + LDA HCLASS_TBLL,Y + LDX HCLASS_TBLH,Y + AUXZP_ACCESS_OFF + JSR HMEM_PTR + STA CCLASSPTR + STX CCLASSPTR+1 + LDY #CLASSSUPER + LDA (CCLASSPTR),Y + STA CCLASSSUPR + LDY #CLASSFIELDCNT + LDA (CCLASSPTR),Y + BEQ RESLVSUPRFIELD ; NO FIELDS FOR THIS CLASS, CHECK SUPER + STA CCLASSCNT + LDY #CLASSFIELDTBL+1 + LDA (CCLASSPTR),Y + DEY + TAX + LDA (CCLASSPTR),Y + JSR HMEM_PTR + STA CCTBLPTR + STA TMPTR + STX CCTBLPTR+1 + STX TMPTR+1 + LDX CCLASSCNT +FINDFIELDLP: LDY #FIELDNAME + LDA (TMPTR),Y + CMP CCLASSNAME + BNE NEXTFIELD + INY + LDA (TMPTR),Y + CMP CCLASSNAME+1 + BNE NEXTFIELD + INY + LDA (TMPTR),Y + CMP CCLASSDESC + BNE NEXTFIELD + INY + LDA (TMPTR),Y + CMP CCLASSDESC+1 + BNE NEXTFIELD + LDA TMPTR ; FOUND MATCH + SEC ; CALC OFFSET INTO TABLE + SBC CCTBLPTR + TAY + LDA TMPTR+1 + SBC CCTBLPTR+1 + TAX + TYA + LDY CCLASSINDEX + CLC + RTS +NEXTFIELD: LDA TMPTR + CLC + ADC #FIELDRECSZ + STA TMPTR + BCC :+ + INC TMPTR+1 +: DEX + BNE FINDFIELDLP +RESLVSUPRFIELD: LDY CCLASSSUPR ; SEARCH SUPERCLASS + BNE RESOLVE_FIELD + SEC ; OUT OF SUPERCLASSES + RTS +;* +;* RETURN POINTER TO FIELD GIVEN INDECES +;* ENTRY: AX = FIELD OFFSET +;* Y = CLASS INDEX +;* EXIT: AX = FIELD POINTER +;* +CLASS_FIELDPTR: STA CCTBLOFST + STX CCTBLOFST+1 + AUXZP_ACCESS_ON + LDA HCLASS_TBLL,Y + LDX HCLASS_TBLH,Y + AUXZP_ACCESS_OFF + JSR HMEM_PTR + STA CCLASSPTR + STX CCLASSPTR+1 + LDY #CLASSFIELDTBL+1 + LDA (CCLASSPTR),Y + DEY + TAX + LDA (CCLASSPTR),Y + JSR HMEM_PTR + CLC + ADC CCTBLOFST + TAY + TXA + ADC CCTBLOFST+1 + TAX + TYA + RTS +;* +;* LOCK CLASS AND RETURN POINTER +;* ENTRY: Y = CLASS INDEX +;* EXIT: AX = CLASS POINTER +;* +CLASS_LOCK: AUXZP_ACCESS_ON + LDA HCLASS_TBLL,Y + LDX HCLASS_TBLH,Y + AUXZP_ACCESS_OFF + JSR HMEM_LOCK + STA CCLASSPTR + STX CCLASSPTR+1 + LDY #CLASSLOCKCNT + LDA (CCLASSPTR),Y + CLC + ADC #$01 + STA (CCLASSPTR),Y + BCC :+ + INY +; TAX + LDA (CCLASSPTR),Y + ADC #$00 + STA (CCLASSPTR),Y +: LDA CCLASSPTR +; LDX CCLASSPTR+1 +: RTS +;* +;* UNLOCK METHOD, CALL AFTER DONE WITH ABOVE +;* ENTRY: Y = CLASSINDEX +;* +CLASS_UNLOCK: STY CCLASSINDEX + AUXZP_ACCESS_ON + LDA HCLASS_TBLL,Y + LDX HCLASS_TBLH,Y + AUXZP_ACCESS_OFF + JSR HMEM_PTR + STA CCLASSPTR + STX CCLASSPTR+1 + LDY #CLASSLOCKCNT + LDA (CCLASSPTR),Y + SEC + SBC #$01 + STA (CCLASSPTR),Y + INY + TAX + LDA (CCLASSPTR),Y + SBC #$00 + STA (CCLASSPTR),Y + BNE :- + CPX #$00 + BNE :- + LDY CCLASSINDEX + AUXZP_ACCESS_ON + LDA HCLASS_TBLL,Y + LDX HCLASS_TBLH,Y + AUXZP_ACCESS_OFF + JMP HMEM_UNLOCK +;* +;* RETURN CODE HANDLE FROM VIRTUAL METHOD TABLE +;* ENTRY: AX = VIRTUAL TABLE OFFSET +;* Y = CLASS INDEX +;* EXIT: AX = CODE HANDLE +;* +CLASS_VIRTCODE: STA CCTBLOFST + STX CCTBLOFST+1 + AUXZP_ACCESS_ON + LDA HCLASS_TBLL,Y + LDX HCLASS_TBLH,Y + AUXZP_ACCESS_OFF + JSR HMEM_PTR + STA CCLASSPTR + STX CCLASSPTR+1 + LDY #CLASSVIRTBL+1 + LDA (CCLASSPTR),Y + DEY + TAX + LDA (CCLASSPTR),Y + JSR HMEM_PTR + CLC + ADC CCTBLOFST + STA CCTBLPTR + TXA + ADC CCTBLOFST+1 + STA CCTBLPTR+1 + LDY #$01 + LDA (CCTBLPTR),Y + DEY + TAX + LDA (CCTBLPTR),Y + RTS +;* +;* DETERMINE IF A CLASS IS A SUBCLASS OF ANOTHER +;* !!! NEEDS TO CHECK INTERFACES AND ARRAYS !!! +;* ENTRY: A = SUB CLASS +;* Y = SUPER CLASS +;* EXIT: C = 0 :: A IS SUBCLASS OF Y +;* C = 1 :: A IS NOT SUBCLASS OF Y +;* +CLASS_OF: STY CCLASSINDEX +CLASSOFCHK: CMP CCLASSINDEX + BNE :+ + CLC + RTS +: TAY + AUXZP_ACCESS_ON + LDA HCLASS_TBLL,Y + LDX HCLASS_TBLH,Y + AUXZP_ACCESS_OFF + JSR HMEM_PTR + STA CCLASSPTR + STX CCLASSPTR+1 + LDY #CLASSSUPER + LDA (CCLASSPTR),Y + BNE CLASSOFCHK + SEC + RTS diff --git a/src/classload.s b/src/classload.s new file mode 100755 index 0000000..ff9ae57 --- /dev/null +++ b/src/classload.s @@ -0,0 +1,1931 @@ +;* +;* JAVA CLASS LOADER FOR 6502/DVM +;* + .INCLUDE "global.inc" + .INCLUDE "class.inc" + .INCLUDE "dvm.inc" + .IMPORT INIT_START,INIT_END + .IMPORT PRBYTE,COUT,CROUT,PRNTAX,PRHSTR,PRHSTRLN,PRHEX + .IMPORT PUTS,PUTSLN,PRSTR,PRSTRLN,KBWAIT,MEMSRC,MEMDST,MEMCPY,MEMCLR,MUL_FIELDRECSZ,MUL_METHODRECSZ + .IMPORT FILE_OPEN,FILE_SETBUFFER,FILE_READ,FILE_CLOSE,PREFIX_GET + .IMPORT HMEM_ALLOC,HMEM_ALLOC_CODE,HMEM_ALLOC_FIXED,HMEM_FREE,HMEM_CLR + .IMPORT HMEM_PTR,HMEM_LOCK,HMEM_UNLOCK,HMEM_REF_INC,HMEM_REF_DEC + .IMPORT HSTR_HASH,STR_HASH,HSTRPL_ADD,HSTRPL_DEL + .IMPORT HMEM_DUMP + .IMPORT HCLASS_NAME,HCLASS_INDEX,HCLASS_HNDL,HCLASS_ADD,CLASS_STRING + .IMPORT CLASS_MATCH_NAME,CLASS_MATCH_DESC,RESOLVE_METHOD,CLASS_METHODPTR,SCANDESCPARMS + .IMPORT ASYNC_STATIC + .IMPORT CODECPY,HCODE_ACCESS,HCODE_UNACCESS,HCODE_ALLOC + .IMPORT HCODE_ISBYTECODE,HCODE_SETSTACK,HCODE_SETLOCALS,HCODE_SETCLASS,HCODE_SETOFFSET,HCODE_SETHEXCEPT,HCODE_SETEXCEPTLEN + .IMPORT THROW_INTERNALERR,THROW_SYSEXCEPTN,CURRENTEXCEPTN + .EXPORT LOADCLASS_INIT,LOADCLASS_MEM,LOADCLASS_FILE,CLASSPREFIX + .EXPORT HMAINNAMESTR,HMAINDESCSTR,HRUNNAMESTR,HFINALNAMESTR,HVOIDDESCSTR + +.MACRO PERR_DVM MSG +.IFDEF DEBUG + DVM_END + PERR MSG + DVM_BEGIN +.ENDIF +.ENDMACRO +.MACRO PLAX + PLA + TAY + PLA + TAX + TYA +.ENDMACRO +.MACRO PHAX + TAY + TXA + PHA + TYA + PHA +.ENDMACRO + .SEGMENT "INIT" +;* +;* ADD STRING CONSTANTS USED FOR CLASS LOADING INTO STRING POOL. +;* NO ADDITIONAL SPACE WILL BE ALLOCATED FOR MATCHES IN THE CONSTANT POOL. +;* +LOADCLASS_INIT: LDA #CODESTR + JSR HSTRPL_ADD + STA HCODESTR+2 ; POKE RIGHT INTO CODE + STX HCODESTR+1 + LDA #CONSTVALSTR + JSR HSTRPL_ADD + STA HCONSTVALSTR+2 + STX HCONSTVALSTR+1 + LDA #NATIVESTR + JSR HSTRPL_ADD + STA HNATIVESTR+2 + STX HNATIVESTR+1 + LDA #MAINNAMESTR + JSR HSTRPL_ADD + STA HMAINNAMESTR + STX HMAINNAMESTR+1 + LDA #MAINDESCSTR + JSR HSTRPL_ADD + STA HMAINDESCSTR + STX HMAINDESCSTR+1 + LDA #RUNNAMESTR + JSR HSTRPL_ADD + STA HRUNNAMESTR + STX HRUNNAMESTR+1 + LDA #CLINITNAMESTR + JSR HSTRPL_ADD + STA CLINIT+1 + STX CLINIT+3 + LDA #FINALNAMESTR + JSR HSTRPL_ADD + STA HFINALNAMESTR + STX HFINALNAMESTR+1 + LDA # AND SHARE DESC + LDX #>VOIDDESCSTR + JSR HSTRPL_ADD + STA HVOIDDESCSTR + STX HVOIDDESCSTR+1 + LDA #BOOLSTR + JSR HSTRPL_ADD + STA HBOOLSTR+2 + STX HBOOLSTR+1 + LDA #BYTESTR + JSR HSTRPL_ADD + STA HBYTESTR+2 + STX HBYTESTR+1 + LDA #CHARSTR + JSR HSTRPL_ADD + STA HCHARSTR+2 + STX HCHARSTR+1 + LDA #SHORTSTR + JSR HSTRPL_ADD + STA HSHORTSTR+2 + STX HSHORTSTR+1 + LDA #INTSTR + JSR HSTRPL_ADD + STA HINTSTR+2 + STX HINTSTR+1 + LDA #FLOATSTR + JSR HSTRPL_ADD + STA HFLOATSTR+2 + STX HFLOATSTR+1 + LDA #LONGSTR + JSR HSTRPL_ADD + STA HLONGSTR+2 + STX HLONGSTR+1 + LDA #DOUBLESTR + JSR HSTRPL_ADD + STA HDOUBLESTR+2 + STX HDOUBLESTR+1 + LDA #CLASSPREFIX + JSR PREFIX_GET +.IFDEF DEBUG_LOAD + JSR PUTS + .ASCIIZ "CLASS LOAD PATH:" + LDA #CLASSPREFIX + JSR PRSTRLN +.ENDIF + LDA #LOADCLASS_FILE + STA LINK_CLASSLOAD+1 +LC_DVM_SIZE EQU LC_DVM_END-LC_DVM_BEGIN + LDA #LC_DVM_BEGIN + JSR MEMSRC + LDA #<(LC_DVM_SIZE) + LDX #>(LC_DVM_SIZE) + LDY #$01 + JSR HMEM_ALLOC + BCC :+ + JSR PUTS + .ASCIIZ "ALLOC LOADCLASS_DVM MEMORY FAILED" + BRK +: STA HLOADCLASSPROC + STX HLOADCLASSPROC+1 + JSR HMEM_PTR + JSR MEMDST + LDA #<(LC_DVM_SIZE) + LDX #>(LC_DVM_SIZE) + JSR MEMCPY ; RELOCATE LOADCLASS_DVM TO MEMORY BLOCK + RTS +LC_DVM_BEGIN: +;***************************************************************************** +;* +;* BEGINNING OF RELOCATED LOADCLASS CODE. ALL 6502 CODE MUST BE RELATIVE. +;* +;***************************************************************************** +; DVM_BEGIN + DUPW ; CHECK FOR NULL HANDLE PASSED IN + BRNZW FILELOAD + POPB + STB CLBUFFOFST + LDCW READBUFF_MEM + STW READBUFFPROC + LDCW CURRENTOFST_MEM + STW CURRENTOFSTPROC + LDCW RELEASEBUFF_MEM + STW RELEASEBUFFPROC + JUMP MEMLOAD +FILELOAD: DVM_END + PLA + TAX + PLA + JSR HMEM_PTR + STA LDPTR + STX LDPTR+1 + LDX #$00 ; COPY CLASS LOAD PREFIX + LDY #$01 + LDA (LDPTR),Y + AND #$7F + CMP #'/' + BEQ :+ +COPYCLASSPREFIX: CPX CLASSPREFIX + BEQ :+ + INX + LDA CLASSPREFIX,X + STA CLASSFILE,X + BNE COPYCLASSPREFIX +: STX CLASSFILE + LDY #$00 + LDA (LDPTR),Y + CMP #16 ; CLAMP BASENAME TO 16 CHARACTERS + BCC BASENAMEOK + STA TMP + TAY +: LDA (LDPTR),Y + AND #$7F + CMP #'/' ; CHECK FOR DIR SEPARATOR + BEQ :+ + DEY + BNE :- +: LDA TMP + STY TMP + LDY #$00 + SEC + SBC TMP + CMP #16 + BCS :+ + LDA (LDPTR),Y + BNE BASENAMEOK +: LDA TMP + CLC + ADC #15 +BASENAMEOK: ADC CLASSFILE + STA CLASSFILE ; SAVE FILENAME LENGTH +COPYCLASSNAME: INY + LDA (LDPTR),Y + INX + STA CLASSFILE,X + CPX CLASSFILE + BNE COPYCLASSNAME +.IFDEF DEBUG_LOAD + .IMPORT KBWAIT + PSTR "LOADING CLASS FILE:" + LDA #CLASSFILE + JSR PRSTRLN +; JSR KBWAIT +.ENDIF + LDA #$00 ; SIZE OF DATA BUFFER + LDX #$01 + LDY #$00 + JSR HMEM_ALLOC + STA HCLASSFILEBUFF + STX HCLASSFILEBUFF+1 + JSR HMEM_LOCK + STA CLBUFFPTR + STX CLBUFFPTR+1 + LDA #CLASSFILE + LDY #>CLASSFILE_IO_BUFF ; CLASSLOAD SYSTEM I/O BUFFER + JSR FILE_OPEN + BCC :+ +.IFDEF DEBUG_LOAD + JSR PRBYTE + PSTR " - ERROR OPENING FILE: " +.ENDIF + JMP FILECLASS_ERR +: STY CLREFNUM + LDY #$00 + STY CLBUFFOFST + STY CLBUFFPAGE + JSR READBUFF_FILE + DVM_BEGIN + LDCW READBUFF_FILE + STW READBUFFPROC + LDCW CURRENTOFST_FILE + STW CURRENTOFSTPROC + LDCW RELEASEBUFF_FILE + STW RELEASEBUFFPROC +MEMLOAD: +.IFDEF DEBUG_LOAD + LDCW $6969 ; STACK MARKER +.ENDIF +.IFDEF DEBUG_DVM + DVM_END + TSX + STX STACKCHK + DVM_BEGIN +.ENDIF +.IFDEF DEBUG_LOAD + DVM_END + PSTR "LOADCLASS..." +; JSR KBWAIT + PSTR "MAGIC: " + DVM_BEGIN +.ENDIF + CALL READWORD ; VERIFY CLASS HEADER +.IFDEF DEBUG_LOAD + DUPW + DVM_END + PLA + TAX + PLA + JSR PRNTAX + DVM_BEGIN +.ENDIF + LDCW $CAFE + BRNEQW BADMAGIC + CALL READWORD +.IFDEF DEBUG_LOAD + DUPW + DVM_END + PLA + TAX + PLA + JSR PRNTAX + DVM_BEGIN +.ENDIF + LDCW $BABE + BREQUW :+ +BADMAGIC: PERR_DVM "BAD MAGIC" + JUMP LOADCLASS_ERR +: +.IFDEF DEBUG_LOAD + DVM_END + JSR CROUT +; JSR KBWAIT + PSTR "VERSION: " + DVM_BEGIN +.ENDIF + CALL READWORD ; READ VERSION + CALL READWORD +.IFDEF DEBUG_LOAD + LD0W + SWAPW + SWAPB + CALL_02 PRNTAX + POPB + LDCB '.' + CALL_02 COUT + POP2W + LD0W + SWAPW + SWAPB + CALL_02 PRNTAX + CALL_02 CROUT +.ENDIF + POP2W +; +; READ CONSTANT POOL +; + LD0W + LDCW $0100 + CALL_02 HMEM_ALLOC + STW HREADSTRBUFF ; ALLOC TEMP STRING BUFFER + POPW + CALL READWORD +.IFDEF DEBUG_LOAD + DUPW + DVM_END + PSTR "CONST POOL COUNT: " + PLA + TAX + PLA + JSR PRNTAX + JSR CROUT +; JSR KBWAIT + DVM_BEGIN +.ENDIF + DECRW + DUPW ; SAVE FOR A LITTLE LATER ON... + DUPW + STZPW LDCNT + DUPW + SHLW ; CALC CONSTPLRECSZ - MUL BY 5 + SHLW + ADDW + LDCW CLASSBASESZ ; ADD STATIC CLASS STRUCTURE SIZE + ADDW + LD1W ; LOAD STATUS/Y + SWAPW + CALL_02 HMEM_ALLOC ; ALLOCATE CLASS STRUCTURE + CALL_02 HMEM_CLR ; CLEAR IT + DUPW + STW HCLASSLD + CALL_02 HMEM_LOCK ; LOCK CLASS STRUCTURE IN PLACE + DUPW + STZPW CLASSLDPTR + LDCW CLASSBASESZ ; CALC OFFSET IN CLASS TO CONST POOL + ADDW + STZPW LDPTR + POPW ; DROP STATUS AND YREG + STPW (CLASSLDPTR), CLASSCONSTCNT ; SAVE CONST COUNT (ON STACK FRM EARLIER) IN CLASS STRUCTURE +LOADCONSTPL: CALL READBYTE ; READ TYPE +.IFDEF DEBUG_LOAD + DUPB + DVM_END + PLA + JSR PRBYTE + LDA #' ' + JSR COUT + DVM_BEGIN +.ENDIF + DUPB + STPB (LDPTR), 0 ; AND STORE IT + SWTCHB 10 + CASEB CONST_UTF8, LDUTF8 ; CONST UTF8 + CASEB CONST_STRING, LDCONST16 ; STRING OBJECT + CASEB CONST_INTEGER, LDCONST32 ; CONST INTEGER + CASEB CONST_FLOAT, LDCONST32 ; CONST FLOAT + CASEB CONST_FIELDREF, LDCONST32 ; FIELD REF + CASEB CONST_METHDREF, LDCONST32 ; METHOD REF + CASEB CONST_IFACEMETHDREF, LDCONST32 ; INTERFACE METHOD REF + CASEB CONST_NAMETYPE, LDCONST32 ; NAME AND TYPE + CASEB CONST_CLASS, LDCONST16 ; CLASS + CASEB CONST_LONG, LDCONST64 ; 64 BIT LONG + PERR_DVM "UNKOWN CONSTANT POOL TYPE" + JUMP LOADCLASS_ERR +LDUTF8: LD0W + LDW HREADSTRBUFF + CALL_02 HMEM_PTR + DUPW ; SAVE FOR HSTRPL_ADD LATER + STZPW DSTADDR + CALL READWORD ; READ STRING LENGTH + SWAPB + BRNZB STRINGTOOBIG ; CHECK MSB FOR 0 OR ITS TOO LONG +.IF 0 + DUPB + STPINCB (DSTADDR) + BRNCH :+ +READUTF8: CALL READBYTE +.IFDEF DEBUG_LOAD + DVM_END + PLA + PHA + JSR COUT + DVM_BEGIN +.ENDIF + STPINCB (DSTADDR) + DECRB +: DUPB + BRNZB READUTF8 + POPB ; DISCARD COUNT + CALL_02 HSTRPL_ADD ; ADD STRING TO POOL + SWAPB + STPW (LDPTR), 3 ; SAVE HANDLE IN LOWORD + STPB (LDPTR), 1 ; HASH INDEX IN HIWORD[0] + POPB + LDCB CL_STR + STPB (LDPTR), 2 ; CLASS INDEX IN HIWORD[1] +.ELSE + DVM_END + PLA + TAX + INX +READUTF8: LDY #$00 + STA (DSTADDR),Y + DEX + BEQ ADDUTF8 + INC DSTADDR + BNE :+ + INC DSTADDR+1 +: LDY CLBUFFOFST + LDA (CLBUFFPTR),Y +.IFDEF DEBUG_LOAD + PHA + TAY + TXA + PHA + TYA + JSR COUT + PLA + TAX + PLA +.ENDIF + INC CLBUFFOFST + BNE READUTF8 + PHA + TXA + PHA + JSR READBUFF + PLA + TAX + PLA + BNE READUTF8 +ADDUTF8: PLAX + JSR HSTRPL_ADD ; ADD STRING TO POOL + PHA + TYA + LDY #$01 + STA (LDPTR),Y + INY + LDA #CL_STR + STA (LDPTR),Y + INY + TXA + STA (LDPTR),Y + INY + PLA + STA (LDPTR),Y + PLA + PLA + DVM_BEGIN +.ENDIF + BRNCH NEXTCONSTPL +STRINGTOOBIG: PERR_DVM "STRING TOO LARGE" + JUMP LOADCLASS_ERR +LDCONST64: CALL READWORD ; SKIP HI 32 BITS + CALL READWORD + POP2W + LDZPW LDPTR + LDCW CONSTPLRECSZ + ADDW + STZPW LDPTR + LDZPW LDCNT + DECRW + STZPW LDCNT +LDCONST32: CALL READWORD + SWAPB + STPW (LDPTR), 1 +LDCONST16: CALL READWORD + SWAPB + STPW (LDPTR), 3 +NEXTCONSTPL: LDZPW LDPTR + LDCW CONSTPLRECSZ + ADDW + STZPW LDPTR +.IFDEF DEBUG_LOAD + DVM_END + JSR CROUT + DVM_BEGIN +.ENDIF +.IFDEF DEBUG_DVM + DVM_END + TSX + CPX STACKCHK + BEQ :+ + PERR "STACK CHECK FAIL DURING LOAD CONST POOL" + BRK +: DVM_BEGIN +.ENDIF + DECJNZW LDCNT, LOADCONSTPL +.IFDEF DEBUG_DVM + DVM_END + TSX + CPX STACKCHK + BEQ :+ + PERR "STACK CHECK FAIL AFTER LOAD CONST POOL" + BRK +: DVM_BEGIN +.ENDIF + LD0W + LDW HREADSTRBUFF + CALL_02 HMEM_FREE ; FREE TEMP STRING BUFFER + POP2W +; +; LOAD ACCESS FLAGS +; +LOADACCFLGS: CALL READWORD + STPW (CLASSLDPTR), CLASSACCESS +; +; LOAD CLASS/SUPERCLASS +; + CALL READWORD + CALL LDCONST +.IFDEF DEBUG_LOAD + LDPB (CLDPTR), 0 + LDCB $07 ; CHECK FOR CLASS TYPE + BREQUB :+ + PERR_DVM "BAD CLASS CONST TYPE" + JUMP LOADCLASS_ERR +: +.ENDIF + CALL LDCONST +.IFDEF DEBUG_LOAD + LDPB (CLDPTR), 0 + LDCB $01 ; CHECK FOR UTF8 TYPE + BREQUB :+ + PERR_DVM "BAD CLASS STR CONST TYPE" + JUMP LOADCLASS_ERR +: +.ENDIF + STPW (CLASSLDPTR), CLASSTHIS + CALL READWORD ; GET SUPERCLASS + DUPW + BRZW SETSUPER ; THIS BETTER BE CLASS OBJECT + CALL LDCONST +.IFDEF DEBUG_LOAD + LDPB (CLDPTR), 0 + LDCB $07 ; CHECK FOR CLASS TYPE + BREQUB :+ + PERR_DVM "BAD SUPERCLASS CONST TYPE" + JUMP LOADCLASS_ERR +: +.ENDIF + CALL LDCONST +.IFDEF DEBUG_LOAD + LDPB (CLDPTR), 0 + LDCB $01 ; CHECK FOR UTF8 TYPE + BREQUB :+ + PERR_DVM "BAD SUPERCLASS STR CONST TYPE" + JUMP LOADCLASS_ERR +: +.ENDIF +SETSUPER: STW SUPERCLASS +; +; LOAD INTERFACES +; + CALL READWORD + SWAPB + BRZB :+ + PERR_DVM "INTERFACE COUNT > 255" + JUMP LOADCLASS_ERR +: DUPB + STPB (CLASSLDPTR), CLASSIFACECNT + DUPB + STZPB LDCNT + BRZB LOADFIELDCNT +LOADIFACE: CALL READWORD +.IFDEF DEBUG_LOAD + CALL LDCONST ; GET STRING HANDLE + CALL LDCONST + LDPB (CLDPTR), 0 + DUPW + LD1B + BREQUB :+ ; READ UTF8 + PERR_DVM "BAD TYPE IN LOAD IFACES" +: LD0W + SWAPW + CALL_02 PRHSTR + POPW +.ENDIF + POPW ; DISCARD + DECJNZB LDCNT, LOADIFACE +.IFDEF DEBUG_DVM + DVM_END + TSX + CPX STACKCHK + BEQ :+ + PERR "STACK CHECK FAIL AFTER LOAD IFACE" + BRK +: DVM_BEGIN +.ENDIF +; +; LOAD FIELDS +; +LOADFIELDCNT: CALL READWORD + SWAPB + BRZB :+ + PERR_DVM "FIELD COUNT > 255" + JUMP LOADCLASS_ERR +: DUPB + STPB (CLASSLDPTR), CLASSFIELDCNT + DUPB + STZPB LDCNT + BRNZB :+ + JUMP LOADMETHODCNT +: +.IFDEF DEBUG_LOAD + DVM_END + PSTR "FIELD COUNT: " + LDA LDCNT + JSR PRBYTE + JSR CROUT +; JSR KBWAIT + DVM_BEGIN +.ENDIF + LD1W + LDZPB LDCNT + ZEXTB + CALL_02 MUL_FIELDRECSZ ; FIELD RECORD SIZE + CALL_02 HMEM_ALLOC ; ALLOC THE FIELD TABLE + DUPW + STPW (CLASSLDPTR), CLASSFIELDTBL + CALL_02 HMEM_LOCK ; LOCK FIELD TABLE IN MEMORY + STZPW LDPTR + POPW +LOADFIELD: CALL READWORD ; ACCESS FLAGS + STPB (LDPTR), FIELDACCESS + POPB ; DISCARD MSB +.IFDEF DEBUG_LOAD + LDPB (LDPTR), FIELDACCESS + DVM_END + PLA + JSR PRBYTE + LDA #' ' + JSR COUT + DVM_BEGIN +.ENDIF + CALL READWORD ; NAME STRING INDEX + CALL LDCONST ; GET STRING HANDLE + CALL READWORD ; DESCRIPTION STRING INDEX + CALL LDCONST ; GET STRING HANDLE + DUPW +HBOOLSTR: LDCW 0 + BRNEQW :+ + LDCB T_BOOLEAN + BRNCH LDFLDTYPE +: DUPW +HBYTESTR: LDCW 0 + BRNEQW :+ + LDCB T_BYTE + BRNCH LDFLDTYPE +: DUPW +HCHARSTR: LDCW 0 + BRNEQW :+ + LDCB T_CHAR + BRNCH LDFLDTYPE +: DUPW +HSHORTSTR: LDCW 0 + BRNEQW :+ + LDCB T_SHORT + BRNCH LDFLDTYPE +: DUPW +HINTSTR: LDCW 0 + BRNEQW :+ + LDCB T_INT + BRNCH LDFLDTYPE +: DUPW +HFLOATSTR: LDCW 0 + BRNEQW :+ + LDCB T_FLOAT + BRNCH LDFLDTYPE +: DUPW +HLONGSTR: LDCW 0 + BREQUW BADTYPE + DUPW +HDOUBLESTR: LDCW 0 + BRNEQW :+ +BADTYPE: PERR_DVM "UNIMPLEMENTED TYPE" + JUMP LOADCLASS_ERR +: LDCB $80|T_REF +LDFLDTYPE: STPB (LDPTR), FIELDTYPE + STPW (LDPTR), FIELDDESC + STPW (LDPTR), FIELDNAME +.IFDEF DEBUG_LOAD + DVM_END + LDY #FIELDNAME+1 + LDA (LDPTR),Y + DEY + TAX + LDA (LDPTR),Y + JSR HMEM_PTR + JSR PRSTR + LDA #' ' + JSR COUT + LDY #FIELDDESC+1 + LDA (LDPTR),Y + DEY + TAX + LDA (LDPTR),Y + JSR HMEM_PTR + JSR PRSTR + LDA #' ' + JSR COUT + DVM_BEGIN +.ENDIF + LDPB (LDPTR), FIELDACCESS + LDCB $08 + ANDB ; CHECK FOR STATIC FIELD + BRZB :+ + LD0W + LD0W + STPW (LDPTR), FIELDSTATICVAL ; ZERO OUT STATIC FIELD + STPW (LDPTR), FIELDSTATICVAL+2 + BRNCH LDFLDATRCNT +: LDPW (CLASSLDPTR), CLASSINSTSIZE ; SAVE OFFSET TO INSTANCE FIELD + STPW (LDPTR), FIELDINSTOFFSET + LDPB (LDPTR), FIELDTYPE ; CONVERT TYPE TO SIZE + LD3B + ANDB ; CLEVERLY MASK SIZE INDEX BITS + ZEXTB + LDCW TYPE2SIZE ; ADDRESS OF TYPE2SIZE + ADDW ; ADD TYPE INDEX + LDINDB ; LOAD TYPE SIZE +.IFDEF DEBUG_LOAD + DVM_END + LDA #'#' + JSR COUT + PLA + PHA + JSR PRBYTE + LDA #' ' + JSR COUT + DVM_BEGIN +.ENDIF + ZEXTB + LDPW (CLASSLDPTR), CLASSINSTSIZE ; INCREMENT INSTANCE SIZE + ADDW + STPW (CLASSLDPTR), CLASSINSTSIZE +LDFLDATRCNT: CALL READWORD ; FIELD ATTRIB COUNT + SWAPB + BRZB :+ + PERR_DVM "TOO MANY METHOD ATTRIBUTES" + JUMP LOADCLASS_ERR +: DUPB + STZPB ACNT + BRZB NEXTFIELD +LDFLDATR: CALL READWORD ; FIELD ATTRIB NAME + CALL LDCONST +.IFDEF DEBUG_LOAD + DUPW + DVM_END + PLAX + JSR HMEM_PTR + JSR PRSTR + DVM_BEGIN +.ENDIF +HCONSTVALSTR: LDCW 0 + BREQUW :+ + CALL SKIPATTRIB + BRNCH NEXTFLDATR +: + CALL READWORD ; FIELD ATTRIB LENL - THIS BETTER BE 2 + LD2W + BRNEQW :+ + PERR_DVM "BAD CONSTVAL" + JUMP LOADCLASS_ERR +: CALL READWORD ; FIELD ATTRIB LENH + POPW + CALL READWORD ; FIELD ATTRIB CONST INDEX + CALL LDCONST + STPW (LDPTR), FIELDSTATICVAL ; SAVE LOWORD CONSTANTVALUE IN STATIC FIELD + LDPW (CLDPTR), 1 + SWAPB + STPW (LDPTR), FIELDSTATICVAL+2 ; SAVE HIWORD CONSTANTVALUE IN STATIC FIELD +.IFDEF DEBUG_LOAD + DVM_END + LDA #' ' + JSR COUT + LDY #FIELDSTATICVAL+2 + LDA (LDPTR),Y + INY + TAX + LDA (LDPTR),Y + JSR PRNTAX + LDY #FIELDSTATICVAL + LDA (LDPTR),Y + INY + TAX + LDA (LDPTR),Y + JSR PRNTAX + DVM_BEGIN +.ENDIF +NEXTFLDATR: DECJNZB ACNT, LDFLDATR +NEXTFIELD: +.IFDEF DEBUG_LOAD + DVM_END + JSR CROUT + DVM_BEGIN +.ENDIF + LDZPW LDPTR + LDCW FIELDRECSZ ; NEXT FIELD RECORD + ADDW + STZPW LDPTR + DECJNZB LDCNT, LOADFIELD +.IFDEF DEBUG_DVM + DVM_END + TSX + CPX STACKCHK + BEQ :+ + PERR "STACK CHECK FAIL AFTER LOAD FIELDS" + BRK +: DVM_BEGIN +.ENDIF +; +; LOAD METHODS INTO TABLE. STATIC METHODS HAVE A CODE HANDLE DIRECTLY IN THE ENTRY, VIRTUAL +; METHODS HAVE AN OFFSET INTO THE VIRTUAL TABLE TO LOOK UP THE CODE HANDLE +; +LOADMETHODCNT: CALL READWORD + SWAPB + BRZB :+ + PERR_DVM "METHOD COUNT > 255" + JUMP LOADCLASS_ERR +: DUPB + STPB (CLASSLDPTR), CLASSMETHODCNT + DUPB + STZPB LDCNT + BRNZB :+ + JUMP RESOLVESUPER +: DVM_END +.IFDEF DEBUG_LOAD + PSTR "METHOD COUNT: " + LDA LDCNT + JSR PRBYTE + JSR CROUT +; JSR KBWAIT +.ENDIF + LDA LDCNT + LDX #$00 + JSR MUL_METHODRECSZ ; 20 BYTES PER METHOD RECORD + LDY #$01 + JSR HMEM_ALLOC ; ALLOC THE METHOD TABLE + LDY #CLASSMETHODTBL + STA (CLASSLDPTR),Y + INY + PHA + TXA + STA (CLASSLDPTR),Y + PLA + JSR HMEM_LOCK ; LOCK METHOD TABLE IN MEMORY + STA LDPTR + STX LDPTR+1 + DVM_BEGIN +LOADMETHOD: CALL READWORD ; ACCESS FLAGS + STPW (LDPTR), METHODACCESS +.IFDEF DEBUG_LOAD + DVM_END + LDY #METHODACCESS + LDA (LDPTR),Y + TAX + INY + LDA (LDPTR),Y + JSR PRNTAX + DVM_BEGIN +.ENDIF + CALL READWORD ; NAME STRING INDEX + CALL LDCONST ; GET STRING HANDLE + STPW (LDPTR), METHODNAME +.IFDEF DEBUG_LOAD + DVM_END + LDA #'-' + JSR COUT + LDY #METHODNAME+1 + LDA (LDPTR),Y + DEY + TAX + LDA (LDPTR),Y + JSR PRHSTR + LDA #' ' + JSR COUT + DVM_BEGIN +.ENDIF + LD0W + CALL READWORD ; DESCRIPTION STRING INDEX + CALL LDCONST ; GET STRING HANDLE + DUPW + STPW (LDPTR), METHODDESC +.IFDEF DEBUG_LOAD + DVM_END + LDY #METHODDESC+1 + LDA (LDPTR),Y + DEY + TAX + LDA (LDPTR),Y + JSR PRHSTR + LDA #' ' + JSR COUT + DVM_BEGIN +.ENDIF + CALL_02 SCANDESCPARMS +.IFDEF DEBUG_LOAD + DVM_END + PLA + PHA + JSR PRBYTE + PSTR " PARAM BYTES " + DVM_BEGIN +.ENDIF + STPB (LDPTR), METHODPARAMS + POPB + POPW + CALL READWORD ; METHOD ATTRIB COUNT + SWAPB + BRZB :+ + PERR_DVM "TOO MANY METHOD ATTRIBUTES" + JUMP LOADCLASS_ERR +: DUPB + STZPB ACNT + BRNZB LDMTHDATR + JUMP NEXTMETHOD +LDMTHDATR: CALL READWORD ; METHOD ATTRIB NAME + CALL LDCONST +.IFDEF DEBUG_LOAD + DUPW + DVM_END + PLAX + JSR HMEM_PTR + JSR PRSTR + DVM_BEGIN +.ENDIF + DUPW +HCODESTR: LDCW 0 + BREQUW LDCODE + DUPW +HNATIVESTR: LDCW 0 + BREQUW CHKNATV + POPW + CALL SKIPATTRIB ; DEFAULT: SKIP ATTRIB + JUMP NEXTMTHDATR +CHKNATV: LDPB (LDPTR), METHODACCESS+1 + LD1B + ANDB ; CHECK FOR NATIVE FLAG + BRNZB LDCODE + PERR_DVM "MISSING NATIVE ACCESS FLAG FOR 6502 METHOD" + JUMP LOADCLASS_ERR +; +; LOAD JAVA BYTECODE/NATIVE 6502 CODE SEGMENT FROM FILE/MEMORY INTO METHOD +; +LDCODE: POPW + CALL READWORD ; CODE ATTRIB LENH + CALL READWORD ; CODE ATTRIB LENL + POP2W + CALL READWORD ; READ CODE BLOCK + SWAPB ; CODE MAX STACK + BRZB :+ + PERR_DVM "METHOD STACK OVERFLOW" + JUMP LOADCLASS_ERR +: STB MAXSTACK ; SAVE TEMP + CALL READWORD ; CODE MAX LOCALS + SWAPB + BRZB :+ ; MUST BE LESS THAN 256 + PERR_DVM "METHOD LOCALS OVERFLOW" + JUMP LOADCLASS_ERR +: STB MAXLOCALS + CALL READWORD ; CODE LENH + BRZW :+ + PERR_DVM "METHOD CODE SIZE OVERFLOW" + JUMP LOADCLASS_ERR +: CALL READWORD ; CODE LENL + STZPW CCNT + LDW CURRENTOFSTPROC ; GET CURRENT FILE OFFSET + CALLIND + STW CODEOFST + LDPB (LDPTR), METHODACCESS+1 + LD1B + ANDB ; CHECK FOR NATIVE FLAG + BRZB READBYTECODE + LD1W + LDZPW CCNT ; READ NATIVE CODE + CALL_02 HMEM_ALLOC ; ALLOCATE REGULAR MEMORY + DUPW + STPW (LDPTR), METHODSTATICODE + CALL_02 HMEM_PTR + STZPW DSTADDR + POPW + LDZPW CCNT + CALL READMEM ; COPY CODE FROM FILE BUFFER TO MEMORY BLOCK + CALL READWORD ; CODE EXCEPTION COUNT + BRNZW :+ + JUMP LDCODEATRCNT ; MUST BE ZERO FOR NATIVE +: PERR_DVM "NATIVE EXCEPTIONS NOT ALLOWED" + JUMP LOADCLASS_ERR +READBYTECODE: LD0B + LDPB (LDPTR), METHODACCESS + LDCB $20 ; MASK SYNCHRONIZED FLAG + ANDB + LDZPW CCNT + CALL_02 HCODE_ALLOC ; ALLOCATE CODE BLOCK + DUPW + STPW (LDPTR), METHODSTATICODE + CALL_02 HCODE_ACCESS ; SET THIS CODE BLOCK AS CURRENTLY ACCESSED + POP2W + LD0W + LDW CODEOFST + CALL_02 HCODE_SETOFFSET + POPB + LDB MAXSTACK + CALL_02 HCODE_SETSTACK + POPB + LDB MAXLOCALS + CALL_02 HCODE_SETLOCALS +.IFDEF DEBUG_LOAD + LD0W + LDCW '{' + CALL_02 COUT + POP2W +.ENDIF +.IF 0 +: POPB + CALL READBYTE + CALL_02 CODECPY ; COPY CODE INTO CODE BLOCK + DECJNZW CCNT, :- +.ELSE + DVM_END +RDBCLP: LDY CLBUFFOFST + LDA (CLBUFFPTR),Y + INC CLBUFFOFST + BNE :+ + PHA + JSR READBUFF + PLA +: JSR CODECPY + LDA CCNT + SEC + SBC #$01 + STA CCNT + LDA CCNT+1 + SBC #$00 + STA CCNT+1 + ORA CCNT + BNE RDBCLP + DVM_BEGIN +.ENDIF +.IFDEF DEBUG_LOAD + LD0W + LDCW '}' + CALL_02 COUT + POP2W +.ENDIF + POPW + CALL READWORD ; CODE EXCEPTION COUNT + DUPW + BRZW READCODEUNACC ; ZERO SIZE, SKIP LOAD OF EXCEPTIONS +.IFDEF DEBUG_LOAD + LD0W + LDCW '[' + CALL_02 COUT + POP2W +.ENDIF + DUP2W + CALL_02 HCODE_SETEXCEPTLEN + POP2W + SHLW ; MULTIPLY BY 8 TO GET SIZE + SHLW + SHLW + DUPW + STW CCNT + SWAPW + POPW + LD1W + SWAPW + CALL_02 HMEM_ALLOC ; ALLOCATE EXCEPTION BLOCK + DUP2W + CALL_02 HCODE_SETHEXCEPT + POP2W + CALL_02 HMEM_PTR + STZPW DSTADDR + LDW CCNT + CALL READMEM ; COPY EXCEPT TABLE FROM FILE BUFFER TO MEMORY BLOCK +.IFDEF DEBUG_LOAD + LD0W + LDCW ']' + CALL_02 COUT + POP2W +.ENDIF + LD0W +READCODEUNACC: CALL_02 HCODE_UNACCESS ; CLEAR CURRENT CODE ACCESS + POP2W +LDCODEATRCNT: CALL READWORD ; CODE ATTRIB COUNT + SWAPB + BRZB :+ + PERR_DVM "TOO MANY CODE ATTRIBS" + JUMP LOADCLASS_ERR +: DUPB + STZPB ACNT+1 + BRZB NEXTMTHDATR +LDCODEATR: CALL READWORD ; SKIP ATTRIB NAME + POPW + CALL SKIPATTRIB ; SKIP ATTRIB DATA +NEXTCODEATR: DECJNZB ACNT+1, LDCODEATR +NEXTMTHDATR: DECJNZB ACNT, LDMTHDATR +NEXTMETHOD: +.IFDEF DEBUG_LOAD + LD0W + LD0W + CALL_02 CROUT + POP2W +.ENDIF + LDZPW LDPTR + LDCW METHODRECSZ ; NEXT METHOD RECORD + ADDW + STZPW LDPTR + DECJNZB LDCNT, LOADMETHOD +.IFDEF DEBUG_DVM + DVM_END + TSX + CPX STACKCHK + BEQ :+ + PERR "STACK CHECK FAIL AFTER LOAD METHODS" + BRK +: DVM_BEGIN +.ENDIF +; +; FINISHED LOADING CLASS FILE. NOW RESOLVE OUTSANDING FIXUPS. +; +RESOLVESUPER: DVM_END + JSR RELEASEBUFF + LDY #$00 + LDA SUPERCLASS ; RESOLVE SUPERCLASS + LDX SUPERCLASS+1 + BEQ ALLDEPENDS + JSR HCLASS_NAME + BCC ALLDEPENDS ; ALL DEPENDENCIES MET +LOADSUPERCLASS: LDA HCLASSLD ; SUPERCLASS NOT FOUND, LOAD IT + PHA + LDA HCLASSLD+1 + PHA + LDA SUPERCLASS ; RESOLVE SUPERCLASS + LDX SUPERCLASS+1 + JSR LOADCLASS_FILE ; LOAD THE SUPERCLASS + BCC :+ + PERR "ERROR LOADING SUPERCLASS" + PLA + PLA + SEC + RTS +: JSR HCLASS_HNDL ; GET INDEX TO SUPERCLASS + STY ISUPER + PLA ; RESTORE HANDLE TO LOADING CLASS + STA HCLASSLD+1 + TAX + PLA + STA HCLASSLD + JSR HMEM_PTR ; RESTORE POINTER TO LOADING CLASS + STA CLASSLDPTR + STX CLASSLDPTR+1 + LDY ISUPER +ALLDEPENDS: STY ISUPER + TYA ; SAVE SUPERCLASS INDEX + LDY #CLASSSUPER + STA (CLASSLDPTR),Y + LDA HCLASSLD ; ADD THIS ALMOST COMPETE CLASS TO DATABASE + LDX HCLASSLD+1 + JSR HCLASS_ADD + STY ICLASSLD +; +; GET POINTER TO SUPERCLASS +; +.IFDEF DEBUG_LOAD + PSTR "FIXUP METHOD/VTBL FOR CLASS:" + LDY ICLASSLD + JSR CLASS_STRING + JSR PRHSTRLN +; JSR KBWAIT +.ENDIF +.IFDEF DEBUG_DVM + TSX + STX STACKCHK +.ENDIF + DVM_BEGIN + LDB ISUPER +.IFDEF DEBUG_DVM + BRNZB :+ + JUMP VTBLINIT +: +.ELSE + BRZB VTBLINIT ; BETTER BE CLASS OBJECT +.ENDIF + LD0B + LDB ISUPER + LD0W + CALL_02 HCLASS_INDEX + CALL_02 HMEM_LOCK ; LOCK SUPERCLASS + STZPW SUPERPTR + POPW + LDPW (SUPERPTR), CLASSINSTSIZE ; GET SUPERCLASS' INSTANCE SIZE + DUPW + STW ENTRYOFFSET ; ADD THIS OFFSET TO INSTANCE SIZE AND FIELD INST OFFSETS + LDPW (CLASSLDPTR), CLASSINSTSIZE ; UPDATE INSTANCE SIZE + ADDW + STPW (CLASSLDPTR), CLASSINSTSIZE + LDPB (CLASSLDPTR), CLASSFIELDCNT +.IFDEF DEBUG_DVM + BRNZB :+ + JUMP VTBLINIT +: +.ELSE + BRZB VTBLINIT +.ENDIF + LDPB (CLASSLDPTR), CLASSFIELDCNT + STZPB LDCNT + LD0W + LDPW (CLASSLDPTR), CLASSFIELDTBL + CALL_02 HMEM_PTR ; STILL LOCKED FROM EARLIER + STZPW LDPTR + POPW +.IFDEF DEBUG_DVM + DVM_END + TSX + CPX STACKCHK + BEQ :+ + PERR "STACK CHECK FAIL AFTER SUPER SETUP" + BRK +: DVM_BEGIN +.ENDIF +; +; FIXUP FIELD OFFSETS +; +UPDATEFLDLP: LDPB (LDPTR), FIELDACCESS + LDCB $08 + ANDB ; CHECK FOR STATIC FIELD + BRNZB UPDATENXTFLD + LDPW (LDPTR), FIELDINSTOFFSET ; UPDATE FIELD INSTANCE OFFSET + LDW ENTRYOFFSET + ADDW + STPW (LDPTR), FIELDINSTOFFSET +UPDATENXTFLD: LDCW FIELDRECSZ + LDZPW LDPTR + ADDW + STZPW LDPTR + DECJNZB LDCNT, UPDATEFLDLP + LD0W + LDPW (CLASSLDPTR), CLASSFIELDTBL ; UNLOCK THE FIELD TABLE + CALL_02 HMEM_UNLOCK + POP2W +.IFDEF DEBUG_DVM + DVM_END + TSX + CPX STACKCHK + BEQ :+ + PERR "STACK CHECK FAIL AFTER FIXUP FIELDS" + BRK +: DVM_BEGIN +.ENDIF +; +; FIXUP VIRTUAL TABLE ENTRIES +; +VTBLINIT: LD0B + LDB ISUPER + BRZB :+ + POPB + LDPB (SUPERPTR), CLASSVTBLCNT +: STZPB VCNT ; THIS WILL BE THE ACTUAL VIRT TABLE SIZE + LDPB (CLASSLDPTR), CLASSMETHODCNT ; GET UPPER BOUNDS ON SIZE OF VIRT TABLE + DUPB + STZPB LDCNT + ZEXTB + LDZPB VCNT + ZEXTB + ADDW ; THIS WILL BE ACTUAL VTBL SIZE + SWAPB + BRZB :+ + POPB + LDCB $FF ; HOPE WE DON'T OVERFLOW +: DUPB + STZPB ACNT ; KEEP ALLOCATED SIZE AROUND + ZEXTB + SHLW + LD1W + SWAPW + CALL_02 HMEM_ALLOC ; ALLOCATE VIRT TABLE + DUPW + STPW (CLASSLDPTR), CLASSVIRTBL + CALL_02 HMEM_LOCK ; LOCK VIRT TABLE + DUPW + STZPW LDPTR + STZPW DSTADDR + POPW + LDB ISUPER ; COPY SUPER VTBL INTO THIS VTBL + BRZB NOSUPERVTBL + LD0W + LDPW (SUPERPTR), CLASSVIRTBL ; GET POINTER TO SUPER VIRT TABLE + CALL_02 HMEM_PTR + STZPW SRCADDR + LDZPB VCNT + ZEXTB + SHLW + CALL_02 MEMCPY ; COPY IT OVER + POP2W +NOSUPERVTBL: +.IFDEF DEBUG_DVM + DVM_END + TSX + CPX STACKCHK + BEQ :+ + PERR "STACK CHECK FAIL AFTER VTABLE INIT" + BRK +: DVM_BEGIN +.ENDIF + LDZPB LDCNT + BRNZB :+ ; CHECK FOR *THIS* METHODS + JUMP VTBLDONE ; NO NEW METHODS, SKIP VTBL CHECK +: LD0W + LDPW (CLASSLDPTR), CLASSMETHODTBL ; GET POINTER TO METHODS + CALL_02 HMEM_PTR ; STILL LOCKED FROM EARLIER + STZPW METHODPTR + POPW +VTBLINDXTLP: LDPB (METHODPTR), METHODACCESS ; CHECK FOR STATIC METHODS + LDCB $08 + ANDB + BRZB VTBLSRCHSUPR + LDPW (METHODPTR), METHODVINDEX + CALL SETCODECLASS ; SET CLASS FOR METHOD + JUMP VTBLINDXNXT +VTBLSRCHSUPR: LDB ISUPER + BRZB VTBLNEWINDX ; NO SUPER, ADD NEW INDEX + LDB ISUPER + ZEXTB + LDPW (METHODPTR), METHODDESC ; LOOK FOR MATCHING METHOD + CALL_02 CLASS_MATCH_DESC + POPW + LDPW (METHODPTR), METHODNAME + CALL_02 CLASS_MATCH_NAME + CALL_02 RESOLVE_METHOD + SWAPW + DUPW + LDCW $0100 ; CHECK CARRY FLAG FOR RESULT + ANDW + BRZW :+ + POP2W + BRNCH VTBLNEWINDX ; NOT FOUND, ALLOCATE NEW INDEX +: SWAPW + CALL_02 CLASS_METHODPTR ; FOUND A MATCH, GET ITS INDEX/OFFSET + STZPW TMPTR + POPW + LDPW (TMPTR), METHODVINDEX + STW ENTRYOFFSET +.IFDEF DEBUG_LOAD + DVM_END + PSTR "OVERRIDE METHOD:" + LDY #METHODNAME+1 + LDA (METHODPTR),Y + DEY + TAX + LDA (METHODPTR),Y + JSR PRHSTR + LDY #METHODDESC+1 + LDA (METHODPTR),Y + DEY + TAX + LDA (METHODPTR),Y + JSR PRHSTR + PSTR " VTBL OFST:" + LDA ENTRYOFFSET+1 + JSR PRBYTE + LDA ENTRYOFFSET + JSR PRBYTE + JSR CROUT +; JSR KBWAIT + DVM_BEGIN +.ENDIF + JUMP VTBLINSRTINDX +VTBLNEWINDX: LDZPB VCNT +.IFDEF DEBUG + DUPB + LDZPB ACNT + BRBEB :+ + PERR "OVERFLOWED ALLLOCATED COUNT" + BRK +: +.ENDIF + DUPB + INCRB + DUPB + STZPB VCNT + BRNZB :+ + DVM_END + PERR "VIRTUAL TABLE OVERFLOW" + JMP THROW_INTERNALERR +: ZEXTB + SHLW + STW ENTRYOFFSET +.IFDEF DEBUG_LOAD + DVM_END + PSTR "ADD METHOD:" + LDY #METHODNAME+1 + LDA (METHODPTR),Y + DEY + TAX + LDA (METHODPTR),Y + JSR PRHSTR + LDY #METHODDESC+1 + LDA (METHODPTR),Y + DEY + TAX + LDA (METHODPTR),Y + JSR PRHSTR + PSTR " VTBL OFST:" + LDA ENTRYOFFSET+1 + JSR PRBYTE + LDA ENTRYOFFSET + JSR PRBYTE + JSR CROUT +; JSR KBWAIT + DVM_BEGIN +.ENDIF +VTBLINSRTINDX: LDPW (METHODPTR), METHODVINDEX ; UPDATE METHOD ENTRY WITH VTBL INDEX + DUPW + CALL SETCODECLASS ; SET CLASS OF METHOD + LDW ENTRYOFFSET + DUPW + STPW (METHODPTR), METHODVINDEX + LDZPW LDPTR + ADDW ; CALC ADDRESS FOR INDEX + STINDW ; PULL HCODE OFF STACK AND SAVE IN VTBL +VTBLINDXNXT: LDCW METHODRECSZ ; NEXT METHOD + LDZPW METHODPTR + ADDW + STZPW METHODPTR + DECJNZB LDCNT, VTBLINDXTLP +METHDTBLDONE: LD0W + LDPW (CLASSLDPTR), CLASSMETHODTBL ; UNLOCK METHOD TABLE + CALL_02 HMEM_UNLOCK + POP2W +.IFDEF DEBUG_DVM + DVM_END + TSX + CPX STACKCHK + BEQ :+ + PERR "STACK CHECK FAIL AFTER VTABLE FIXUPS" + BRK +: DVM_BEGIN +.ENDIF +VTBLDONE: LD0W + LDPW (CLASSLDPTR), CLASSVIRTBL ; UNLOCK VIRT TABLE + CALL_02 HMEM_UNLOCK + POP2W + LDZPB VCNT ; SAVE ACTUAL VTBL SIZE + STPB (CLASSLDPTR), CLASSVTBLCNT ; SAVE VTBL SIZE + DVM_END +; +; UNLOCK THE CLASSES +; + LDY ISUPER + BEQ :+ + JSR HCLASS_INDEX ; UNLOCK SUPERCLASS + JSR HMEM_UNLOCK +: LDA HCLASSLD + LDX HCLASSLD+1 + JSR HMEM_UNLOCK ; UNLOCK THIS CLASS + LDA HCLASSLD ; SAVE CLASS INFO JUST + PHA ; IN CASE MESSES IT UP + LDA HCLASSLD+1 + PHA + LDA ICLASSLD + PHA +; +; LOOK FOR AND INVOKE IF FOUND +; +CLINIT: LDA #0 ; LOOK FOR METHOD + LDX #0 ; VALUES WERE POKED IN DURING INIT + JSR CLASS_MATCH_NAME + LDA HVOIDDESCSTR + LDX HVOIDDESCSTR+1 + JSR CLASS_MATCH_DESC + LDY ICLASSLD + JSR RESOLVE_METHOD + BCS CLASSLOADDONE ; NO +.IFDEF DEBUG_LOAD + PHA + TXA + PHA + TYA + PHA + PSTRLN "CALLING " + PLA + TAY + PLA + TAX + PLA +.ENDIF + JSR ASYNC_STATIC +.IFDEF DEBUG_LOAD + PHP + PSTRLN "BACK FROM " + PLP +.ENDIF + BCC CLASSLOADDONE ; CHECK FOR EXCEPTION + PLA + STA CURRENTEXCEPTN + PLA + STA CURRENTEXCEPTN+1 + PLA + STA CURRENTEXCEPTN+2 + PLA + STA CURRENTEXCEPTN+3 + BCS :+ +CLASSLOADDONE: CLC +: PLA ; YIPEE, ALL DONE + TAY + PLA + TAX + PLA +.IFDEF DEBUG_LOAD + STA TMP + PLA + CMP #$69 + BNE BADSTACK + PLA + CMP #$69 + BEQ OKSTACK +BADSTACK: PERR "LOADCLASS BAD STACK POINTER" + LDA #$EE ; SET STACK MARKER + PHA + PHA + BRK +OKSTACK: LDA TMP + CLC +.ENDIF + RTS +;* +;* READ CLASS DATA FROM FILE BUFFER +;* ONE BYTE VALUE IS RETURNED +;* IN A +;* ENTRY: +;* EXIT: TOSB = DATA +;* +READBYTE: DVM_END + LDY CLBUFFOFST + LDA (CLBUFFPTR),Y + PHA + INC CLBUFFOFST + BNE :+ + JSR READBUFF +: DVM_BEGIN + RET +;* +;* READ CLASS DATA FROM FILE BUFFER +;* ENTRY: +;* EXIT: TOSW = DATA +;* +READWORD: DVM_END + LDY CLBUFFOFST + LDA (CLBUFFPTR),Y + PHA + INY + BNE :+ + JSR READBUFF + LDY #$00 +: LDA (CLBUFFPTR),Y + PHA + INY + BNE :+ + JSR READBUFF + LDY #$00 +: STY CLBUFFOFST + DVM_BEGIN + RET +;* +;* READ DATA INTO MEMORY. +;* ENTRY: DSTADDR = ADDRESS OF MEMORY TO READ INTO +;* TOSW = NUMBER OF BYTES TO READ +;* +READMEM: DVM_END + PLAX + STA CCNT + STX CCNT+1 +RDMEMLP: LDY CLBUFFOFST + LDA (CLBUFFPTR),Y + INC CLBUFFOFST + BNE :+ + PHA + JSR READBUFF + PLA +: LDY #$00 + STA (DSTADDR),Y + INC DSTADDR + BNE :+ + INC DSTADDR+1 +: LDA CCNT + SEC + SBC #$01 + STA CCNT + LDA CCNT+1 + SBC #$00 + STA CCNT+1 + ORA CCNT + BNE RDMEMLP + DVM_BEGIN + RET +;* +;* READ ATTRIBUTE DATA AND DISCARD +;* +SKIPATTRIB: CALL READWORD ; LENH + BRNZW SKIPATTRIB_ERR + CALL READWORD ; LENL +SKIPBYTES: LDZPB CLBUFFOFST + ZEXTB + ADDW + STZPB CLBUFFOFST + DUPB + BRZB SKIPPED +SKIPPAGES: LD0W + LD0W + CALL_02 READBUFF + POP2W + DECRB + DUPB + BRNZB SKIPPAGES +SKIPPED: POPB + RET +SKIPATTRIB_ERR: JUMP LOADCLASS_ERR +;* +;* CALCULATE INDEX INTO CONSTANT POOL AND RETURN LOWORD AT CONST POOL INDEX +;* ENTRY: TOS = INDEX +;* EXIT: TOS = LOWORD +;* +LDCONST: DVM_END + PLAX + CALC_CONSTPLRECSZ + CLC ; CALC OFFSET IN CLASS TO CONST POOL + ADC #CLASSBASESZ-CONSTPLRECSZ + BCC :+ + INX + CLC +: ADC CLASSLDPTR + STA CLDPTR + TXA + ADC CLASSLDPTR+1 + STA CLDPTR+1 + LDY #$03 + LDA (CLDPTR),Y + INY + PHA + LDA (CLDPTR),Y + PHA + DVM_BEGIN + RET +;* +;* CLASS LOAD ERROR. +;* +LOADCLASS_ERR: DVM_END +.IFDEF DEBUG_LOAD + JSR KBWAIT + PERR "ERROR LOADING CLASS: " + LDY #CLASSTHIS+1 + LDA (CLASSLDPTR),Y + DEY + TAX + BEQ :+ + LDA (CLASSLDPTR),Y + JSR HMEM_PTR + JSR PRSTRLN +: +.ENDIF + JMP READCLASS_ERR +;* +;* SET CLASS INDEX OF BYTECODE METHOD +;* +SETCODECLASS: DVM_END + PLAX + STA HCODE + STX HCODE+1 + JSR HCODE_ISBYTECODE + BNE :+ + LDA HCODE + LDX HCODE+1 + JSR HCODE_ACCESS ; SET THE CLASS FOR THE CODE + LDA ICLASSLD + JSR HCODE_SETCLASS + JSR HCODE_UNACCESS +: DVM_BEGIN + RET +;***************************************************************************** +;* +;* END OF RELOCATED DVM CODE +;* +;***************************************************************************** +LC_DVM_END: + +CODESTR: .BYTE 4, "Code" ; CODE ATTRIBUTE +CONSTVALSTR: .BYTE 13, "ConstantValue" ; CONSTANT VALUE ATTRIBUTE +NATIVESTR: .BYTE 4, "6502" ; NATIVE 6502 CODE ATTRIBUTE +MAINNAMESTR: .BYTE 4, "main" ; MAIN ENRTYPOINT METHOD NAME +MAINDESCSTR: .BYTE 22, "([Ljava/lang/String;)V" ; MAIN ENTRYPOINT METHOD DESC +RUNNAMESTR: .BYTE 3, "run" ; THREAD ENTRYPOINT METHOD NAME +CLINITNAMESTR: .BYTE 8,"" ; CLASS INIT METHOD +FINALNAMESTR: .BYTE 8,"finalize" ; FINALIZER METHOD +VOIDDESCSTR: .BYTE 3,"()V" ; VOID METHOD DESC +BOOLSTR: .BYTE 1,"Z" ; BOOLEAN TYPE +BYTESTR: .BYTE 1,"B" ; BYTE TYPE +CHARSTR: .BYTE 1,"C" ; CHARACTER TYPE +SHORTSTR: .BYTE 1,"S" ; SHORT TYPE +INTSTR: .BYTE 1,"I" ; INTEGER TYPE +FLOATSTR: .BYTE 1,"F" ; FLOAT TYPE +LONGSTR: .BYTE 1,"J" ; LONG TYPE +DOUBLESTR: .BYTE 1,"D" ; DOUBLE TYPE + + .DATA +LOADCLASSCALLCNT: .BYTE 0 +CLASSFILEBASE: .ADDR $0000 +CLASSPREFIX: .RES 65 +CLASSFILE: .RES 65 +CLREFNUM: .BYTE $00 +HCLASSFILEBUFF: .WORD $0000 +READBUFFPROC: .ADDR 0 +RELEASEBUFFPROC: .ADDR 0 +HLOADCLASSPROC: .WORD 0 +LOADCLASSPROC: .WORD 0 +HMAINNAMESTR: .WORD $0000 ; ENTRYPOINT METHOD NAME +HMAINDESCSTR: .WORD $0000 ; ENTRYPOINT METHOD DESC +HRUNNAMESTR: .WORD $0000 ; ENTRYPOINT METHOD NAME +HFINALNAMESTR: .WORD $0000 ; FINALIZER METHOD NAME +HVOIDDESCSTR: .WORD $0000 ; VOID METHOD DESC +HCLASSLD: .WORD $0000 ; HANDLE TO CLASS BEING LOADED +ICLASSLD: .BYTE $00 ; INDEX TO LOADED CLASS IN HCLASS TABLE +SUPERCLASS: .WORD $0000 ; HSTR TO SUPERCLASS +ISUPER: .BYTE $00 +ENTRYOFFSET: .WORD $0000 +HREADSTRBUFF: .WORD $0000 ; TEMPORARY STRING BUFFER +MAXSTACK: .BYTE $00 +MAXLOCALS: .BYTE $00 +HCODE: ; ALIAS WITH CODE OFFSET +CODEOFST: .WORD $0000 +TYPE2SIZE: .BYTE 1,2,4,0 +CURRENTOFSTPROC: .ADDR 0 +.IFDEF DEBUG_DVM +STACKCHK: .BYTE $00 ; USE THIS TO VALIDATE STACK DEPTH +.ENDIF + + .CODE +;* +;* READ A CLASS FROM A MEMORY IMAGE +;* ENTRY: AX = POINTER TO CLASS IMAGE +;* +LOADCLASS_MEM: STA CLASSFILEBASE + STX CLASSFILEBASE+1 + STA CLBUFFPTR + STX CLBUFFPTR+1 + DVM_BEGIN + LD0W ; NULL HANDLE = LOADCLASS_MEM + JUMP LOADCLASS_INTERNAL +;* +;* READ A CLASS FROM A FILE +;* ENTRY: AX = HANDLE TO CLASS NAME +;* EXIT: AX = HANDLE TO CLASS +;* Y = CLASS INDEX +;* +LOADCLASS_FILE: PHA ; OUSH HANDLE ON STACK + TXA + PHA + DVM_BEGIN +;* +;* LOAD A CLASS AND CREATE AN INTERNAL CLASS STRUCTURE +;* CALLED FROM EITHER LOADCLASS_MEM OR LOADCLASS_FILE +;* +LOADCLASS_INTERNAL: LDCW LOADCLASS_INTRET-1 ; SET UP OUR RETURN ADDRESS (IN 6502 LAND) + SWAPW + DVM_END + LDA LOADCLASSCALLCNT + BNE :+ + LDA HLOADCLASSPROC + LDX HLOADCLASSPROC+1 + JSR HMEM_LOCK ; FIND THE CODE MODULE AND LOCK IT IN PLACE + STA LOADCLASSPROC + STX LOADCLASSPROC+1 +: INC LOADCLASSCALLCNT + DVM_BEGIN + LDW LOADCLASSPROC +.IFDEF DEBUG_LOAD + DUPW + BRNZW :+ + PERR_DVM "BAD LOADCLASSPROC" + JUMP LOADCLASS_ERR +: +.ENDIF + JUMPIND ; JUMP TO IT +LOADCLASS_INTRET:PHP ; SAVE RETURN VALUES + DEC LOADCLASSCALLCNT + BNE :+ + PHA + TXA + PHA + TYA + PHA + LDA HLOADCLASSPROC ; UNLOCK THE CODE MODULE + LDX HLOADCLASSPROC+1 + JSR HMEM_UNLOCK +.IFDEF DEBUG_LOAD + LDA #$00 + STA LOADCLASSPROC + STA LOADCLASSPROC+1 +.ENDIF + PLA ; RESTORE RETURN VALUES AND RETURN + TAY + PLA + TAX + PLA +: PLP + RTS +;* +;* CLASS FILE READ ERROR. +;* +;* +;* CLASS LOAD ERROR. +;* +READCLASS_ERR: +.IFDEF DEBUG_LOAD + PERR "ERROR READING CLASS FILE: " +.ENDIF + JSR RELEASEBUFF + LDA #7 ; CLASS FORMAT + JMP THROW_SYSEXCEPTN +FILECLASS_ERR: +.IFDEF DEBUG_LOAD + LDA #CLASSFILE + JSR PRSTRLN +.ENDIF + LDA #6 ; NO CLASS DEF FOUND + JMP THROW_SYSEXCEPTN +;* +;* RETURN CURRENT READ OFFSET POSITION IN CLASS FILE +;* +;* EXIT: TOS = OFFSET WORD +;* +CURRENTOFST_MEM: LD0W + RET +CURRENTOFST_FILE: LDB CLBUFFPAGE + LDB CLBUFFOFST + RET +;* +;* INDIRECT JUMPS TO BELOW ROUTINES +;* +READBUFF: JMP (READBUFFPROC) +RELEASEBUFF: JMP (RELEASEBUFFPROC) +;* +;* READ FROM FILE INTO BUFFER +;* +READBUFF_MEM: INC CLBUFFPTR+1 + RTS +READBUFF_FILE: LDA CLBUFFPTR + LDX CLBUFFPTR+1 + JSR FILE_SETBUFFER + LDA #$00 + LDX #$01 + LDY CLREFNUM + JSR FILE_READ + BCC :+ +.IFDEF DEBUG_LOAD + JSR PRBYTE + PERR " - ERROR FILE READ, " +.ENDIF + JMP READCLASS_ERR +: INC CLBUFFPAGE + RTS +;* +;* RELEASE CLASSFILE +;* +RELEASEBUFF_MEM: RTS +RELEASEBUFF_FILE: LDY CLREFNUM + JSR FILE_CLOSE +.IFDEF DEBUG_LOAD + BCC :+ + JSR PRBYTE + PERR " - ERROR CLOSING FILE: " + JMP FILECLASS_ERR +: +.ENDIF + LDA HCLASSFILEBUFF ; RELEASE FILE BUFFER + LDX HCLASSFILEBUFF+1 + JMP HMEM_FREE diff --git a/src/codemgr.s b/src/codemgr.s new file mode 100755 index 0000000..d5f6e7f --- /dev/null +++ b/src/codemgr.s @@ -0,0 +1,472 @@ +;* +;* JAVA BYTECODE MANAGER FOR 6502 +;* + .INCLUDE "global.inc" + .IMPORT PRBLNK,PRBYTE,COUT,CROUT,PRNTAX + .IMPORT PUTS,PUTSLN,PRSTR,PRSTRLN,MEMSRC,MEMDST,MEMCPY,MUL_FIELDRECSZ,MUL_METHODRECSZ + .IMPORT HMEM_ALLOC,HMEM_ALLOC_FIXED,HMEM_ALLOC_CODE,HMEM_FREE,HMEM_LOCK,HMEM_UNLOCK,HMEM_UNLOCK_CODE + .IMPORT HMEM_PTR,HMEM_REF_INC,HMEM_REF_DEC + .IMPORT THROW_INTERNALERR,SYSTHROW + .EXPORT CODECPY,HCODE_ALLOC,HCODE_ACCESS,HCODE_UNACCESS,HCODE_LOCK,HCODE_UNLOCK,HCODE_ISBYTECODE,HCODE_FLAGS + .EXPORT HCODE_SETSTACK,HCODE_SETLOCALS,HCODE_SETOFFSET,HCODE_SETCLASS,HCODE_SETHEXCEPT,HCODE_SETEXCEPTLEN + .EXPORT HCODE_GETSTACK,HCODE_GETLOCALS,HCODE_GETOFFSET,HCODE_GETCLASS,HCODE_GETHEXCEPT,HCODE_GETEXCEPTLEN,HCODE_GETLEN +;* +;* BYTECODE BLOCK INTERNAL STRUCTURE +;* +CODEBLKSIG EQU $00 ; 1 BYTE = $42 (UNUSED 6502/65C02/65802 OPCODE) +CODEBLKCLASS EQU $01 ; 1 BYTE +CODEBLKSTACK EQU $02 ; 1 BYTE +CODEBLKLOCALCNT EQU $03 ; 1 BYTE +CODEBLKLOCALSZ EQU $04 ; 2 BYTES (MUL BY 5 IN SET LOCALS) +CODEBLKOFFST EQU $06 ; 3 BYTES +CODEBLKHEXCEPT EQU $09 ; 2 BYTES +CODEBLKEXCPTLEN EQU $0B ; 2 BYTES +CODELOCKCNT EQU $0D ; 2 BYTES +CODEBLKLEN EQU $0F ; 2 BYTES +CODEBLKFLAGS EQU $11 ; 1 BYTE +CODEAUXADDR EQU $12 ; 2 BYTES = ADDRESS OF CODE IN AUX MEMs +CODEBLKCODE EQU $14 ; CODEBLKLEN BYTES, 32 BIT ALIGNED +CODEBLKPARMSZ EQU $14 ; 32 BIT ALIGNED + + .DATA +HCODE: .WORD 0 +HCODEBLK: .WORD 0 + + .CODE +;* +;* COPY BYTECODES TO CODE MEMORY +;* +;* ENTRY: A = CODEBYTE +;* +CODECPY: +.IFDEF DEBUG + PHA + LDA HCODEBLK + ORA HCODEBLK+1 + BNE :+ + PERR "CODE NOT ACCESSED" + JMP THROW_INTERNALERR +: PLA +.ENDIF + LDY #$00 + AUXMEM_WRACCESS_ON + STA (CODECOPYPTR),Y ; STORE CODE BYTE + AUXMEM_WRACCESS_OFF + INC CODECOPYPTR ; INCREMENT POINTER + BNE :+ + INC CODECOPYPTR+1 +: RTS +;* +;* ACCESS CODE BLOCK - WILL LOCK +;* ENTRY: AX = CODE HANDLE +;* +HCODE_ACCESS: +.IFDEF DEBUG + PHA + LDA HCODEBLK + ORA HCODEBLK+1 + BEQ :+ + PERR "CODE NOT UNACCESSED BEFORE ANOTHER ACCESS" +; JMP THROW_INTERNALERR +: PLA +.ENDIF + STA HCODEBLK + STX HCODEBLK+1 + JSR HCODE_LOCK + STA CODECOPYPTR + STX CODECOPYPTR+1 +.IFDEF BIGMEM + LDA HCODEBLK + LDX HCODEBLK+1 + JSR HMEM_PTR +.ELSE + SEC + SBC #CODEBLKCODE + BCS :+ + DEX +: +.ENDIF + STA CODEBLKPTR + STX CODEBLKPTR+1 + RTS +;* +;* UNACCESS CODE BLOCK - WILL UNLOCK +;* +HCODE_UNACCESS: LDA HCODEBLK + LDX HCODEBLK+1 +.IFDEF DEBUG + BEQ :+ + JSR HCODE_UNLOCK + LDA #$00 + STA HCODEBLK + STA HCODEBLK+1 +: RTS +.ENDIF + JMP HCODE_UNLOCK +;* +;* ALLOCATE CODE BLOCK +;* +;* ENTRY: AX = CODE SIZE +;* Y = FLAGS +;* EXIT: AX = HANDLE +;* C = 1 :: SUCCESS +;* C = 0 :: ERROR +;* +HCODE_ALLOC: +.IFDEF BIGMEM + CLC ; ROUND TO 32 BIT SIZE + ADC #$03 + BCC :+ + INX +: AND #$FC + PHA ; CODELEN + TXA + PHA ; CODELEN+1 + TYA + PHA ; CODEFLAGS + LDA #CODEBLKPARMSZ + LDX #$00 +.ELSE + STA TMP + PHA ; CODELEN + TXA + PHA ; CODELEN+1 + TYA + PHA ; CODEFLAGS + LDA TMP + CLC + ADC #CODEBLKPARMSZ + BCC :+ + INX +: +.ENDIF + LDY #$01 ; INITIAL REF COUNT + JSR HMEM_ALLOC_CODE + STA HCODE + STX HCODE+1 + JSR HMEM_PTR + STA TMPTR + STX TMPTR+1 + LDY #CODEBLKFLAGS ; SET CODE FLAGS + PLA ; CODEFLAGS + STA (TMPTR),Y + DEY ; LDY #CODEBLKLEN - SET CODELEN + PLA ; CODELEN+1 + STA (TMPTR),Y + DEY + PLA ; CODELEN + STA (TMPTR),Y + DEY ; LDY #CODEBLKPARMSZ - ZERO OUT PARAMTERS + LDA #$00 +: STA (TMPTR),Y + DEY + BNE :- + LDA #$42 ; UNUSED 6502/65C02/65802 OPCODE + STA (TMPTR),Y ; FOR BYTECODE SIGNATURE +.IFDEF BIGMEM + LDA CODEHEAPTOP + LDY #CODEBLKLEN + SEC + SBC (TMPTR),Y + INY + STA CODEHEAPTOP + TAX + LDA CODEHEAPTOP+1 + SBC (TMPTR),Y + CMP #$08 + BCS :+ + PERR "OUT OF BYTECODE HEAP" + LDA #4 ; OUT OF MEMORY + JMP SYSTHROW +: STA CODEHEAPTOP+1 + LDY #CODEAUXADDR+1 + STA (TMPTR),Y + DEY + TXA + STA (TMPTR),Y +.ENDIF + LDA HCODE + LDX HCODE+1 + CLC + RTS + +;* +;* SET CODE BLOCK PARAMETERS +;* ENTRY: A = BYTE +;* AX = WORD +;* AXY = 3 BYTES +;* +HCODE_SETCLASS: +.IFDEF DEBUG + PHA + LDA HCODEBLK + ORA HCODEBLK+1 + BNE :+ + PERR "CODE NOT ACCESSED" + JMP THROW_INTERNALERR +: PLA +.ENDIF + LDY #CODEBLKCLASS + STA (CODEBLKPTR),Y + RTS +HCODE_SETSTACK: +.IFDEF DEBUG + PHA + LDA HCODEBLK + ORA HCODEBLK+1 + BNE :+ + PERR "CODE NOT ACCESSED" + JMP THROW_INTERNALERR +: PLA +.ENDIF + LDY #CODEBLKSTACK + STA (CODEBLKPTR),Y + RTS +HCODE_SETLOCALS: +.IFDEF DEBUG + PHA + LDA HCODEBLK + ORA HCODEBLK+1 + BNE :+ + PERR "CODE NOT ACCESSED" + JMP THROW_INTERNALERR +: PLA +.ENDIF + LDY #CODEBLKLOCALCNT + STA (CODEBLKPTR),Y + INY ; LDY #CODEBLKLOCALSZ + STA TMP + LDX #$00 + ASL ; MULTIPLE A BY 5 + BCC :+ + LDX #$02 +: ASL + BCC :+ + INX + CLC +: ADC TMP + BCC :+ + INX +: STA (CODEBLKPTR),Y + INY + TXA + STA (CODEBLKPTR),Y + RTS +HCODE_SETOFFSET: +.IFDEF DEBUG + PHA + LDA HCODEBLK + ORA HCODEBLK+1 + BNE :+ + PERR "CODE NOT ACCESSED" + JMP THROW_INTERNALERR +: PLA +.ENDIF + STY TMP + LDY #CODEBLKOFFST + STA (CODEBLKPTR),Y + INY + TXA + STA (CODEBLKPTR),Y + INY + LDA TMP + STA (CODEBLKPTR),Y + RTS +HCODE_SETHEXCEPT: + LDY #CODEBLKHEXCEPT + BNE HCODE_SETWORD +HCODE_SETEXCEPTLEN: + LDY #CODEBLKEXCPTLEN +HCODE_SETWORD: +.IFDEF DEBUG + PHA + LDA HCODEBLK + ORA HCODEBLK+1 + BNE :+ + JMP THROW_INTERNALERR +: PLA +.ENDIF + STA (CODEBLKPTR),Y + INY + TXA + STA (CODEBLKPTR),Y + RTS +;* +;* GET CODE BLOCK PARAMETERS +;* EXIT: A = BYTE +;* AX = WORD +;* AXY = 3 BYTES +;* +HCODE_GETCLASS: +.IFDEF DEBUG + LDA HCODEBLK + ORA HCODEBLK+1 + BNE :+ + PERR "CODE NOT ACCESSED" + JMP THROW_INTERNALERR +: +.ENDIF + LDY #CODEBLKCLASS + LDA (CODEBLKPTR),Y + RTS +HCODE_GETSTACK: +.IFDEF DEBUG + LDA HCODEBLK + ORA HCODEBLK+1 + BNE :+ + PERR "CODE NOT ACCESSED" + JMP THROW_INTERNALERR +: +.ENDIF + LDY #CODEBLKSTACK + LDA (CODEBLKPTR),Y + RTS +HCODE_GETLOCALS: +.IFDEF DEBUG + LDA HCODEBLK + ORA HCODEBLK+1 + BNE :+ + PERR "CODE NOT ACCESSED" + JMP THROW_INTERNALERR +: +.ENDIF + LDY #CODEBLKLOCALSZ+1 ; SIZE IN AX + LDA (CODEBLKPTR),Y + DEY + TAX + LDA (CODEBLKPTR),Y + DEY + STA TMP + LDA (CODEBLKPTR),Y + TAY ; COUNT IN Y + LDA TMP + RTS +HCODE_GETOFFSET: +.IFDEF DEBUG + LDA HCODEBLK + ORA HCODEBLK+1 + BNE :+ + PERR "CODE NOT ACCESSED" + JMP THROW_INTERNALERR +: +.ENDIF + LDY #CODEBLKOFFST+2 + LDA (CODEBLKPTR),Y + DEY + STA TMP + LDA (CODEBLKPTR),Y + DEY + TXA + LDA (CODEBLKPTR),Y + LDY TMP + RTS +HCODE_GETLEN: + LDY #CODEBLKLEN+1 + BNE HCODE_GETWORD +HCODE_GETHEXCEPT: + LDY #CODEBLKHEXCEPT+1 + BNE HCODE_GETWORD +HCODE_GETEXCEPTLEN: + LDY #CODEBLKEXCPTLEN+1 +HCODE_GETWORD: +.IFDEF DEBUG + LDA HCODEBLK + ORA HCODEBLK+1 + BNE :+ + PERR "CODE NOT ACCESSED" + JMP THROW_INTERNALERR +: +.ENDIF + LDA (CODEBLKPTR),Y + DEY + TAX + LDA (CODEBLKPTR),Y + RTS +;* +;* LOCK CODE BLOCK +;* ENTRY: AX = CODE HANDLE +;* EXIT: AX = POINTER TO LOCKED CODE +;* +HCODE_LOCK: STA HCODE + STX HCODE+1 + JSR HMEM_LOCK + STA TMPTR + STX TMPTR+1 + LDY #CODELOCKCNT + LDA (TMPTR),Y + CLC + ADC #$01 + STA (TMPTR),Y + BCC :+ + INY + LDA (TMPTR),Y + ADC #$00 + STA (TMPTR),Y +: +.IFDEF BIGMEM + LDY #CODEAUXADDR+1 + LDA (TMPTR),Y + DEY + TAX + LDA (TMPTR),Y +.ELSE + LDA TMPTR + LDX TMPTR+1 + CLC + ADC #CODEBLKCODE + BCC :+ + INX +: +.ENDIF + RTS +;* +;* UNLOCK CODE BLOCK +;* ENTRY: AX = CODE HANDLE +;* +HCODE_UNLOCK: STA HCODE + STX HCODE+1 + JSR HMEM_PTR + STA TMPTR + STX TMPTR+1 + LDY #CODELOCKCNT + LDA (TMPTR),Y + SEC + SBC #$01 + STA (TMPTR),Y + INY + TAX + LDA (TMPTR),Y + SBC #$00 + STA (TMPTR),Y + BNE :- + CPX #$00 + BNE :- + LDA HCODE + LDX HCODE+1 + JMP HMEM_UNLOCK_CODE +;* +;* CHECK FOR BYTECODE SIGNATURE +;* ENTRY: AX = HANDLE +;* EXIT: Z = 1 :: IS BYTECODE +;* Z = 0 :: IS NOT BYTECODE +;* +HCODE_ISBYTECODE: + JSR HMEM_PTR + STA TMPTR + STX TMPTR+1 + LDY #CODEBLKSIG + LDA (TMPTR),Y + CMP #$42 + RTS +;* +;* RETURN HCODE FLAGS +;* ENTRY: AX = HANDLE +;* EXIT: Z = 1 :: IS SYNCHRONIZED +;* Z = 0 :: IS NOT SYNCHRONIZED +;* +HCODE_FLAGS: JSR HMEM_PTR + STA TMPTR + STX TMPTR+1 + LDY #CODEBLKFLAGS + LDA (TMPTR),Y + RTS \ No newline at end of file diff --git a/src/consoledrvr.s b/src/consoledrvr.s new file mode 100755 index 0000000..d4019dc --- /dev/null +++ b/src/consoledrvr.s @@ -0,0 +1,214 @@ +;* +;* CONSOLE DEVICE DRIVER +;* +CON_DRIVER: +CON_DRVR_SZ: .WORD CON_DRVR_END - CON_DRVR_START +CON_READ_OFS: .WORD CON_READ - CON_DRVR_START +CON_WRITE_OFS: .WORD CON_WRITE - CON_DRVR_START +CON_CTRL_OFS: .WORD CON_CTRL - CON_DRVR_START +CON_IRQ_OFS: .WORD CON_IRQ - CON_DRVR_START +CON_DRVR_START: +; +; READ CHARACTER FROM KEYBOARD BUFFER, WAITING IF NONE AVAILABLE +; EXIT: A = CHARACTER +; +CON_READ: SEI + LDX TYPEBUFFLEN + BNE :+ + CLI + LDY CURRENT_THREAD + JSR THREAD_NOTIMEOUT + LDY #$03 ; LOAD SLOT # + JSR THREAD_WAITIO + CLC + BCC CON_READ +: LDA TYPEBUFF ; SAVE OLDEST CHAR + PHA + DEC TYPEBUFFLEN + BEQ CONRDEXIT + LDX #$00 +: LDA TYPEBUFF+1,X ; SHIFT TYPE AHEAD BUFFER DOWN + STA TYPEBUFF,X + INX + CPX TYPEBUFFLEN + BNE :- + LDY #$03 + JSR THREAD_NOTIFYIO +CONRDEXIT: PLA +; CLI + RTS +; +; WRITE TO CONSOLE +; +CON_WRITE: JMP COUT +; +; CONSOLE DEVICE CONTROL +; +CON_CTRL: TYA + AND #$F8 ; MASK OFF SLOT NUMBER + LDX #$00 + CMP #IOCTL_AVAIL + BNE :+ + LDA TYPEBUFFLEN ; RETURN AVAILABLE KEYBOARD CHARACTERS + CLC + RTS +: CMP #IOCTL_SPACE + BNE :+ + LDA #$01 + CLC + RTS +: CMP #CONCTL_HOME + BNE :+ + LDA MACHID + BMI ROMHOME + AND #$02 + BEQ ROMHOME + LDA #$0C ; CTRL-L = HOME CHARACTER + JSR COUT + CLC + RTS +ROMHOME: JSR HOME + CLC + RTS +: CMP #CONCTL_TEXT80 + BNE :+ +.IFNDEF DEBUG_DUMP + LDA MACHID ; CHECK FOR 80 COL CARD INSTALLED + AND #$02 + BEQ CONCTLBAD + SEI ; NO INTS FOR SETUP + LDA #$00 + TAX + TAY + BIT ROMIN + JSR $C300 + LDA MACHID + BMI ROMHOME +.IF 0 + LDA $C301 + CMP #$CB + BNE NOTVIDEX + LDA #$02 ; ADJUST VIDEX PARAMETERS + STA $C0B0 + LDA #$5E + STA $C0B1 + LDA #$07 + STA $C0B0 + LDA #$1B + STA $C0B1 + LDA #$08 + STA $C0B0 + LDA #$01 + STA $C0B1 +.ENDIF +NOTVIDEX: LDA #$FF ; CLEAR LOWER-CASE MASK + STA LCOUT_MASK + LDA #$0C ; CTRL-L = HOME CHARACTER + JSR COUT + CLC + RTS +.ENDIF +;: CMP #IOCTL_CLOSE +; BNE :+ +; LDA #IOCTL_DEACTIVATE ; FALL THROUGH +: CMP #IOCTL_DEACTIVATE + BNE :+ + LDA #26 ; DEACTIVATE 80 COL CARDS + JSR COUT + LDA #'1' + JSR COUT + LDA #8 + JSR COUT + LDA #' ' + JSR COUT + LDA #21 + JSR COUT + BIT $C054 ; SET TEXT MODE + BIT $C051 + CLC + RTS +: CMP #IOCTL_ID + BEQ :+ +CONCTLBAD: SEC + RTS +: LDA MACHID + AND #$02 + BEQ CONCTLOK ; ID $00 = NO 80 COLUMN + LDA MACHID ; ID $80 = II, II+ 80 COLUMN + AND #$80 ; ID $88 = IIE, IIC 80 COLUMN + BEQ :+ + LDA #$08 +: ORA #$80 +CONCTLOK: CLC + RTS +; +; KEYBOARD IRQ. FAKED ON II, II+, AND IIE - THIS WILL ACTUALLY BE AN IRQ ON IIC +; +CON_IRQ: LDA KEYBD + BMI SPCLKEYS + SEC + RTS +SPCLKEYS: BIT CLRKBD ; CLEAR KEYBOARD STROBE + AND #$7F +.IFDEF DEBUG_BREAK + CMP #$03 ; CHECK FOR CTRL-C + BNE NOBREAK + PHP + SEI + BIT CLRKBD + LDA #$4C + STA $03F8 + LDA #BREAKOUT + STA $03FA + BIT $C054 ; SET TEXT MODE + BIT $C051 + JSR HOME + JSR THREAD_TRACE + BIT ROMIN + JMP $FF65 +BREAKOUT: PLA ; REMOVE RETURN ADDRESS + PLA + BIT CLRKBD + BIT LCBNK2 + BIT LCBNK2 + PLP + SEC + RTS +NOBREAK: +.ENDIF + LDY MACHID ; IS IT A II OR II+? + BMI TYPEAHEAD ; NOPE + CMP #$01 ; CHECK FOR CTRL-A + BNE :+ + LDA #$20 ; TOGGLE LOWERCASE MASK + EOR LCIN_MASK ; CTRL-A = CAPS LOCK + STA LCIN_MASK + SEC ; EAT KEYPRESS + RTS +: CMP #$20 + BCS CHKKEYLOWER + CMP #$0E ; CTRL-N -> [ + BNE :+ + LDA #$5B +: CMP #$0F ; CTRL-O -> _ + BEQ :+ + CMP #$0C ; CTRL-L -> \ + BNE CHKKEYLOWER +: ORA #$50 +CHKKEYLOWER: CMP #$40 + BCC TYPEAHEAD + ORA LCIN_MASK +TYPEAHEAD: LDX TYPEBUFFLEN + CPX #TYPEBUFFMAX + BCS TYPEBUFFULL + STA TYPEBUFF,X + LDA $C061 ; OPEN-APPLE KEY / PB0 + AND #$80 + ORA TYPEBUFF,X + STA TYPEBUFF,X + INC TYPEBUFFLEN +TYPEBUFFULL: CLC + RTS +CON_DRVR_END EQU * diff --git a/src/dvm.inc b/src/dvm.inc new file mode 100755 index 0000000..2f6699b --- /dev/null +++ b/src/dvm.inc @@ -0,0 +1,502 @@ +;* +;* DVM STACK BASED OPCODE INTERPRETER FOR 6502 +;* MACROS FOR MNEMONI CS +;* +; +; ENTRY/EXIT +; + .IMPORT DVM + +.MACRO DVM_BEGIN + JSR DVM +.ENDMACRO +.MACRO DVM_END + .BYTE $30 +.ENDMACRO +.MACRO DVM_ENTER + JSR ENTER_DVM +.ENDMACRO +.MACRO DVM_EXIT + .BYTE $30 +.ENDMACRO +; +; LOAD OPS +; +.MACRO LD0B + .BYTE $00 +.ENDMACRO +.MACRO LD0W + .BYTE $80 +.ENDMACRO +.MACRO LD1B + .BYTE $01 +.ENDMACRO +.MACRO LD1W + .BYTE $81 +.ENDMACRO +.MACRO LD2B + .BYTE $02 +.ENDMACRO +.MACRO LD2W + .BYTE $82 +.ENDMACRO +.MACRO LD3B + .BYTE $03 +.ENDMACRO +.MACRO LD3W + .BYTE $83 +.ENDMACRO +.MACRO LD4B + .BYTE $04 +.ENDMACRO +.MACRO LD4W + .BYTE $84 +.ENDMACRO +.MACRO LD5B + .BYTE $05 +.ENDMACRO +.MACRO LD5W + .BYTE $85 +.ENDMACRO +.MACRO DUPB + .BYTE $06 +.ENDMACRO +.MACRO DUPW + .BYTE $86 +.ENDMACRO +.MACRO DUP2B + .BYTE $07 +.ENDMACRO +.MACRO DUP2W + .BYTE $87 +.ENDMACRO +.MACRO SWAPB + .BYTE $08 +.ENDMACRO +.MACRO SWAPW + .BYTE $88 +.ENDMACRO +.MACRO LDCB LIT8 + .BYTE $09, LIT8 +.ENDMACRO +.MACRO LDCW LIT16 + .BYTE $89, >(LIT16), <(LIT16) +.ENDMACRO +.MACRO LDZPB ZP + .BYTE $0A, ZP +.ENDMACRO +.MACRO LDZPW ZP + .BYTE $8A, ZP +.ENDMACRO +.MACRO LDB MEM + .BYTE $0B + .ADDR MEM +.ENDMACRO +.MACRO LDW MEM + .BYTE $8B + .ADDR MEM +.ENDMACRO +.MACRO LDPB ZP, OFST8 + .BYTE $0C, ZP, OFST8 +.ENDMACRO +.MACRO LDPW ZP, OFST8 + .BYTE $8C, ZP, OFST8 +.ENDMACRO +.MACRO LDPINCB ZP + .BYTE $0D, ZP +.ENDMACRO +.MACRO LDPINCW ZP + .BYTE $8D, ZP +.ENDMACRO +.MACRO LDPDECB ZP + .BYTE $0E, ZP +.ENDMACRO +.MACRO LDPDECW ZP + .BYTE $8E, ZP +.ENDMACRO +.MACRO LDINDB + .BYTE $0F +.ENDMACRO +.MACRO LDINDW + .BYTE $8F +.ENDMACRO +; +; STORE OPS +; +.MACRO STZPB ZP + .BYTE $12, ZP +.ENDMACRO +.MACRO STZPW ZP + .BYTE $92, ZP +.ENDMACRO +.MACRO STB MEM + .BYTE $13 + .ADDR MEM +.ENDMACRO +.MACRO STW MEM + .BYTE $93 + .ADDR MEM +.ENDMACRO +.MACRO STPB ZP, OFST8 + .BYTE $14, ZP, OFST8 +.ENDMACRO +.MACRO STPW ZP, OFST8 + .BYTE $94, ZP, OFST8 +.ENDMACRO +.MACRO STPINCB ZP + .BYTE $15, ZP +.ENDMACRO +.MACRO STPINCW ZP + .BYTE $95, ZP +.ENDMACRO +.MACRO STPDECB ZP + .BYTE $16, ZP +.ENDMACRO +.MACRO STPDECW ZP + .BYTE $96, ZP +.ENDMACRO +.MACRO STINDB + .BYTE $17 +.ENDMACRO +.MACRO STINDW + .BYTE $97 +.ENDMACRO +; +; POP +; +.MACRO POPB + .BYTE $10 +.ENDMACRO +.MACRO POPW + .BYTE $90 +.ENDMACRO +.MACRO POP2B + .BYTE $11 +.ENDMACRO +.MACRO POP2W + .BYTE $91 +.ENDMACRO +; +; MATH OPS +; +.MACRO ZEXTB + .BYTE $18 +.ENDMACRO +.MACRO SEXTB + .BYTE $98 +.ENDMACRO +.MACRO NEGB + .BYTE $19 +.ENDMACRO +.MACRO NEGW + .BYTE $99 +.ENDMACRO +.MACRO NOTB + .BYTE $1A +.ENDMACRO +.MACRO NOTW + .BYTE $9A +.ENDMACRO +.MACRO ADDB + .BYTE $1B +.ENDMACRO +.MACRO ADDW + .BYTE $9B +.ENDMACRO +.MACRO SUBB + .BYTE $1C +.ENDMACRO +.MACRO SUBW + .BYTE $9C +.ENDMACRO +.MACRO ANDB + .BYTE $1D +.ENDMACRO +.MACRO ANDW + .BYTE $9D +.ENDMACRO +.MACRO ORB + .BYTE $1E +.ENDMACRO +.MACRO ORW + .BYTE $9E +.ENDMACRO +.MACRO XORB + .BYTE $1F +.ENDMACRO +.MACRO XORW + .BYTE $9F +.ENDMACRO +; +; BRANCH OPS +; +.MACRO BRZB DST + .BYTE $20 +.ASSERT (1+DST-*) < 128, ERROR, "BRANCH > 127" +.ASSERT (1+DST-*) > -129, ERROR, "BRANCH < -128" + .BYTE 1+DST-* +.ENDMACRO +.MACRO BRZW DST + .BYTE $A0 +.ASSERT (1+DST-*) < 128, ERROR, "BRANCH > 127" +.ASSERT (1+DST-*) > -129, ERROR, "BRANCH < -128" + .BYTE 1+DST-* +.ENDMACRO +.MACRO BRNZB DST + .BYTE $21 +.ASSERT (1+DST-*) < 128, ERROR, "BRANCH > 127" +.ASSERT (1+DST-*) > -129, ERROR, "BRANCH < -128" + .BYTE 1+DST-* +.ENDMACRO +.MACRO BRNZW DST + .BYTE $A1 +.ASSERT (1+DST-*) < 128, ERROR, "BRANCH > 127" +.ASSERT (1+DST-*) > -129, ERROR, "BRANCH < -128" + .BYTE 1+DST-* +.ENDMACRO +.MACRO BRPOSB DST + .BYTE $22 +.ASSERT (1+DST-*) < 128, ERROR, "BRANCH > 127" +.ASSERT (1+DST-*) > -129, ERROR, "BRANCH < -128" + .BYTE 1+DST-* +.ENDMACRO +.MACRO BRPOSW DST + .BYTE $A2 +.ASSERT (1+DST-*) < 128, ERROR, "BRANCH > 127" +.ASSERT (1+DST-*) > -129, ERROR, "BRANCH < -128" + .BYTE 1+DST-* +.ENDMACRO +.MACRO BRNEGB DST + .BYTE $23 +.ASSERT (1+DST-*) < 128, ERROR, "BRANCH > 127" +.ASSERT (1+DST-*) > -129, ERROR, "BRANCH < -128" + .BYTE 1+DST-* +.ENDMACRO +.MACRO BRNEGW DST + .BYTE $A3 +.ASSERT (1+DST-*) < 128, ERROR, "BRANCH > 127" +.ASSERT (1+DST-*) > -129, ERROR, "BRANCH < -128" + .BYTE 1+DST-* +.ENDMACRO +.MACRO BREQUB DST + .BYTE $24 +.ASSERT (1+DST-*) < 128, ERROR, "BRANCH > 127" +.ASSERT (1+DST-*) > -129, ERROR, "BRANCH < -128" + .BYTE 1+DST-* +.ENDMACRO +.MACRO BREQUW DST + .BYTE $A4 +.ASSERT (1+DST-*) < 128, ERROR, "BRANCH > 127" +.ASSERT (1+DST-*) > -129, ERROR, "BRANCH < -128" + .BYTE 1+DST-* +.ENDMACRO +.MACRO BRNEQB DST + .BYTE $25 +.ASSERT (1+DST-*) < 128, ERROR, "BRANCH > 127" +.ASSERT (1+DST-*) > -129, ERROR, "BRANCH < -128" + .BYTE 1+DST-* +.ENDMACRO +.MACRO BRNEQW DST + .BYTE $A5 +.ASSERT (1+DST-*) < 128, ERROR, "BRANCH > 127" +.ASSERT (1+DST-*) > -129, ERROR, "BRANCH < -128" + .BYTE 1+DST-* +.ENDMACRO +.MACRO BRGTB DST + .BYTE $26 +.ASSERT (1+DST-*) < 128, ERROR, "BRANCH > 127" +.ASSERT (1+DST-*) > -129, ERROR, "BRANCH < -128" + .BYTE 1+DST-* +.ENDMACRO +.MACRO BRGTW DST + .BYTE $A6 +.ASSERT (1+DST-*) < 128, ERROR, "BRANCH > 127" +.ASSERT (1+DST-*) > -129, ERROR, "BRANCH < -128" + .BYTE 1+DST-* +.ENDMACRO +.MACRO BRLEB DST + .BYTE $27 +.ASSERT (1+DST-*) < 128, ERROR, "BRANCH > 127" +.ASSERT (1+DST-*) > -129, ERROR, "BRANCH < -128" + .BYTE 1+DST-* +.ENDMACRO +.MACRO BRLEW DST + .BYTE $A7 +.ASSERT (1+DST-*) < 128, ERROR, "BRANCH > 127" +.ASSERT (1+DST-*) > -129, ERROR, "BRANCH < -128" + .BYTE 1+DST-* +.ENDMACRO +.MACRO BRGEB DST + .BYTE $11, $27 ; SWAPB, BRLEB +.ASSERT (1+DST-*) < 128, ERROR, "BRANCH > 127" +.ASSERT (1+DST-*) > -129, ERROR, "BRANCH < -128" + .BYTE 1+DST-* +.ENDMACRO +.MACRO BRGEW DST + .BYTE $91, $A7 ; SWAPW, BRLEW +.ASSERT (1+DST-*) < 128, ERROR, "BRANCH > 127" +.ASSERT (1+DST-*) > -129, ERROR, "BRANCH < -128" + .BYTE 1+DST-* +.ENDMACRO +.MACRO BRLTB DST + .BYTE $11, $26 ; SWAPB, BRGTB +.ASSERT (1+DST-*) < 128, ERROR, "BRANCH > 127" +.ASSERT (1+DST-*) > -129, ERROR, "BRANCH < -128" + .BYTE 1+DST-* +.ENDMACRO +.MACRO BRLTW DST + .BYTE $91, $A6 ; SWAPW, BRGTW +.ASSERT (1+DST-*) < 128, ERROR, "BRANCH > 127" +.ASSERT (1+DST-*) > -129, ERROR, "BRANCH < -128" + .BYTE 1+DST-* +.ENDMACRO +.MACRO BRAB DST + .BYTE $28 +.ASSERT (1+DST-*) < 128, ERROR, "BRANCH > 127" +.ASSERT (1+DST-*) > -129, ERROR, "BRANCH < -128" + .BYTE 1+DST-* +.ENDMACRO +.MACRO BRAW DST + .BYTE $A8 +.ASSERT (1+DST-*) < 128, ERROR, "BRANCH > 127" +.ASSERT (1+DST-*) > -129, ERROR, "BRANCH < -128" + .BYTE 1+DST-* +.ENDMACRO +.MACRO BRBEB DST + .BYTE $29 +.ASSERT (1+DST-*) < 128, ERROR, "BRANCH > 127" +.ASSERT (1+DST-*) > -129, ERROR, "BRANCH < -128" + .BYTE 1+DST-* +.ENDMACRO +.MACRO BRBEW DST + .BYTE $A9 +.ASSERT (1+DST-*) < 128, ERROR, "BRANCH > 127" +.ASSERT (1+DST-*) > -129, ERROR, "BRANCH < -128" + .BYTE 1+DST-* +.ENDMACRO +.MACRO BRAEB DST + .BYTE $08, $29 ; SWAPB, BRBEB +.ASSERT (1+DST-*) < 128, ERROR, "BRANCH > 127" +.ASSERT (1+DST-*) > -129, ERROR, "BRANCH < -128" + .BYTE 1+DST-* +.ENDMACRO +.MACRO BRAEW DST + .BYTE $88, $A9 ; SWAPW, BRBEW +.ASSERT (1+DST-*) < 128, ERROR, "BRANCH > 127" +.ASSERT (1+DST-*) > -129, ERROR, "BRANCH < -128" + .BYTE 1+DST-* +.ENDMACRO +.MACRO BRBB DST + .BYTE $08, $28 ; SWAPB, BRAB +.ASSERT (1+DST-*) < 128, ERROR, "BRANCH > 127" +.ASSERT (1+DST-*) > -129, ERROR, "BRANCH < -128" + .BYTE 1+DST-* +.ENDMACRO +.MACRO BRBW DST + .BYTE $88, $A8 ; SWAPW, BRAW +.ASSERT (1+DST-*) < 128, ERROR, "BRANCH > 127" +.ASSERT (1+DST-*) > -129, ERROR, "BRANCH < -128" + .BYTE 1+DST-* +.ENDMACRO +.MACRO BRNCH DST + .BYTE $2A +.ASSERT (1+DST-*) < 128, ERROR, "BRANCH > 127" +.ASSERT (1+DST-*) > -129, ERROR, "BRANCH < -128" + .BYTE 1+DST-* +.ENDMACRO +.MACRO DECJNZB MEM, DST + .BYTE $2B + .ADDR MEM +.ASSERT (3+DST-*) < 32768, ERROR, "JUMP > 32768" +.ASSERT (3+DST-*) > -32768, ERROR, "JUMP < -32768" + .WORD 3+DST-* +.ENDMACRO +.MACRO DECJNZW MEM, DST + .BYTE $AB + .ADDR MEM +.ASSERT (3+DST-*) < 32768, ERROR, "JUMP > 32768" +.ASSERT (3+DST-*) > -32768, ERROR, "JUMP < -32768" + .WORD 3+DST-* +.ENDMACRO +; +; SHIFT OPERATIONS +; +.MACRO SHLB + .BYTE $2C +.ENDMACRO +.MACRO SHLW + .BYTE $AC +.ENDMACRO +.MACRO SHRB + .BYTE $2D +.ENDMACRO +.MACRO SHRW + .BYTE $AD +.ENDMACRO +; +; INC/DEC OPERATIONS +; +.MACRO INCRB + .BYTE $2E +.ENDMACRO +.MACRO INCRW + .BYTE $AE +.ENDMACRO +.MACRO DECRB + .BYTE $2F +.ENDMACRO +.MACRO DECRW + .BYTE $AF +.ENDMACRO +; +; CONTROL FLOW OPERATIONS +; +;.MACRO EXIT +; .BYTE $30 +;.ENDMACRO +.MACRO JUMP DST + .BYTE $31 +.ASSERT (1+DST-*) < 32768, ERROR, "JUMP > 32767" +.ASSERT (1+DST-*) > -32769, ERROR, "JUMP < -32768" + .WORD 1+DST-* +.ENDMACRO +.MACRO JUMPIND + .BYTE $B1 +.ENDMACRO +.MACRO CALL DST + .BYTE $32 +.ASSERT (1+DST-*) < 32768, ERROR, "CALL > 32767" +.ASSERT (1+DST-*) > -32769, ERROR, "CALL < -32768" + .WORD 1+DST-* +.ENDMACRO +.MACRO CALLIND + .BYTE $B2 +.ENDMACRO +.MACRO RET + .BYTE $33 +.ENDMACRO +.MACRO CALL_02 DST + .BYTE $34 + .ADDR DST +.ENDMACRO +.MACRO CALLIND_02 + .BYTE $B4 +.ENDMACRO +.MACRO SWTCHB CNT + .BYTE $35, CNT +.ENDMACRO +.MACRO SWTCHW CNT + .BYTE $B5, CNT +.ENDMACRO +.MACRO CASEB LIT8, DST + .BYTE LIT8 +.ASSERT (DST-*) < 32768, ERROR, "CASE > 32767" +.ASSERT (DST-*) > -32769, ERROR, "CASE < -32768" + .WORD DST-* +.ENDMACRO +.MACRO CASEW LIT16, DST + .WORD LIT16 +.ASSERT (DST-*) < 32768, ERROR, "CASE > 32767" +.ASSERT (DST-*) > -32769, ERROR, "CASE < -32768" + .WORD DST-* +.ENDMACRO diff --git a/src/dvm.s b/src/dvm.s new file mode 100755 index 0000000..89db0f4 --- /dev/null +++ b/src/dvm.s @@ -0,0 +1,914 @@ +;* +;* DAVE'S VIRTUAL MACHINE BYTECODE INTERPRETER V. 1.0 +;* STACK IS PUSHED MSB/LSB AND POPPED LSB/MSB +;* + +;* +;* ZERO PAGE LOCATIONS +;* +;DVM_PC = $08 ; PROGRAM COUNTER +;DVM_PTR = $0A ; MEMORY POINTER; + .INCLUDE "global.inc" + + .IMPORT MEMSRC,MEMDST,MEMCPY,MEMCLR,KBWAIT + .EXPORT DVM, DVM_INIT + + .DATA +DVM_SP: .BYTE 0 +DVM_CALLSTACK: .RES 6*2 + + .CODE +.IFDEF DEBUG_DVM +CHK_OP: PHP + CMP #$6C + BCC :+ + PERR "INVALID DVM OP" + BRK +: PLP + RTS +.ENDIF +;* +;* LOAD OPS $00-$0F/$80-$8F +;* +; LDPDECB $06 (LoaD Pointer Dec Byte) +; LDPDECW $86 (LoaD Pointer Dec Word) +LDPDEC: PHP + LDA #$01 + ADC #$00 + STA DVM_PTR + LDA (DVM_PC),Y + TAX + LDA $00,X + SEC + SBC DVM_PTR + STA $00,X + STA DVM_PTR + LDA $01,X + SBC #$00 + STA $01,X + STA DVM_PTR+1 + PLP + BCC :++ + BCS :+ +; LDPINCB $05 (LoaD Pointer Inc Byte) +; LDPINCW $85 (LoaD Pointer Inc Word) +LDPINC: PHP + LDA (DVM_PC),Y + TAX + LDA $00,X + STA DVM_PTR + ADC #$01 + STA $00,X + LDA $01,X + STA DVM_PTR+1 + ADC #$00 + STA $01,X + PLP + BCC :++ +: LDA (DVM_PTR),Y + PHA +: DEY + LDA (DVM_PTR),Y + PHA + LDA #$02 + JMP DVM_NEXTOPA +; LDPB $04 (LoaD Pointer Byte) +; LDPW $84 (LoaD Pointer Word) +LDP: LDA (DVM_PC),Y + INY + TAX + LDA $00,X + STA DVM_PTR + LDA $01,X + STA DVM_PTR+1 + LDA (DVM_PC),Y + TAY + BCC :+ + INY + LDA (DVM_PTR),Y + PHA + DEY +: LDA (DVM_PTR),Y + PHA + LDA #$03 + JMP DVM_NEXTOPA +; LDINDB $04 (LoaD INDirect Byte) +; LDINDW $84 (LoaD INDirect Word) +LDIND: PLA + STA DVM_PTR + PLA + STA DVM_PTR+1 + BCC :+ + LDA (DVM_PTR),Y + PHA +: DEY + LDA (DVM_PTR),Y + INY + PHA + BNE DVM_NEXTOP +; LDB $03 (LoaD Byte) +; LDW $83 (LoaD Word) +LD: LDA (DVM_PC),Y + INY + STA DVM_PTR + LDA (DVM_PC),Y + STA DVM_PTR+1 + BCC :+ + DEY + LDA (DVM_PTR),Y + PHA +: LDY #$00 + LDA (DVM_PTR),Y + PHA + LDA #$03 + BNE DVM_NEXTOPA +; LDZPB $02 (LoaD Zero Page Byte) +; LDZPW $82 (LoaD Zero Page Word) +LDZP: LDA (DVM_PC),Y + TAX + BCC :+ + LDA $01,X + PHA +: LDA $00,X + PHA + INY + BNE DVM_NEXTOP +; LDCB $09 (LoaD Constant Byte) +; LDCW $89 (LoaD Constant Word) NOTE word is MSB FIRST! +LDC: LDA (DVM_PC),Y + INY + PHA + BCC DVM_NEXTOP + LDA (DVM_PC),Y + INY + PHA + BCS DVM_NEXTOP +; LDM1B $08 (LoaD Minus 1 Byte) +; LDM1W $88 (Load Minus Word) +;LDM1: LDA #$FF +; PHA +; BCC DVM_NEXTOP +; PHA +; BCS DVM_NEXTOP +; LDCB $00-$07 (Load Literal Byte) +; LDCW $80-$87 (Load Literal Word) +LDL: BCC :+ + LDA #$00 + PHA +: TXA + LSR ; CLEARS CARRY + PHA + BCC DVM_NEXTOP +; POP2B $10 (POP 2 Bytes) +; POP2W $90 (POP 2 Words) +POP2: PLA + PLA + BCC DVM_NEXTOP +; PLA +; PLA +; BCS DVM_NEXTOP +; POPB $10 (POP Byte) +; POPW $90 (POP Word) +POP: PLA + BCC DVM_NEXTOP + PLA + BCS DVM_NEXTOP +; DUP2B $17 (DUPlicate 2 bytes) - same as DUPW +; DUP2W $97 (DUPlicate 2 Words) +DUP2: TSX + BCC :+ + LDA $0104,X + PHA + LDA $0103,X + PHA + BCS :+ +; DUPB $0F (DUPlicate Byte) +; DUPW $8F (DUPlicate Word) +DUP: TSX + BCC :++ +: LDA $0102,X + PHA +: LDA $0101,X + PHA +; JMP DVM_NEXTOP +NOOP: +DVM_NEXTOP: TYA +DVM_NEXTOPA: CLC + ADC DVM_PC + STA DVM_PC + BCC DVM_DISPATCH + INC DVM_PC+1 +DVM_DISPATCH: + LDY #$00 + LDA (DVM_PC),Y + INY + ASL +.IFDEF DEBUG_DVM + JSR CHK_OP +.ENDIF + TAX + LDA DVM_OPTBL+1,X + PHA + LDA DVM_OPTBL,X + PHA + RTS +;* +;* STORE OPS $08-$0F/$88-$8F +;* +; SWAPB $09 (SWAP Bytes) +; SWAPW $89 (SWAP Words) +SWAP: TSX + PLA ; LDA $0101,X + BCS :+ + LDY $0102,X + STA $0102,X + TYA + PHA ; STA $0101,X + LDA #$01 + BNE DVM_NEXTOPA +: LDY $0103,X + STA $0103,X + TYA + PHA ; STA $0101,X + LDY $0104,X + LDA $0102,X + STA $0104,X + TYA + STA $0102,X + LDA #$01 + BNE DVM_NEXTOPA +; STZPW $0A (STore Zero Page Word) +; STZPB $8A (STore Zero Page Byte) +STZP: LDA (DVM_PC),Y + INY + TAX + PLA + STA $00,X + BCC DVM_NEXTOP + PLA + STA $01,X + BCS DVM_NEXTOP +; STB $0B (STore Byte) +; STW $8B (STore Word) +ST: LDA (DVM_PC),Y + INY + STA DVM_PTR + LDA (DVM_PC),Y + STA DVM_PTR+1 + PLA + LDY #$00 + STA (DVM_PTR),Y + BCC :+ + PLA + INY + STA (DVM_PTR),Y +: LDA #$03 + BNE DVM_NEXTOPA +; STINDB $0C (STore INDirect Byte) +; STINDW $8C (STore INDirect Word) +STIND: PLA + STA DVM_PTR + PLA + STA DVM_PTR+1 + PLA + DEY + STA (DVM_PTR),Y + INY + BCC :+ + PLA + STA (DVM_PTR),Y +: JMP DVM_NEXTOP +; STPB $0C (STore Byte Pointer) +; STPW $8C (STore Word Pointer) +STP: LDA (DVM_PC),Y + INY + TAX + LDA $00,X + STA DVM_PTR + LDA $01,X + STA DVM_PTR+1 + LDA (DVM_PC),Y + TAY + PLA + STA (DVM_PTR),Y + BCC :+ + INY + PLA + STA (DVM_PTR),Y +: LDA #$03 + JMP DVM_NEXTOPA +; STPINCB $0D (STore Pointer INC Byte) +; STPINCW $8D (STore Pointer INC Word) +STPINC: PHP + LDA (DVM_PC),Y + TAX + LDA $00,X + STA DVM_PTR + ADC #$01 + STA $00,X + LDA $01,X + STA DVM_PTR+1 + ADC #$00 + STA $01,X + PLP +: PLA + DEY + STA (DVM_PTR),Y + BCC :+ + PLA + INY + STA (DVM_PTR),Y +: LDA #$02 + JMP DVM_NEXTOPA +; STPDECB $0E (STore Pointer DEC Byte) +; STPDECW $8E (STore Pointer DEC Word) +STPDEC: PHP + LDA #$01 + ADC #$00 + STA DVM_PTR + LDA (DVM_PC),Y + TAX + LDA $00,X + SEC + SBC DVM_PTR + STA $00,X + STA DVM_PTR + LDA $01,X + SBC #$00 + STA $01,X + STA DVM_PTR+1 + PLP + JMP :-- +;* +;* MATH OPS $10-$17/$90-$97 +;* +; ZEXTB $10 (Zero EXTend Byte) +; SEXTB $90 (Sign EXTend Byte) +EXT: PLA + TAX + BCC :+ + BPL :+ + LDA #$FF + BMI :++ +: LDA #$00 +: PHA + TXA + PHA + JMP DVM_NEXTOP +; NEGB $11 (NEGate Byte) +; NEGW $91 (NEGate Word) +NEG: TSX + BCS :+ + SEC + LDA #$00 + SBC $0101,X + STA $0101,X + JMP DVM_NEXTOP +: LDA #$00 + SBC $0101,X + STA $0101,X + LDA #$00 + SBC $0102,X + STA $0102,X + JMP DVM_NEXTOP +; NOTB $12 (NOT Byte) +; NOTW $92 (NOT Word) +NOT: TSX + LDA $0101,X + EOR #$FF + STA $0101,X + BCC :+ + LDA $0102,X + EOR #$FF + STA $0102,X +: JMP DVM_NEXTOP +; ADDB $13 (ADD Byte) +; ADDW $93 (ADD Word) +ADD: TSX + PLA + BCS :+ + ADC $0102,X + STA $0102,X + JMP DVM_NEXTOP +: CLC + ADC $0103,X + STA $0103,X + PLA + ADC $0104,X + STA $0104,X + JMP DVM_NEXTOP +; SUBB $14 (SUBtract Byte) +; SUBW $94 (SUBtract Word) +SUB: TSX + BCS :+ + SEC + LDA $0102,X + SBC $0101,X + STA $0102,X + PLA + JMP DVM_NEXTOP +: LDA $0103,X + SBC $0101,X + STA $0103,X + LDA $0104,X + SBC $0102,X + STA $0104,X + PLA + PLA + JMP DVM_NEXTOP +; ANDB $15 (AND Bytes) +; ANDW $95 (AND Words) +L_AND: TSX + PLA + BCS :+ + AND $0102,X + STA $0102,X + JMP DVM_NEXTOP +: AND $0103,X + STA $0103,X + PLA + AND $0104,X + STA $0104,X + JMP DVM_NEXTOP +; ORB $16 (OR Bytes) +; ORW $96 (OR Words) +L_OR: TSX + PLA + BCS :+ + ORA $0102,X + STA $0102,X + JMP DVM_NEXTOP +: ORA $0103,X + STA $0103,X + PLA + ORA $0104,X + STA $0104,X + JMP DVM_NEXTOP +; XORB $17 (XOR Bytes) +; XORW $97 (XOR Words) +L_XOR: TSX + PLA + BCS :+ + EOR $0102,X + STA $0102,X + JMP DVM_NEXTOP +: EOR $0103,X + STA $0103,X + PLA + EOR $0104,X + STA $0104,X + JMP DVM_NEXTOP +; BRZB $18 (BRanch Zero Byte) +; BRZW $98 (BRanch Zero Word) +BRZ: PLA + BCC :+ + STA DVM_PTR + PLA + ORA DVM_PTR + BNE :++ +: BEQ BRNCH +: INY + JMP DVM_NEXTOP +; BRNZB $19 (BRanch Not Zero Byte) +; BRNZW $99 (BRanch Not Zero Word) +BRNZ: PLA + BCC :+ + STA DVM_PTR + PLA + ORA DVM_PTR + BEQ :++ +: BNE BRNCH +: INY + JMP DVM_NEXTOP +; BRPOSB $1A (BRanch Positive Byte) +; BRPOSW $9A (BRanch Positive Word) +BRPOS: PLA + BCC :+ + PLA +: BPL BRNCH + INY + JMP DVM_NEXTOP +; BRNEGB $1B (BRanch NEGative Byte) +; BRNEGW $9B (BRanch NEGative Word) +BRNEG: PLA + BCC :+ + PLA +: BMI BRNCH + INY + JMP DVM_NEXTOP +; BREQUB $1C (BRanch EQUal Bytes) - branch if top bytes equal +; BREQUW $9C (BRanch EQUal Words) - branch if top words equal +BREQU: TSX + PLA + BCS :+ + PLA + CMP $0101,X + BNE :++++ + BEQ BRNCH +: CMP $0103,X + BNE :+ + PLA + CMP $0104,X + BEQ :+++++++ + BNE :++ +: PLA +: PLA + PLA +: INY + JMP DVM_NEXTOP +; BRNEQB $1D (BRanch Not EQual Bytes) - branch if top bytes not equal +; BRNEQW $9D (BRanch Not EQual Words) - branch if top words not equal +BRNEQ: TSX + PLA + BCS :+ + PLA + CMP $0101,X + BEQ :++ + BNE BRNCH +: CMP $0103,X + BNE :++ + PLA + CMP $0104,X + BNE :+++ + PLA + PLA +: INY + JMP DVM_NEXTOP +: PLA +: PLA + PLA +; BRNCH $22 (BRaNCH) +BRNCH: LDX #$00 + LDA (DVM_PC),Y + BPL :+ + LDX #$FF +: CLC + ADC DVM_PC + STA DVM_PC + TXA + ADC DVM_PC+1 + STA DVM_PC+1 + JMP DVM_DISPATCH +; BRGTB $1E (BRanch Greater Than Bytes) +; BRGTW $9E (BRanch Greater Than Words) +; TOS-1 > TOS -> TOS < TOS-1 +BRGT: TSX + PLA + BCS :++ + SEC + SBC $0102,X + BVC :+ + EOR #$80 +: BMI :++++ + PLA + LDA #$03 + JMP DVM_NEXTOPA +: SBC $0103,X + PLA + SBC $0104,X + BVC :+ + EOR #$80 +: BMI :+ + PLA + PLA + INY + JMP DVM_NEXTOP +: PLA +: PLA + JMP BRNCH +; BRLEB $1F (BRanch Less than or Equal Bytes) +; BRLEW $9F (BRanch Less than or Equal Words) +; TOS-1 <= TOS -> TOS >= TOS-1 +BRLE: TSX + PLA + BCS :++ + SEC + SBC $0102,X + BVC :+ + EOR #$80 +: BPL :-- + PLA + INY + JMP DVM_NEXTOP +: SBC $0103,X + PLA + SBC $0104,X + BVC :+ + EOR #$80 +: BPL :----- + PLA + PLA + INY + JMP DVM_NEXTOP +; BRAB $22 (BRanch Above Bytes) +; BRAW $A2 (BRanch Above Than Words) +; (UNSIGNED) TOS-1 > TOS -> TOS < TOS-1 +BRA: TSX + PLA + BCS :+ + CMP $0102,X + BCC :+++ + PLA + INY + JMP DVM_NEXTOP +: SBC $0103,X + PLA + SBC $0104,X + BCC :+ + PLA + PLA + INY + JMP DVM_NEXTOP +: PLA +: PLA + JMP BRNCH +; BRBEB $23 (BRanch Below or Equal Bytes) +; BRBEW $A3 (BRanch Below or Equal Words) +; (UNSIGNED) TOS-1 <= TOS -> TOS >= TOS-1 +BRBE: TSX + PLA + BCS :+ + CMP $0102,X + BCS :- + PLA + INY + JMP DVM_NEXTOP +: SBC $0103,X + PLA + SBC $0104,X + BCS :--- + PLA + PLA + INY + JMP DVM_NEXTOP +; SHLB $28 (SHift Left Byte) +; SHLW $A8 (SHift Left Word) +SHL: TSX + BCS :+ + ASL $0101,X + JMP DVM_NEXTOP +: ASL $0101,X + ROL $0102,X + JMP DVM_NEXTOP +; SHRB $29 (SHift Right Byte) +; SHRW $A9 (SHift Right Word) +SHR: TSX + BCS :+ + LSR $0101,X + JMP DVM_NEXTOP +: LSR $0102,X + ROR $0101,X + JMP DVM_NEXTOP +; INCRB $28 (INCRement Byte) +; INCRW $A8 (INCRement Word) +INCR: TSX + INC $0101,X + BCS :+ + JMP DVM_NEXTOP +: BNE :+ + INC $0102,X +: JMP DVM_NEXTOP +; DECRB $28 (DECRement Byte) +; DECRW $A8 (DECRement Word) +DECR: TSX + DEC $0101,X + BCS :+ + JMP DVM_NEXTOP +: LDA $0101,X + CMP #$FF + BNE :+ + DEC $0102,X +: JMP DVM_NEXTOP +; SWITCHB $35 (SWiTCH Byte) +; SWITCHW $B5 (SWiTCH Word) +SWTCH: BCS SWTCHW + LDA (DVM_PC),Y + INY + TAX + PLA + STA DVM_PTR +SWTCHBLP: LDA (DVM_PC),Y + INY + CMP DVM_PTR + BNE :++ + LDX DVM_PC+1 + TYA + CLC + ADC DVM_PC + BCC :+ + INX + CLC +: ADC (DVM_PC),Y + INY + PHA + TXA + ADC (DVM_PC),Y + STA DVM_PC+1 + PLA + STA DVM_PC + LDA #$00 + JMP DVM_NEXTOPA +: INY + INY + DEX + BNE SWTCHBLP + JMP DVM_NEXTOP +SWTCHW: LDA (DVM_PC),Y + INY + TAX + PLA + STA DVM_PTR + PLA + STA DVM_PTR+1 +SWTCHWLP: LDA (DVM_PC),Y + INY + CMP DVM_PTR + BNE :++ + LDA (DVM_PC),Y + INY + CMP DVM_PTR+1 + BNE :+++ + LDX DVM_PC+1 + TYA + CLC + ADC DVM_PC + BCC :+ + INX + CLC +: ADC (DVM_PC),Y + INY + PHA + TXA + ADC (DVM_PC),Y + STA DVM_PC+1 + PLA + STA DVM_PC + LDA #$00 + JMP DVM_NEXTOPA +: INY +: INY + INY + DEX + BNE SWTCHWLP + JMP DVM_NEXTOP +; EXIT $28 (EXIT) +EXIT: LDA DVM_PC+1 + PHA + LDA DVM_PC + PHA + RTS +;* +;* ENTRYPOINT INTO DVM +;* +DVM: LDY #$01 + BNE :+ +; JUMP $29 (JUMP) +JUMP: BCS JUMPIND + LDA (DVM_PC),Y + INY + ADC DVM_PC + TAX + LDA (DVM_PC),Y + ADC DVM_PC+1 + PHA + TXA + PHA +; JUMP $A9 (JUMP INDirect) +JUMPIND: LDY #$00 +: PLA + STA DVM_PC + PLA + STA DVM_PC+1 + JMP DVM_NEXTOP +; DECJNZB $26 (DECrement memory Jump Not Zero Byte) +; DECJNZW $A6 (DECrement memory Jump Not Zero Word) +DECJNZ: LDA (DVM_PC),Y + INY + STA DVM_PTR + LDA (DVM_PC),Y + STA DVM_PTR+1 + LDY #$00 + LDA (DVM_PTR),Y + BCS :++ + ADC #$FF + STA (DVM_PTR),Y + BEQ :+++ +: LDY #$03 + CLC + BCC JUMP +: SBC #$01 + STA (DVM_PTR),Y + INY + LDA (DVM_PTR),Y + SBC #$00 + STA (DVM_PTR),Y + DEY + ORA (DVM_PTR),Y + BNE :-- +: LDA #$05 + JMP DVM_NEXTOPA +; CALL $2A (CALL) +CALL: BCS CALLIND + LDA (DVM_PC),Y + INY + ADC DVM_PC + TAX + LDA (DVM_PC),Y + INY + ADC DVM_PC+1 + PHA + TXA + PHA +; CALL $AA (CALL INDirect) +CALLIND: LDX DVM_SP + TYA + CLC + ADC DVM_PC + STA DVM_CALLSTACK,X + INX + LDA #$00 + ADC DVM_PC+1 + STA DVM_CALLSTACK,X + INX + STX DVM_SP + BNE JUMPIND +; RET $2B (RETurn) +RET: LDX DVM_SP + DEX + LDA DVM_CALLSTACK,X + STA DVM_PC+1 + DEX + LDA DVM_CALLSTACK,X + STA DVM_PC + STX DVM_SP + LDA #$00 + JMP DVM_NEXTOPA +; CALL_02 $34 (CALL 6502) +CALL_02: BCS CALLIND_02 + LDA (DVM_PC),Y + INY + TAX + LDA (DVM_PC),Y + INY + PHA + TXA + PHA +; CALLIND_02 $B4 (CALL INDirect 6502) +CALLIND_02: TYA + CLC + ADC DVM_PC + STA DVM_PC + BCC :+ + INC DVM_PC+1 +: PLA + STA JSRADDR+1 ; BAD, SELF MODIFYING CODE + PLA + STA JSRADDR+2 + PLA + STA DVM_PTR + PLA + TAX + PLA + TAY + PLP + LDA DVM_PTR +JSRADDR: JSR $0000 + PHP + STA DVM_PTR + TYA + PHA + TXA + PHA + LDA DVM_PTR + PHA + JMP DVM_DISPATCH + + .SEGMENT "INIT" +DVM_INIT: LDA #$EA ; NOP OPCODE + STA ENTER_DVM-1 + LDA #$4C ; JUMP OPCODE + STA ENTER_DVM + LDA #DVM + STA LINK_DVM+1 + LDA #DVMOPTBL_RELOC + JSR MEMSRC + LDA #DVM_OPTBL + JSR MEMDST + LDA #$6C + LDX #$00 + JSR MEMCPY ; RELOCATE TABLE TO LOW MEMORY + RTS +DVMOPTBL_RELOC: + .ORG $290 + +DVM_OPTBL: .ADDR LDL-1, LDL-1, LDL-1, LDL-1, LDL-1, LDL-1, DUP-1, DUP2-1 ; $00-$07 + .ADDR SWAP-1, LDC-1, LDZP-1, LD-1, LDP-1, LDPINC-1, LDPDEC-1, LDIND-1 ; $08-$0F + .ADDR POP-1, POP2-1, STZP-1, ST-1, STP-1, STPINC-1, STPDEC-1, STIND-1 ; $10-$17 + .ADDR EXT-1, NEG-1, NOT-1, ADD-1, SUB-1, L_AND-1, L_OR-1, L_XOR-1 ; $18-$1F + .ADDR BRZ-1, BRNZ-1, BRPOS-1, BRNEG-1, BREQU-1, BRNEQ-1, BRGT-1, BRLE-1 ; $20-$27 + .ADDR BRA-1, BRBE-1, BRNCH-1, DECJNZ-1, SHL-1, SHR-1, INCR-1, DECR-1 ; $28-$2F + .ADDR EXIT-1, JUMP-1, CALL-1, RET-1, CALL_02-1, SWTCH-1 ; $30-$37 diff --git a/src/except.s b/src/except.s new file mode 100755 index 0000000..6ddc1de --- /dev/null +++ b/src/except.s @@ -0,0 +1,231 @@ +;* +;* JAVA VIRTUAL MACHINE EXCEPTION SUPPORT FOR 6502 +;* + .INCLUDE "global.inc" + .INCLUDE "class.inc" + .INCLUDE "frame.inc" + .IMPORT PRBLNK,PRBYTE,COUT,CROUT,PRNTAX,KBWAIT + .IMPORT PUTS,PUTSLN,PRSTR,PRHSTR,PRSTRLN,MEMSRC,MEMDST,MEMCPY,MEMCLR + .IMPORT HMEM_PTR,HSTRPL_ADD + .IMPORT CLASS_STRING,CLASS_METHODPTR,RESOLVE_CLASS + .IMPORT CLASS_MATCH_NAME,CLASS_MATCH_DESC,RESOLVE_METHOD,CLASS_METHODPTR + .IMPORT ASYNC_STATIC + .IMPORT CURRENT_THREAD + .IMPORT VM_RESTART + .EXPORT EXCEPT_INIT,THROW_SYSEXCEPTN,THROW_INTERNALERR,UNHANDLED_EXCEPTN,CURRENTEXCEPTN,THREAD_TRACE + + .SEGMENT "INIT" + +EXCEPT_INIT: LDA #SYSTHROWSTR + JSR HSTRPL_ADD + STA HSYSTHROWSTR+1 + STX HSYSTHROWSTR+3 + LDA #SYSEXCEPTNNAMESTR + JSR HSTRPL_ADD + STA HSYSEXCEPTNNAMESTR+1 + STX HSYSEXCEPTNNAMESTR+3 + LDA #SYSEXCEPTNDESCSTR + JSR HSTRPL_ADD + STA HSYSEXCEPTNDESCSTR+1 + STX HSYSEXCEPTNDESCSTR+3 + LDA #THREAD_TRACE + STA LINK_DUMPSTACK+1 + RTS +SYSTHROWSTR: .BYTE 22,"apple2/SystemException" ; SYSTEM EXCEPTION CLASS +SYSEXCEPTNNAMESTR: .BYTE 20,"throwSystemException" ; THROW SYSTEM EXCEPTION METHOD NAME +SYSEXCEPTNDESCSTR: .BYTE 4,"(I)V" ; THROW SYSTEM EXCEPTION METHOD DESCRIPTOR + + .CODE + +UNHANDLED_EXCEPTN: PSTRLN "UNHANDLED EXCEPTION: " + TSX + LDA $0105,X + AND #$7F + TAY + STA $0105,X + JSR CLASS_STRING + JSR PRHSTR + JMP CROUT +THROW_SYSEXCEPTN: TAX ; SAVE INDEX AS METHOD PARAM + LDA #$00 + PHA + PHA + PHA + TXA + PHA + LDA HSYSTHROW + LDX HSYSTHROW+1 + BNE CALLSYSEXCPTN +HSYSTHROWSTR: LDA #$00 + LDX #$00 + JSR RESOLVE_CLASS + BCS :+ +HSYSEXCEPTNNAMESTR: LDA #$00 + LDX #$00 + JSR CLASS_MATCH_NAME ; SAVE MATCH NAME +HSYSEXCEPTNDESCSTR: LDA #$00 + LDX #$00 + JSR CLASS_MATCH_DESC ; SAVE MATCH TYPE + JSR RESOLVE_METHOD ; LOOK IT UP + BCS :+ ; METHOD NOT FOUND - REAL BAD + STA HSYSTHROW + STX HSYSTHROW+1 +CALLSYSEXCPTN: JSR ASYNC_STATIC + PLA + STA CURRENTEXCEPTN + PLA + STA CURRENTEXCEPTN+1 + PLA + STA CURRENTEXCEPTN+2 + PLA + STA CURRENTEXCEPTN+3 + RTS +: PERR "SYS EXCEPTION METHOD NOT FOUND!" +THROW_INTERNALERR: + SEI + JSR THREAD_TRACE +.IFDEF DEBUG +FOREVER: JMP FOREVER +.ENDIF + LDA #$FF + TAX + JMP VM_RESTART +THREAD_TRACE: +.IFDEF DEBUG + TSX + INX + INX + STX DUMP_TOS + JSR CROUT + PSTR "CURRENT THREAD: " + LDA CURRENT_THREAD + JSR PRBYTE + JSR CROUT + LDA HEXECFRAME ; SET FRAME POINTER + LDX HEXECFRAME+1 + BNE :+ + PSTRLN "NO CURRENT FRAME" + LDA #$FF + JMP DUMPSTACK +: JSR PRNTMETHD + LDA EXECPC + SEC + SBC EXECCODEBASE + TAX + INY + LDA EXECPC+1 + SBC EXECCODEBASE+1 + JSR PRNTAX + JSR CROUT + LDY #FRAMESP + LDA (FRAMEPTR),Y + PHA + JSR DUMPSTACK + PLA + STA DUMP_TOS +FRAMETRACE: LDY #FRAMELINKPREV+1 + LDA (FRAMEPTR),Y + BNE :+ + JSR CROUT +.IFDEF DEBUG_EXCEPT + JSR KBWAIT +.ENDIF + RTS +: DEY + TAX + LDA (FRAMEPTR),Y + CMP HEXECFRAME + BNE :+ + CPX HEXECFRAME+1 + BNE :+ + PERR "SELF-LINKED FRAMES!" + BRK +: JSR PRNTMETHD + LDY #FRAMEPC + LDA (FRAMEPTR),Y + INY + TAX + LDA (FRAMEPTR),Y + JSR PRNTAX + JSR CROUT + LDY #FRAMESP + LDA (FRAMEPTR),Y + PHA + JSR DUMPSTACK + PLA + STA DUMP_TOS + JMP FRAMETRACE +DUMPSTACK: PHA +; PSTRLN "EVAL STACK:" + PLA + TAY +DUMPSTKLP: CPY DUMP_TOS + BCS :+ + RTS +: BNE :+ + RTS +: DEY + STY TMP + TYA +; JSR PRBYTE + LDA #':' +; JSR COUT + LDY TMP + LDX $0100,Y + LDA $0101,Y +; JSR PRNTAX +; JSR CROUT + LDY TMP + DEY + BNE DUMPSTKLP +PRNTMETHD: STA HEXECFRAME + STX HEXECFRAME+1 + JSR HMEM_PTR + STA FRAMEPTR + STX FRAMEPTR+1 + LDY #FRAMEICLASS + LDA (FRAMEPTR),Y + PHA + TAY + JSR CLASS_STRING + JSR PRHSTR + LDA #'.' + JSR COUT + PLA + STA TMP + LDY #FRAMEMETHOD+1 + LDA (FRAMEPTR),Y + DEY + TAX + LDA (FRAMEPTR),Y + LDY TMP + JSR CLASS_METHODPTR ; GET POINTER TO METHOD + STA METHODPTR + STX METHODPTR+1 + LDY #METHODNAME+1 + LDA (METHODPTR),Y + DEY + TAX + LDA (METHODPTR),Y + JSR PRHSTR + LDY #METHODDESC+1 + LDA (METHODPTR),Y + DEY + TAX + LDA (METHODPTR),Y + JSR PRHSTR + LDA #'#' + JMP COUT +DUMP_TOS: .BYTE 0 +.ELSE + RTS +.ENDIF + .DATA + +HSYSTHROW: .WORD $0000 +CURRENTEXCEPTN: .BYTE 0,0,0,0 \ No newline at end of file diff --git a/src/frame.inc b/src/frame.inc new file mode 100755 index 0000000..f51b9ab --- /dev/null +++ b/src/frame.inc @@ -0,0 +1,14 @@ +;* +;* JAVA FRAME STRUCTURE +;* +FRAMEBLK_SIZE EQU $0400 ; 1K DEFAULT FRAME BLOCK SIZE +FRAMEMETHOD EQU $00 ; U2 - METHOD OFFSET +FRAMEICLASS EQU $02 ; U1 - CLASS INDEX +FRAMELOCALCNT EQU $03 ; U1 - NUMBER OF LOCAL VARIABLES +FRAMEHCODE EQU $04 ; U2 - CODE HANDLE +FRAMEPC EQU $06 ; U2 - SAVED INSTRUCTION PROGRAM COUNTER +FRAMELINKPREV EQU $08 ; U2 - PREVIOUS FRAME HANDLE +FRAMESP EQU $0A ; U1 - FRAME SP ENTRY VALUE (AFTER PARAMS POPPED) +FRAMETHROWABLE EQU $0B ; U3 - THROWN EXCEPTION INSIDE FRAME HANDLE+CLASS +FRAMESYNCHOBJ EQU $0E ; U2 - SYNCHRONIZED OBJECT +FRAMEBASESZ EQU $10 diff --git a/src/frame.s b/src/frame.s new file mode 100755 index 0000000..993ca84 --- /dev/null +++ b/src/frame.s @@ -0,0 +1,885 @@ +;* +;* JAVA VIRTUAL MACHINE FRAME/STACK SUPPORT FOR 6502 +;* +;* +;* FRAME BLOCKS ARE LINKED LIST OF PREDEFINED SIZES TO HOLD LOCAL VARIABLES AND A STACK +;* FOR EACH METHOD INVOCATION. A FRAME BLOCK CONTAINS AS MANY FRAMES AS WILL FIT. WHEN +;* SPANNING BLOCKS, THE FIRST FIELDS IN THE BLOCK IS THE PREVIOUS BLOCK AND STACK_PTR. +;* THE FRAME BLOCK IS ORGANIZED AS: +;* FRAME_PTR -> PREV HFRAME +;* FRAME 0 +;* ... +;* FRAME N +;* IF PREV HFRAME IS 0, THEN FRAME LIST IS EMPTY, THREAD IS FINISHED. +;* +;* A METHOD FRAME IS ORGANIZED AS: +;* VAR_BASE -> PARAMETERS/LOCAL VARIABLES +;* (BP),Y -> LOCAL VARIABLE POINTERS +;* RETURN ADDRESS = HMETHOD, PC +;* STACK_BASE -> STACK +;* ... +;* (SP),Y-> TOP OF STACK +;* +;* IF NEW FRAME WON'T FIT IN CURRENT FRAME BLOCK, ALLOCATE A NEW ONE AND LINK TO PREVIOUS +;* + .INCLUDE "global.inc" + .INCLUDE "class.inc" + .INCLUDE "frame.inc" + .IMPORT CROUT,COUT,PRSTR,KBWAIT,PRHSTR,PRHSTRLN + .IMPORT HMEM_ALLOC,HMEM_ALLOC_FIXED,HMEM_FREE,HMEM_LOCK,HMEM_UNLOCK,HMEM_UNLOCK_CODE + .IMPORT HMEM_PTR,HMEM_REF_INC,HMEM_REF_DEC + .IMPORT HSTR_HASH,STR_HASH,HSTRPL_ADD,HSTRPL_DEL + .IMPORT HCLASS_NAME,HCLASS_HNDL,HCLASS_ADD,HCLASS_INDEX,CLASS_STRING,CLASS_OF,CLASS_LOCK,CLASS_UNLOCK + .IMPORT CLASS_METHODPTR,CLASS_VIRTCODE,CLASS_LOCKMETHOD,CLASS_UNLOCKMETHOD + .IMPORT THREAD_PUSH_TLS,THREAD_POP_TLS,THREAD_LOCK,THREAD_UNLOCK,CURRENT_THREAD + .IMPORT HCODE_ACCESS,HCODE_UNACCESS,HCODE_LOCK,HCODE_UNLOCK,HCODE_ISBYTECODE + .IMPORT HCODE_GETLOCALS,HCODE_GETCLASS,HCODE_FLAGS,HCODE_GETHEXCEPT,HCODE_GETEXCEPTLEN + .IMPORT EXECBYTECODES,LOOKUPCLASSIDX + .IMPORT UNREF_OBJECT,SYSTHROW,THROW_INTERNALERR,CURRENTEXCEPTN + .EXPORT ASYNC_VIRTUAL,ASYNC_STATIC,INVOKE_VIRTUAL,INVOKE_SPECIAL,INVOKE_STATIC,EXIT_METHOD,CATCH_EXCEPTN + + .CODE +;* +;* INVOKE AN ASYNCHRONOUS METHOD. JSR HERE. +;* ENTRY: AX = METHOD OFFSET +;* Y = CLASS INDEX +;* +ASYNC_VIRTUAL: STY LOCKCLASS +.IFDEF DEBUG + STA METHDOFST + STX METHDOFST+1 +.ENDIF + JSR CLASS_LOCKMETHOD ; GET POINTER TO LOCKED METHOD + STA METHODPTR + STX METHODPTR+1 + LDY #METHODVINDEX+1 ; GET INDEX FOR VIRTUAL TABLE + LDA (METHODPTR),Y + DEY + STA TMP+1 + LDA (METHODPTR),Y + DEY + STA TMP + TSX + TXA + CLC + ADC (METHODPTR),Y ; SKIP METHOD PARAM SIZE + TAX + LDA $0105,X ; GET ICLASS FROM *THIS* REF + AND #$7F +.IFDEF DEBUG_INVOKE + BNE :+ + JMP NULL_THIS +: +.ELSE + BEQ NULL_THIS +.ENDIF + TAY + LDA TMP + LDX TMP+1 + JSR CLASS_VIRTCODE + JMP ASYNC_METHOD +ASYNC_STATIC: STY LOCKCLASS +.IFDEF DEBUG + STA METHDOFST + STX METHDOFST+1 +.ENDIF + JSR CLASS_LOCKMETHOD ; GET POINTER TO LOCKED METHOD + STA METHODPTR + STX METHODPTR+1 + LDY #METHODSTATICODE+1 ; GET STATIC CODE HANDLE + LDA (METHODPTR),Y + DEY + TAX + LDA (METHODPTR),Y +ASYNC_METHOD: STA HMETHODCODE + STX HMETHODCODE+1 +.IFDEF DEBUG_INVOKE + PSTR "INVOKING ASYNC METHOD:" + LDY LOCKCLASS + JSR CLASS_STRING + JSR HMEM_PTR + JSR PRSTR + LDA #'.' + JSR COUT + LDY #METHODNAME+1 + LDA (METHODPTR),Y + DEY + TAX + LDA (METHODPTR),Y + JSR HMEM_PTR + JSR PRSTR + LDY #METHODDESC+1 + LDA (METHODPTR),Y + DEY + TAX + LDA (METHODPTR),Y + JSR HMEM_PTR + JSR PRSTR + JSR CROUT +; JSR KBWAIT +.ENDIF + LDA HMETHODCODE + LDX HMETHODCODE+1 + JSR HCODE_ISBYTECODE ; CHECK FOR NATIVE METHOD + BEQ ASYNCBYTECODE + LDY LOCKCLASS + JSR CLASS_UNLOCKMETHOD ; UNLOCK METHOD STRUCTURE + LDA HMETHODCODE + LDX HMETHODCODE+1 + JSR HMEM_PTR + STA NATIVECODEPTR ; CALL NATIVE METHOD + STX NATIVECODEPTR+1 + CLC ; CLEAR CARRY + JMP (NATIVECODEPTR) +ASYNCBYTECODE: JSR SAVEPC_RELFRM ; SAVE EXECPC AND RELEASE FRAME + PLA ; SAVE RETURN ADDRESS + TAX ; IN TLS + PLA + JSR THREAD_PUSH_TLS + LDA HEXECFRAME + LDX HEXECFRAME+1 + JSR THREAD_PUSH_TLS + LDA #$00 ; ZERO OUT CURRENT FRAME + STA HEXECFRAME + STA HEXECFRAME+1 + JMP BUILD_FRAME +NULL_THIS: LDA #17 ; NULL *THIS* REF + JMP SYSTHROW +;* +;* INVOKE A METHOD. DON'T JSR HERE, JMP HERE. +;* ENTRY: AX = METHOD OFFSET +;* Y = CLASS INDEX +;* +INVOKE_VIRTUAL: STY LOCKCLASS +.IFDEF DEBUG + STA METHDOFST + STX METHDOFST+1 +.ENDIF + JSR CLASS_LOCKMETHOD ; GET POINTER TO LOCKED METHOD + STA METHODPTR + STX METHODPTR+1 + LDY #METHODVINDEX+1 ; GET INDEX FOR VIRTUAL TABLE + LDA (METHODPTR),Y + DEY + STA TMP+1 + LDA (METHODPTR),Y + DEY + STA TMP + TSX + TXA + CLC + ADC (METHODPTR),Y ; SKIP METHOD PARAM SIZE + TAX + LDA $0103,X ; GET ICLASS FROM *THIS* REF + AND #$7F + BEQ NULL_THIS + TAY + LDA TMP + LDX TMP+1 + JSR CLASS_VIRTCODE + JMP INVOKE_METHOD +INVOKE_SPECIAL: STY LOCKCLASS +.IFDEF DEBUG + STA METHDOFST + STX METHDOFST+1 +.ENDIF + JSR CLASS_LOCKMETHOD ; GET POINTER TO LOCKED METHOD + STA METHODPTR + STX METHODPTR+1 + LDY #METHODVINDEX+1 ; GET INDEX FOR VIRTUAL TABLE + LDA (METHODPTR),Y + DEY + TAX + LDA (METHODPTR),Y + LDY LOCKCLASS + JSR CLASS_VIRTCODE + JMP INVOKE_METHOD +INVOKE_STATIC: STY LOCKCLASS +.IFDEF DEBUG + STA METHDOFST + STX METHDOFST+1 +.ENDIF + JSR CLASS_LOCKMETHOD ; GET POINTER TO LOCKED METHOD + STA METHODPTR + STX METHODPTR+1 + LDY #METHODSTATICODE+1 ; GET STATIC CODE HANDLE + LDA (METHODPTR),Y + DEY + TAX + LDA (METHODPTR),Y +;* +;* INVOKE METHOD +;* ENTRY: AX = CODE HANDLE +;* +INVOKE_METHOD: STA HMETHODCODE + STX HMETHODCODE+1 +.IFDEF DEBUG_INVOKE + PSTR "INVOKING METHOD:" + LDY LOCKCLASS + JSR CLASS_STRING + JSR HMEM_PTR + JSR PRSTR + LDA #'.' + JSR COUT + LDY #METHODNAME+1 + LDA (METHODPTR),Y + DEY + TAX + LDA (METHODPTR),Y + JSR HMEM_PTR + JSR PRSTR + LDY #METHODDESC+1 + LDA (METHODPTR),Y + DEY + TAX + LDA (METHODPTR),Y + JSR HMEM_PTR + JSR PRSTR + JSR CROUT +; JSR KBWAIT +.ENDIF + LDA EXECPC ; INCREMENT EXECPC + CLC + ADC #$03 + STA EXECPC + BCC :+ + INC EXECPC+1 +: LDA HMETHODCODE + LDX HMETHODCODE+1 + JSR HCODE_ISBYTECODE ; CHECK FOR NATIVE METHOD + BEQ BUILD_FRAME + LDY LOCKCLASS + JSR CLASS_UNLOCKMETHOD ; UNLOCK METHOD STRUCTURE + LDA HMETHODCODE + LDX HMETHODCODE+1 + JSR HMEM_PTR + STA NATIVECODEPTR ; CALL NATIVE METHOD + STX NATIVECODEPTR+1 + CLC ; CLEAR CARRY + JSR :+ + SEI ; MAKE A SANE ENVIRONMENT ON RETURN + BIT LCBNK2 + BIT LCBNK2 + CLI + JMP EXECBYTECODES ; RETURN TO EXECUTING BYTECODES +: JMP (NATIVECODEPTR) +;* +;* BUILD A NEW FRAME FOR METHOD INVOCATION +;* A NEW FRAME BLOCK WILL BE ALLOCATED IF THE CURRENT +;* BLOCK CAN'T FIT THE NEW FRAME +;* ENTRY: METHODPTR = POINTER TO METHOD BEING CALLED +;* +BUILD_FRAME: +.IFDEF DEBUG + LDA $0101 ; CHECK FOR STACK OVERFLOW + CMP #$69 + BEQ :++ +: PERR "STACK OVERFLOW IN METHOD INVOKE" + BRK + JMP THROW_INTERNALERR +: LDA $0100 + CMP #$69 + BNE :-- +.ENDIF + JSR SAVEPC_RELFRM ; SAVE EXECPC AND RELEASE FRAME + LDA HMETHODCODE + LDX HMETHODCODE+1 + JSR HCODE_ACCESS ; ACCESS THIS CODE BLOCK + JSR HCODE_GETCLASS + STA CALLCLASS + JSR HCODE_GETLOCALS ; GET LOCAL VAR COUNT & SIZE IN BYTES + STY FRMVARS ; (INCLUDES PARAMETERS) + CLC + ADC #FRAMEBASESZ + BCC :+ + INX +: LDY #$00 + JSR HMEM_ALLOC ; ALLOCATE NEW FRAME + STA HLINKFRAME + STX HLINKFRAME+1 + JSR HMEM_LOCK + STA FRAMEPTR + STX FRAMEPTR+1 +.IFDEF DEBUG + LDY #FRAMEMETHOD + LDA METHDOFST + STA (FRAMEPTR),Y + INY + LDA METHDOFST+1 + STA (FRAMEPTR),Y + INY +.ELSE + LDY #FRAMEICLASS ; SAVE CLASS IN FRAME +.ENDIF + LDA CALLCLASS + STA (FRAMEPTR),Y + INY ; LDY #FRAMELOCALCNT + LDA FRMVARS ; SAVE LOCAL VAR COUNT + STA (FRAMEPTR),Y + INY ; LDY #FRAMEHCODE + LDA HMETHODCODE ; SAVE CODE HANDLE IN FRAME + STA (FRAMEPTR),Y + INY + LDA HMETHODCODE+1 + STA (FRAMEPTR),Y + INY ; LDY #FRAMEPC + LDA #$00 ; SET PC TO ENTRYPOINT + STA (FRAMEPTR),Y + INY + STA (FRAMEPTR),Y + INY ; LDY #FRAMEHPREV + LDA HEXECFRAME ; LINK TO PREVIOUS FRAME HANDLE + STA (FRAMEPTR),Y + INY + LDA HEXECFRAME+1 + STA (FRAMEPTR),Y + LDA HLINKFRAME + LDX HLINKFRAME+1 + JSR SETUP_FRAME + LDY #METHODDESC+1 + LDA (METHODPTR),Y ; GET POINTER TO DESC STRING + DEY + TAX + LDA (METHODPTR),Y + JSR HMEM_LOCK ; LOCK STRING IN PLACE + STA SCANPTR + STX SCANPTR+1 + LDY #$01 ; SKIP SIZE BYTE + STY SCANPOS + DEY + STY VARCNT + TSX ; COPY PARAMETERS INTO NEW LOCALS + TXA + LDY #METHODPARAMS + CLC + ADC (METHODPTR),Y ; ADD PARAM BYTE COUNT + TAX + STX STACKPOPPED + LDY #METHODACCESS ; CHECK FOR STATIC METHOD, Y = 0 + LDA (METHODPTR),Y + AND #$08 + BNE SCANPARAMTYPES + TXA + CLC + ADC #$04 + STA STACKPOPPED + TAX + BNE COPYREF ; COPY THIS REF PARAMETER +SCANPARAMTYPES: LDY SCANPOS ; SCAN PARAMETERS FOR REF TYPE + INY + LDA (SCANPTR),Y + CMP #')' ; END OF PARAM LIST + BNE SCANPTYPECHK + JMP ZEROLOCALTYPES +SCANPTYPECHK: CMP #'L' ; CHECK FOR REFERENCE + BEQ SCANTYPEREF + CMP #'[' ; CHECK FOR ARRAY + BEQ SCANTYPEARRAY + CMP #'J' + BEQ SCANLONG + STY SCANPOS ; PULL 32 BIT VALUE OFF STACK + LDY VARCNT +: LDA #$00 ; NON-REF TYPE + STA (BPT),Y + LDA $0100,X + DEX + STA (BP3),Y + LDA $0100,X + DEX + STA (BP2),Y + LDA $0100,X + DEX + STA (BP1),Y + LDA $0100,X + DEX + STA (BP0),Y + INC VARCNT + BNE SCANPARAMTYPES +SCANLONG: STY SCANPOS + LDY VARCNT + INY + LDA #$00 + STA (BPT),Y ; ZERO OUT HIWORD TYPE + DEY + INC VARCNT ; ADD TWO TO VARCNT TO MATCH UP LOCALS + BNE :- +SCANTYPEARRAY: INY ; EAT ARRAY + LDA (SCANPTR),Y + CMP #'[' + BEQ SCANTYPEARRAY + CMP #'L' ; FALL THRU FOR ARRAY OBJS + BNE INCREFCNT +SCANTYPEREF: INY + LDA (SCANPTR),Y + CMP #';' ; CHECK FOR END OF REFERENCE + BNE SCANTYPEREF +INCREFCNT: STY SCANPOS +COPYREF: LDY VARCNT + LDA #T_REF|$80 ; PULL REF VALUE OFF STACK + STA (BPT),Y + LDA $0100,X + DEX + STA (BP3),Y + LDA $0100,X + DEX + AND #$7F ; MASK OFF NOINC FLAG + STA (BP2),Y + LDA $0100,X + DEX + STA (BP1),Y + LDA $0100,X + DEX + STA (BP0),Y + LDA $0103,X ; CHECK NOINC FLAG + BMI SKIPREFINC + LDA (BP1),Y ; CHECK NULL REF + BEQ SKIPREFINC + STX STACKPOS + TAX + LDA (BP0),Y + JSR HMEM_REF_INC ; INCREMENT REF CNT + LDX STACKPOS +SKIPREFINC: INC VARCNT + JMP SCANPARAMTYPES +ZEROLOCALTYPES: LDX STACKPOPPED ; UPDATE STACK POINTER + TXS + LDY #FRAMESP ; SAVE SP FOR EXCEPTION + TXA + STA (FRAMEPTR),Y + LDY #FRAMELOCALCNT ; ZERO OUT REMAINING LOCALS + LDA (FRAMEPTR),Y + SEC + SBC VARCNT + BEQ EXECFRAME + TAX + LDA #$00 + LDY VARCNT +ZEROLOCALSLP: STA (BPT),Y + INY + DEX + BNE ZEROLOCALSLP +EXECFRAME: LDY #METHODDESC+1 + LDA (METHODPTR),Y ; UNLOCK DESC STRING + DEY + TAX + LDA (METHODPTR),Y + JSR HMEM_UNLOCK + JSR HCODE_UNACCESS ; DONE ACCESSING CODE PARAMTERS + LDY LOCKCLASS + JSR CLASS_UNLOCKMETHOD ; UNLOCK METHOD STRUCTURE + LDA HMETHODCODE + LDX HMETHODCODE+1 + JSR HCODE_FLAGS + AND #$20 ; CHECK FOR SYNCHRONIZED METHODS + BNE :+ + JMP EXECBYTECODES +: LDY #METHODACCESS ; CHECK FOR STATIC METHOD + LDA (METHODPTR),Y + AND #$08 + BEQ :+ + LDY CALLCLASS + JSR HCLASS_INDEX + BCC LOCKNLOAD ; SHOULD ALWAYS BE TAKEN + PERR "BAD SYNCH CLASS" +: LDA (BP1),Y ; Y = 0 + TAX + LDA (BP0),Y +LOCKNLOAD: PHA + LDY #FRAMESYNCHOBJ ; SAVE HCLASS IN FRAME FOR SYNCHRONIZATION + STA (FRAMEPTR),Y + INY + TXA + STA (FRAMEPTR),Y + PLA + JSR THREAD_LOCK ; LOCK OBJECT + JMP EXECBYTECODES +;* +;* SETUP FRAME POINTERS +;* ENTRY: AX = FRAME HANDLE +;* +SETUP_FRAME: STA HEXECFRAME ; SET NEW FRAME + STX HEXECFRAME+1 + JSR HMEM_LOCK ; LOCK FRAME IN PLACE, RETURN POINTER + STA FRAMEPTR + STX FRAMEPTR+1 + LDY #FRAMEHCODE+1 ; GET CODE SEGMENT + LDA (FRAMEPTR),Y + DEY + TAX + LDA (FRAMEPTR),Y + JSR HCODE_LOCK + STA EXECCODEBASE + STX EXECCODEBASE+1 + LDY #FRAMEPC ; SET PC POINTER + CLC ; ADD EXECPC OFFSET + ADC (FRAMEPTR),Y + INY + STA EXECPC + TXA + ADC (FRAMEPTR),Y + STA EXECPC+1 + LDY #FRAMEICLASS ; SET CLASS INDEX + LDA (FRAMEPTR),Y + STA IEXECCLASS + TAY + JSR CLASS_LOCK + CLC + ADC #(CLASSCONSTPL-CONSTPLRECSZ) ; INDEX IS 1 BASED + BCC :+ + INX +: STA EXECCONSTPL + STX EXECCONSTPL+1 + LDY #FRAMELOCALCNT + LDA (FRAMEPTR),Y ; SETUP BASE POINTERS + STA TMP + LDA FRAMEPTR + LDX FRAMEPTR+1 + CLC + ADC #FRAMEBASESZ + BCC :+ + INX + CLC +: STA BPT ; BASE POINTER - TYPE + STX BPT+1 + ADC TMP + BCC :+ + INX + CLC +: STA BP0 ; BASE POINTER - BYTE0 + STX BP0+1 + ADC TMP + BCC :+ + INX + CLC +: STA BP1 ; BASE POINTER - BYTE1 + STX BP1+1 + ADC TMP + BCC :+ + INX + CLC +: STA BP2 ; BASE POINTER - BYTE2 + STX BP2+1 + ADC TMP + BCC :+ + INX + CLC +: STA BP3 ; BASE POINTER - BYTE3 + STX BP3+1 +: RTS +;* +;* SAVE EXECPC AND FALL INTO RELEASE_FRAME +;* +SAVEPC_RELFRM: LDX HEXECFRAME+1 + BEQ :- + LDA HEXECFRAME + JSR HMEM_PTR + STA FRAMEPTR + STX FRAMEPTR+1 + LDY #FRAMEPC + LDA EXECPC ; SAVE INSTRUCTION PTR IN CURRENT FRAME + SEC ; SAVE AS OFFSET FROM CODEPTR + SBC EXECCODEBASE + STA (FRAMEPTR),Y + INY + LDA EXECPC+1 + SBC EXECCODEBASE+1 + STA (FRAMEPTR),Y +;* +;* RELEASE CURRENT FRAME'S MEMORY RESOURCES +;* +RELEASE_FRAME: LDY #FRAMEHCODE+1 ; EXIT CODE BLOCK + LDA (FRAMEPTR),Y + DEY + TAX + LDA (FRAMEPTR),Y + JSR HCODE_UNLOCK + LDA HEXECFRAME ; UNLOCK CURRENT FRAME + LDX HEXECFRAME+1 + JSR HMEM_UNLOCK + LDY IEXECCLASS + JMP CLASS_UNLOCK +;* +;* EXIT A METHOD, BREAK DOWN FRAME. +;* ENTRY: AX = REFERENCE NOT TO DELETE +;* +EXIT_METHOD: STA RETURN_REF + STX RETURN_REF+1 +.IFDEF DEBUG_INVOKE + PERR "EXITING METHOD" +; JSR KBWAIT +.ENDIF +.IFDEF DEBUG + LDA $0101 ; CHECK FOR STACK OVERFLOW + CMP #$69 + BEQ :++ +: PERR "STACK OVERFLOW IN EXIT METHOD" + BRK + JMP THROW_INTERNALERR +: LDA $0100 + CMP #$69 + BNE :-- +.ENDIF + LDA HEXECFRAME ; SET FRAME POINTER + LDX HEXECFRAME+1 + JSR HMEM_PTR + STA FRAMEPTR + STX FRAMEPTR+1 + LDY #FRAMELOCALCNT + LDA (FRAMEPTR),Y + TAY + BEQ CHECKSYNC +DEREFLOCALS: DEY + LDA (BPT),Y ; CHECK FOR LOCAL REF VAR + BPL NEXTLOCAL + LDA (BP1),Y + BEQ NEXTLOCAL ; CHECK FOR NULL REFERENCE + TAX + LDA (BP0),Y + CMP RETURN_REF + BNE UNREFLOCAL + CPX RETURN_REF+1 + BNE UNREFLOCAL ; MATCHES RETURN REF, DON'T DELETE + STY VARCNT + JSR HMEM_REF_DEC ; JUST DEC REF COUNT + LDY VARCNT + JMP NEXTLOCAL +UNREFLOCAL: TYA + PHA + LDA RETURN_REF + PHA + LDA RETURN_REF+1 + PHA + LDA (BP3),Y + PHA + LDA (BP2),Y + PHA + TXA + PHA + LDA (BP0),Y + PHA + JSR UNREF_OBJECT + PLA + STA RETURN_REF+1 + PLA + STA RETURN_REF + PLA + TAY +NEXTLOCAL: CPY #$00 + BNE DEREFLOCALS + LDA HEXECFRAME ; RE-SET FRAME POINTER + LDX HEXECFRAME+1 + JSR HMEM_PTR + STA FRAMEPTR + STX FRAMEPTR+1 +CHECKSYNC: LDY #FRAMEHCODE+1 + LDA (FRAMEPTR),Y + DEY + TAX + LDA (FRAMEPTR),Y + JSR HCODE_FLAGS + AND #$20 ; CHECK FOR SYNCHRONIZED METHODS + BEQ UNLINKFRAME + LDY #FRAMESYNCHOBJ+1 + LDA (FRAMEPTR),Y + DEY + TAX + LDA (FRAMEPTR),Y + JSR THREAD_UNLOCK ; UNLOCK OBJECT +UNLINKFRAME: LDY #FRAMELINKPREV ; GET PREVIOUS FRAME + LDA (FRAMEPTR),Y + INY + STA HLINKFRAME + LDA (FRAMEPTR),Y + STA HLINKFRAME+1 + JSR RELEASE_FRAME ; RELEASE CURRENT FRAME + LDA HEXECFRAME + LDX HEXECFRAME+1 + JSR HMEM_FREE ; FREE UP ITS MEMORY + LDA HLINKFRAME + LDX HLINKFRAME+1 + BEQ ASYNC_EXIT + JSR SETUP_FRAME +.IFDEF DEBUG_INVOKE + PSTR "RETURNING TO METHOD:" + LDY #FRAMEICLASS ; GET METHOD CLASS + LDA (FRAMEPTR),Y + TAY + STY CALLCLASS + JSR CLASS_STRING + JSR PRHSTR + LDA #'.' + JSR COUT + LDY #FRAMEMETHOD+1 + LDA (FRAMEPTR),Y + DEY + TAX + LDA (FRAMEPTR),Y + STA METHDOFST + STX METHDOFST+1 + LDY CALLCLASS + JSR CLASS_LOCKMETHOD ; GET POINTER TO LOCKED METHOD + STA METHODPTR + STX METHODPTR+1 + LDY #METHODNAME+1 + LDA (METHODPTR),Y + DEY + TAX + LDA (METHODPTR),Y + JSR PRHSTR + LDY #METHODDESC+1 + LDA (METHODPTR),Y + DEY + TAX + LDA (METHODPTR),Y + JSR PRHSTR + JSR CROUT + LDY CALLCLASS + JSR CLASS_UNLOCKMETHOD +; JSR KBWAIT +.ENDIF + LDA EXECFLAGS ; CHECK FOR EXCEPTION + BMI CATCH_EXCEPTN + JMP EXECBYTECODES +ASYNC_EXIT: JSR THREAD_POP_TLS ; RETURN FROM ASYNC METHOD + STA HEXECFRAME + STX HEXECFRAME+1 + CPX #$00 + BEQ :+ + JSR SETUP_FRAME +: +.IFDEF DEBUG_INVOKE + PERR "ASYNC RETURN" +; JSR KBWAIT +.ENDIF + JSR THREAD_POP_TLS + PHA + TXA + PHA + ASL EXECFLAGS ; MOVE EXCEPTION FLAG INTO CARRY + RTS +;* +;* AN EXCEPTION IS IN PROGRESS - SEARCH FOR MATCHING CATCH CLAUSE +;* +CATCH_EXCEPTN: +.IFDEF DEBUG_EXCEPT +; .IMPORT THREAD_TRACE +; JSR THREAD_TRACE + PERR "CATCH EXCEPTION" + JSR KBWAIT +.ENDIF + PLA ; POP EXCEPTION + STA CURRENTEXCEPTN + PLA + STA CURRENTEXCEPTN+1 + PLA + STA CURRENTEXCEPTN+2 + PLA + STA CURRENTEXCEPTN+3 + LDY #FRAMESP ; RESTORE SP TO CALLING DEPTH + LDA (FRAMEPTR),Y ; PUSH EXCEPTION BACK ON STACK + TAX + TXS + LDA CURRENTEXCEPTN+3 + PHA + LDA CURRENTEXCEPTN+2 + PHA + LDA CURRENTEXCEPTN+1 + PHA + LDA CURRENTEXCEPTN + PHA + LDY #FRAMEPC+1 ; RECOVER PC POINTER + LDA (FRAMEPTR),Y + DEY + STA EXCEPTPC+1 + LDA (FRAMEPTR),Y + STA EXCEPTPC + LDY #FRAMEHCODE+1 ; GET CODE SEGMENT + LDA (FRAMEPTR),Y + DEY + TAX + LDA (FRAMEPTR),Y + JSR HCODE_ACCESS ; ACCESS THIS CODE BLOCK + JSR HCODE_GETHEXCEPT + STA HEXCEPTTBL + STX HEXCEPTTBL+1 + CPX #$00 + BEQ NOTCAUGHT + JSR HMEM_LOCK + STA EXCEPTPTR + STX EXCEPTPTR+1 + JSR HCODE_GETEXCEPTLEN + STX EXCEPTCNT+1 +SEARCHEXCEPT: STA EXCEPTCNT + ORA EXCEPTCNT+1 + BNE CHKRANGE +NOTCAUGHT: JSR HCODE_UNACCESS + LDA HEXCEPTTBL + LDX HEXCEPTTBL+1 + BEQ :+ + JSR HMEM_UNLOCK +: LDA RETURN_REF + LDX RETURN_REF+1 + JMP EXIT_METHOD ; BACKTRACE FRAMES +CHKRANGE: LDY #$03 ; CHECK HANDLER END RANGE + LDA EXCEPTPC + CMP (EXCEPTPTR),Y + DEY + LDA EXCEPTPC+1 + SBC (EXCEPTPTR),Y + BCS NEXTEXCEPT + DEY ; CHECK HANDLER START RANGE + LDA EXCEPTPC + CMP (EXCEPTPTR),Y + DEY + LDA EXCEPTPC+1 + SBC (EXCEPTPTR),Y + BCC NEXTEXCEPT + LDY #$06 ; CHECK HANDLER EXCEPTION + LDA (EXCEPTPTR),Y + INY + TAX + LDA (EXCEPTPTR),Y + CMP #$00 + BNE :+ + CPX #$00 + BEQ CAUGHTEXCEPT +: JSR LOOKUPCLASSIDX + LDA CURRENTEXCEPTN+2 + AND #$7F + JSR CLASS_OF ; IS EXCEPTION A CLASS OF HANDLER + BCS NEXTEXCEPT +CAUGHTEXCEPT: LDY #$05 ; GET HANDLER PC + LDA (EXCEPTPTR),Y + DEY + CLC + ADC EXECCODEBASE ; SET PC PTR + STA EXECPC + LDA (EXCEPTPTR),Y + ADC EXECCODEBASE+1 + STA EXECPC+1 + JSR HCODE_UNACCESS + LDA HEXCEPTTBL + LDX HEXCEPTTBL+1 + JSR HMEM_UNLOCK + ASL EXECFLAGS ; CLEAR EXCEPTION FLAG + JMP EXECBYTECODES ; EXECUTE HANDLER +NEXTEXCEPT: LDA EXCEPTPTR + CLC + ADC #$08 + BCC :+ + INC EXCEPTPTR+1 +: STA EXCEPTPTR + LDA EXCEPTCNT + SEC + SBC #$01 + BCS :+ + DEC EXCEPTCNT+1 +: JMP SEARCHEXCEPT + + .DATA + +HEXCEPTTBL: +HLINKFRAME: .RES 2 +EXCEPTPC: +METHDOFST: .RES 2 + diff --git a/src/global.inc b/src/global.inc new file mode 100755 index 0000000..667c364 --- /dev/null +++ b/src/global.inc @@ -0,0 +1,955 @@ +;***************************************************************************** +;* +;* GNU GENERAL PUBLIC LICENSE +;* Version 2, June 1991 +;* +;* Copyright (C) 1989, 1991 Free Software Foundation, Inc., +;* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;* Everyone is permitted to copy and distribute verbatim copies +;* of this license document, but changing it is not allowed. +;* +;* Preamble +;* +;* The licenses for most software are designed to take away your +;* freedom to share and change it. By contrast, the GNU General Public +;* License is intended to guarantee your freedom to share and change free +;* software--to make sure the software is free for all its users. This +;* General Public License applies to most of the Free Software +;* Foundation's software and to any other program whose authors commit to +;* using it. (Some other Free Software Foundation software is covered by +;* the GNU Lesser General Public License instead.) You can apply it to +;* your programs, too. +;* +;* When we speak of free software, we are referring to freedom, not +;* price. Our General Public Licenses are designed to make sure that you +;* have the freedom to distribute copies of free software (and charge for +;* this service if you wish), that you receive source code or can get it +;* if you want it, that you can change the software or use pieces of it +;* in new free programs; and that you know you can do these things. +;* +;* To protect your rights, we need to make restrictions that forbid +;* anyone to deny you these rights or to ask you to surrender the rights. +;* These restrictions translate to certain responsibilities for you if you +;* distribute copies of the software, or if you modify it. +;* +;* For example, if you distribute copies of such a program, whether +;* gratis or for a fee, you must give the recipients all the rights that +;* you have. You must make sure that they, too, receive or can get the +;* source code. And you must show them these terms so they know their +;* rights. +;* +;* We protect your rights with two steps: (1) copyright the software, and +;* (2) offer you this license which gives you legal permission to copy, +;* distribute and/or modify the software. +;* +;* Also, for each author's protection and ours, we want to make certain +;* that everyone understands that there is no warranty for this free +;* software. If the software is modified by someone else and passed on, we +;* want its recipients to know that what they have is not the original, so +;* that any problems introduced by others will not reflect on the original +;* authors' reputations. +;* +;* Finally, any free program is threatened constantly by software +;* patents. We wish to avoid the danger that redistributors of a free +;* program will individually obtain patent licenses, in effect making the +;* program proprietary. To prevent this, we have made it clear that any +;* patent must be licensed for everyone's free use or not licensed at all. +;* +;* The precise terms and conditions for copying, distribution and +;* modification follow. +;* +;* GNU GENERAL PUBLIC LICENSE +;* TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION +;* +;* 0. This License applies to any program or other work which contains +;* a notice placed by the copyright holder saying it may be distributed +;* under the terms of this General Public License. The "Program", below, +;* refers to any such program or work, and a "work based on the Program" +;* means either the Program or any derivative work under copyright law: +;* that is to say, a work containing the Program or a portion of it, +;* either verbatim or with modifications and/or translated into another +;* language. (Hereinafter, translation is included without limitation in +;* the term "modification".) Each licensee is addressed as "you". +;* +;* Activities other than copying, distribution and modification are not +;* covered by this License; they are outside its scope. The act of +;* running the Program is not restricted, and the output from the Program +;* is covered only if its contents constitute a work based on the +;* Program (independent of having been made by running the Program). +;* Whether that is true depends on what the Program does. +;* +;* 1. You may copy and distribute verbatim copies of the Program's +;* source code as you receive it, in any medium, provided that you +;* conspicuously and appropriately publish on each copy an appropriate +;* copyright notice and disclaimer of warranty; keep intact all the +;* notices that refer to this License and to the absence of any warranty; +;* and give any other recipients of the Program a copy of this License +;* along with the Program. +;* +;* You may charge a fee for the physical act of transferring a copy, and +;* you may at your option offer warranty protection in exchange for a fee. +;* +;* 2. You may modify your copy or copies of the Program or any portion +;* of it, thus forming a work based on the Program, and copy and +;* distribute such modifications or work under the terms of Section 1 +;* above, provided that you also meet all of these conditions: +;* +;* a) You must cause the modified files to carry prominent notices +;* stating that you changed the files and the date of any change. +;* +;* b) You must cause any work that you distribute or publish, that in +;* whole or in part contains or is derived from the Program or any +;* part thereof, to be licensed as a whole at no charge to all third +;* parties under the terms of this License. +;* +;* c) If the modified program normally reads commands interactively +;* when run, you must cause it, when started running for such +;* interactive use in the most ordinary way, to print or display an +;* announcement including an appropriate copyright notice and a +;* notice that there is no warranty (or else, saying that you provide +;* a warranty) and that users may redistribute the program under +;* these conditions, and telling the user how to view a copy of this +;* License. (Exception: if the Program itself is interactive but +;* does not normally print such an announcement, your work based on +;* the Program is not required to print an announcement.) +;* +;* These requirements apply to the modified work as a whole. If +;* identifiable sections of that work are not derived from the Program, +;* and can be reasonably considered independent and separate works in +;* themselves, then this License, and its terms, do not apply to those +;* sections when you distribute them as separate works. But when you +;* distribute the same sections as part of a whole which is a work based +;* on the Program, the distribution of the whole must be on the terms of +;* this License, whose permissions for other licensees extend to the +;* entire whole, and thus to each and every part regardless of who wrote it. +;* +;* Thus, it is not the intent of this section to claim rights or contest +;* your rights to work written entirely by you; rather, the intent is to +;* exercise the right to control the distribution of derivative or +;* collective works based on the Program. +;* +;* In addition, mere aggregation of another work not based on the Program +;* with the Program (or with a work based on the Program) on a volume of +;* a storage or distribution medium does not bring the other work under +;* the scope of this License. +;* +;* 3. You may copy and distribute the Program (or a work based on it, +;* under Section 2) in object code or executable form under the terms of +;* Sections 1 and 2 above provided that you also do one of the following: +;* +;* a) Accompany it with the complete corresponding machine-readable +;* source code, which must be distributed under the terms of Sections +;* 1 and 2 above on a medium customarily used for software interchange; or, +;* +;* b) Accompany it with a written offer, valid for at least three +;* years, to give any third party, for a charge no more than your +;* cost of physically performing source distribution, a complete +;* machine-readable copy of the corresponding source code, to be +;* distributed under the terms of Sections 1 and 2 above on a medium +;* customarily used for software interchange; or, +;* +;* c) Accompany it with the information you received as to the offer +;* to distribute corresponding source code. (This alternative is +;* allowed only for noncommercial distribution and only if you +;* received the program in object code or executable form with such +;* an offer, in accord with Subsection b above.) +;* +;* The source code for a work means the preferred form of the work for +;* making modifications to it. For an executable work, complete source +;* code means all the source code for all modules it contains, plus any +;* associated interface definition files, plus the scripts used to +;* control compilation and installation of the executable. However, as a +;* special exception, the source code distributed need not include +;* anything that is normally distributed (in either source or binary +;* form) with the major components (compiler, kernel, and so on) of the +;* operating system on which the executable runs, unless that component +;* itself accompanies the executable. +;* +;* If distribution of executable or object code is made by offering +;* access to copy from a designated place, then offering equivalent +;* access to copy the source code from the same place counts as +;* distribution of the source code, even though third parties are not +;* compelled to copy the source along with the object code. +;* +;* 4. You may not copy, modify, sublicense, or distribute the Program +;* except as expressly provided under this License. Any attempt +;* otherwise to copy, modify, sublicense or distribute the Program +;* void, and will automatically terminate your rights under this License. +;* However, parties who have received copies, or rights, from you under +;* this License will not have their licenses terminated so long as such +;* parties remain in full compliance. +;* +;* 5. You are not required to accept this License, since you have not +;* signed it. However, nothing else grants you permission to modify or +;* distribute the Program or its derivative works. These actions are +;* prohibited by law if you do not accept this License. Therefore, by +;* modifying or distributing the Program (or any work based on the +;* Program), you indicate your acceptance of this License to do so, and +;* all its terms and conditions for copying, distributing or modifying +;* the Program or works based on it. +;* +;* 6. Each time you redistribute the Program (or any work based on the +;* Program), the recipient automatically receives a license from the +;* original licensor to copy, distribute or modify the Program subject to +;* these terms and conditions. You may not impose any further +;* restrictions on the recipients' exercise of the rights granted herein. +;* You are not responsible for enforcing compliance by third parties to +;* this License. +;* +;* 7. If, as a consequence of a court judgment or allegation of patent +;* infringement or for any other reason (not limited to patent issues), +;* conditions are imposed on you (whether by court order, agreement or +;* otherwise) that contradict the conditions of this License, they do not +;* excuse you from the conditions of this License. If you cannot +;* distribute so as to satisfy simultaneously your obligations under this +;* License and any other pertinent obligations, then as a consequence you +;* may not distribute the Program at all. For example, if a patent +;* license would not permit royalty-free redistribution of the Program by +;* all those who receive copies directly or indirectly through you, then +;* the only way you could satisfy both it and this License would be to +;* refrain entirely from distribution of the Program. +;* +;* If any portion of this section is held invalid or unenforceable under +;* any particular circumstance, the balance of the section is intended to +;* apply and the section as a whole is intended to apply in other +;* circumstances. +;* +;* It is not the purpose of this section to induce you to infringe any +;* patents or other property right claims or to contest validity of any +;* such claims; this section has the sole purpose of protecting the +;* integrity of the free software distribution system, which is +;* implemented by public license practices. Many people have made +;* generous contributions to the wide range of software distributed +;* through that system in reliance on consistent application of that +;* system; it is up to the author/donor to decide if he or she is willing +;* to distribute software through any other system and a licensee cannot +;* impose that choice. +;* +;* This section is intended to make thoroughly clear what is believed to +;* be a consequence of the rest of this License. +;* +;* 8. If the distribution and/or use of the Program is restricted in +;* certain countries either by patents or by copyrighted interfaces, the +;* original copyright holder who places the Program under this License +;* may add an explicit geographical distribution limitation excluding +;* those countries, so that distribution is permitted only in or among +;* countries not thus excluded. In such case, this License incorporates +;* the limitation as if written in the body of this License. +;* +;* 9. The Free Software Foundation may publish revised and/or new versions +;* of the General Public License from time to time. Such new versions will +;* be similar in spirit to the present version, but may differ in detail to +;* address new problems or concerns. +;* +;* Each version is given a distinguishing version number. If the Program +;* specifies a version number of this License which applies to it and "any +;* later version", you have the option of following the terms and conditions +;* either of that version or of any later version published by the Free +;* Software Foundation. If the Program does not specify a version number of +;* this License, you may choose any version ever published by the Free Software +;* Foundation. +;* +;* 10. If you wish to incorporate parts of the Program into other free +;* programs whose distribution conditions are different, write to the author +;* to ask for permission. For software which is copyrighted by the Free +;* Software Foundation, write to the Free Software Foundation; we sometimes +;* make exceptions for this. Our decision will be guided by the two goals +;* of preserving the free status of all derivatives of our free software and +;* of promoting the sharing and reuse of software generally. +;* +;* NO WARRANTY +;* +;* 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +;* FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +;* OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +;* PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +;* OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +;* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +;* TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +;* PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +;* REPAIR OR CORRECTION. +;* +;* 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +;* WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +;* REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +;* INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +;* OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +;* TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +;* YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +;* PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +;* POSSIBILITY OF SUCH DAMAGES. +;* +;***************************************************************************** +;* +;* Copyright 2010, David Schmenk +;* +;***************************************************************************** + +;********************************************************** +;* +;* GLOBAL DEFINES +;* +;********************************************************** +;* +;* DEBUG OPTIONS +;* +;DEBUG = 1 +;DEBUG_BREAK = 1 +;DEBUG_DUMP = 1 ; SLOT TO DUMP TO +;DEBUG_TIMER = 1 +;DEBUG_MEMMGR = 1 +;DEBUG_GC = 1 +;DEBUG_LOCK = 1 +;DEBUG_LOAD = 1 +;DEBUG_INVOKE = 1 +;DEBUG_INTERP = 1 +;DEBUG_THREAD = 1 +;DEBUG_FINALIZE = 1 +;DEBUG_EXCEPT = 1 +;DEBUG_PARAMS = 1 +;DEBUG_DVM = 1 +;DEBUG_SWAP = 1 +;* +;* HANDY MACROS +;* +.DEFINE EQU = +.IFDEF DEBUG +.MACRO PERR MSG + .IMPORT PUTSLN + JSR PUTSLN + .ASCIIZ MSG +.ENDMACRO +.ELSE +.MACRO PERR MSG +.ENDMACRO +.ENDIF +.MACRO PSTR MSG + .IMPORT PUTS + JSR PUTS + .ASCIIZ MSG +.ENDMACRO +.MACRO PSTRLN MSG + .IMPORT PUTSLN + JSR PUTSLN + .ASCIIZ MSG +.ENDMACRO +; +;********************************************************** +;* +;* SYSTEM LIMITS AND OPTIONS +;* +;********************************************************** +; +MAX_THREADS EQU 4 ; MAX THREADS ALLOWED +FLOATING_POINT EQU 1 ; SINGLE PRECISION FLOATING POINT OPERATIONS +IDLE_GC EQU 1 ; DO GC DURING IDLE LOOP +IDLE_GC_DELAY EQU 1 ; DELAY BETWEEN GC DURING IDLE LOOP +IDLE_GC_WAIT EQU 16 ; DELAY BEFORE STARTING GC DURING IDLE LOOP +SWAPPING EQU 1 ; MEMORY HANDLE SWAPPING TO DISK +;BIGMEM EQU 1 ; 128K MEMORY SUPPORT FOR //C AND //E +; +;********************************************************** +;* +;* ZERO PAGE LOCATIONS +;* +;********************************************************** +; +OPJMP EQU $01 ; CONTAINS A JMP INTRUCTION +OPADDR EQU $02 ; CONTAINS ADDRESS OF JMP INSTRUCTION +OPCNT EQU $04 +;* +;* LOWERCASE MASKS FOR CONSOLE I/O +;* +LCOUT_MASK EQU $06 +LCIN_MASK EQU $07 +;* +;* THREAD/BYTECODE INTERPRETER ZERO PAGE LOCATIONS +;* +ZP_THREAD_STATE EQU $0A +ZP_THREAD_SIZE EQU $14 +EXECFLAGS EQU $0A +IEXECCLASS EQU $0B ; INDEX TO CURRENT CLASS +EXECCONSTPL EQU $0C ; POINTER TO CONSTANT POOL +HEXECFRAME EQU $0E ; HANDLE TO CURRENT FRAME +EXECPC EQU $10 ; PROGRAM COUNTER +EXECCODEBASE EQU $12 ; POINTER TO CODE SEGMENT +BPT EQU $14 ; BASE TYPE POINTER +BP0 EQU $16 ; BASE BYTE0 POINTER +BP1 EQU $18 ; BASE BYTE1 POINTER +BP2 EQU $1A ; BASE BYTE2 POINTER +BP3 EQU $1C ; BASE BYTE3 POINTER +;* +;* CODE MANAGER ZERO PAGE LOCATIONS +;* +CODEBLKPTR EQU $56 +CODECOPYPTR EQU $58 +;* +;* OPCODE INTERPRETER ZERO PAGE LOCATIONS +;* +ICONST EQU $60 +PCINC EQU $60 +CONSTPTR EQU $62 +ARRAYPTR EQU $62 +FIELDPTR EQU $62 +ARRAYHNDL EQU $62 +TARGETCLASS EQU $64 +TARGETOBJ EQU $66 +TARGETSIZE EQU $68 +TARGETOFFSET EQU $68 +TARGETTYPE EQU $6A +TARGETDEPTH EQU $6E +ADEPTH EQU $6F +;* +;* SWITCH OPCODE ZERO PAGE LOCATIONS +;* +TABLEIDX EQU $64 +TABLEPTR EQU $6A +MATCHPTR EQU $6C +MATCHCNT EQU $6E +;* +;* INT MATH ZERO PAGE LOCATIONS +;* +MULTPLR EQU $60 +MULTPLND EQU $64 +PROD EQU $68 +MULIDX EQU $6C +MULSIGN EQU $6D +DVDND EQU $60 +DVSR EQU $64 +REMNDR EQU $68 +DVSIGN EQU $6C +;* +;* FLOATING POINT MATH ZERO PAGE LOCATIONS +;* +FP1MAN0 EQU $60 +FP1MAN1 EQU $61 +FP1MAN2 EQU $62 +FP1MAN3 EQU $63 +FP1SGN EQU $63 +FP1EXP EQU $64 +FP2MAN0 EQU $65 +FP2MAN1 EQU $66 +FP2MAN2 EQU $67 +FP2MAN3 EQU $68 +FP2SGN EQU $68 +FP2EXP EQU $69 +FPMAN0 EQU $6A +FPMAN1 EQU $6B +FPMAN2 EQU $6C +FPMAN3 EQU $6D +FPSGN EQU $6E +FPEXP EQU $6F +;* +;* FRAME MANAGER ZERO PAGE LOCATIONS +;* +RETURN_REF EQU $60 +SCANPTR EQU $62 +FRAMEPTR EQU $64 +EXCEPTPTR EQU $66 +STACKPOS EQU $66 +SCANPOS EQU $67 +EXCEPTCNT EQU $68 +STACKPOPPED EQU $68 +VARCNT EQU $69 +CALLCLASS EQU $6A +LOCKCLASS EQU $6B +FRMVARS EQU $6C + +;* +;* DAVE'S VIRTUAL MACHINE BYTECODE INTERPRETER ZERO PAGE LOCATIONS +;* +DVM_PC EQU $6C ; PROGRAM COUNTER +DVM_PTR EQU $6E ; MEMORY POINTER +;* +;* NATIVE METHOD ZERO PAGE LOCATIONS +;* +NATIVECODEPTR EQU $A0 +NATIVE_00 EQU $A0 +NATIVE_01 EQU $A1 +HMETHODCODE EQU $A2 +NATIVE_02 EQU $A2 +NATIVE_03 EQU $A3 +NATIVE_04 EQU $A4 +NATIVE_05 EQU $A5 +NATIVE_06 EQU $A6 +NATIVE_07 EQU $A7 +NATIVE_08 EQU $A8 +NATIVE_09 EQU $A9 +NATIVE_0A EQU $AA +NATIVE_0B EQU $AB +NATIVE_0C EQU $AC +NATIVE_0D EQU $AD +NATIVE_0E EQU $AE +NATIVE_0F EQU $AF +;* +;* SYSTEM CLASS ZERO PAGE LOCATIONS +;* +CCLASSPTR EQU $B0 +CCLASSCNT EQU $B2 +CCLASSSUPR EQU $B3 +CCLASSINDEX EQU $B4 +CCLASSNAME EQU $B6 +CCLASSDESC EQU $B8 +CCTBLPTR EQU $BA +CCTBLOFST EQU $BA +CCINSTPTR EQU $BC +CCINST EQU $BE +;* +;* CLASS LOADER/FRAME HANDLER ZERO PAGE LOCATIONS +;* +METHODPTR EQU $C0 +CLBUFFPTR EQU $C0 +CLBUFFOFST EQU $C2 +CLBUFFPAGE EQU $C3 +SUPERPTR EQU $C2 +CLASSLDPTR EQU $C4 +LDPTR EQU $C6 +LDCNT EQU $C8 +ACNT EQU $CA +CLDPTR EQU $CC +CCNT EQU $CE +VCNT EQU $CE +;* +;* STRING POOL ZERO PAGE LOCATIONS +;* +STRPTR EQU $D0 +HSTR EQU $D2 +STRMATCHPTR EQU $D4 +STRHASH EQU $D6 +HSTRNEXT EQU $D8 +REFCNT EQU $DA +;* +;* UTILITIES ZERO PAGE LOCATIONS +;* +SRCADDR EQU $DC +DSTADDR EQU $DE +;* +;* GARBAGE COLLECTION ZERO PAGE LOCATIONS +;* +GCHNDL EQU $E0 +GCMPTR EQU $E2 +GCMEND EQU $E4 +GCMLEN EQU $E4 +GCTMP EQU $E6 +GCBEST EQU $E8 +GCNEIGHBOR EQU $EA +GCNEEDED EQU $EC +;* +;* FINALIZER ZERO PAGE LOCATIONS +;* +FINPTR EQU $EE +;* +;* MEMORY MANAGER ZERO PAGE LOCATIONS +;* +HUNUSED EQU $F0 +HFREE EQU $F2 +HNDL EQU $F4 +MPTR EQU $F6 +MLEN EQU $F8 +MEND EQU $FA +TMP EQU $FC +TMPTR EQU $FC +HBEST EQU $FE +; +;********************************************************** +;* +;* EXTERNAL LINKEAGE JUMP TABLE +;* +;********************************************************** +; +LINK_TABLE EQU $0300 +LINK_YIELD EQU LINK_TABLE+$00 +LINK_LOCKENTER EQU LINK_TABLE+$02 +LINK_LOCKEXIT EQU LINK_TABLE+$04 +; +LINK_HMEMPTR EQU LINK_TABLE+$06 +LINK_HMEMALLOC EQU LINK_TABLE+$08 +LINK_HMEMALLOCFIXED EQU LINK_TABLE+$0A +LINK_HMEMFREE EQU LINK_TABLE+$0C +LINK_HMEMLOCK EQU LINK_TABLE+$0E +LINK_HMEMUNLOCK EQU LINK_TABLE+$10 +; +LINK_THREADNEW EQU LINK_TABLE+$12 +LINK_THREADPUSH EQU LINK_TABLE+$14 +LINK_THREADSTART EQU LINK_TABLE+$16 +LINK_THREADEXIT EQU LINK_TABLE+$18 +LINK_THREADKILL EQU LINK_TABLE+$1A +LINK_THREADGETCURRENT EQU LINK_TABLE+$1C +LINK_THREADSETTIMEOUTL EQU LINK_TABLE+$1E +LINK_THREADSETTIMEOUTH EQU LINK_TABLE+$20 +LINK_THREADNOTIMEOUT EQU LINK_TABLE+$22 +LINK_THREADSETSTATE EQU LINK_TABLE+$24 +LINK_THREADGETSTATE EQU LINK_TABLE+$26 +LINK_THREADSETPRIORITY EQU LINK_TABLE+$28 +LINK_THREADGETPRIORITY EQU LINK_TABLE+$2A +LINK_THREADSETCLASS EQU LINK_TABLE+$2C +LINK_THREADSETREF EQU LINK_TABLE+$2E +LINK_THREADGETCLASS EQU LINK_TABLE+$30 +LINK_THREADGETREF EQU LINK_TABLE+$32 +LINK_THREADWAITIO EQU LINK_TABLE+$34 +LINK_THREADNOTIFYIO EQU LINK_TABLE+$36 +LINK_SYSTEMTIC EQU LINK_TABLE+$38 +LINK_GETTICL EQU LINK_TABLE+$3A +LINK_GETTICH EQU LINK_TABLE+$3C +; +LINK_MEMSRC EQU LINK_TABLE+$3E +LINK_MEMDST EQU LINK_TABLE+$40 +LINK_MEMCPY EQU LINK_TABLE+$42 +LINK_MEMCLR EQU LINK_TABLE+$44 +; +LINK_HSTRADD EQU LINK_TABLE+$46 +; +SAVEZPIRQ EQU LINK_TABLE+$49 ; SAVED ZERO PAGE LOCS FOR IRQ +; +LINK_SCRPRT EQU LINK_TABLE+$50 +LINK_SCRPRTLN EQU LINK_TABLE+$52 +; +LINK_PRODOS EQU LINK_TABLE+$54 +; +LINK_HMEMREFINC EQU LINK_TABLE+$56 +LINK_HMEMREFDEC EQU LINK_TABLE+$58 +; +LINK_MEMSET EQU LINK_TABLE+$5A +; +RAMAVAIL EQU LINK_TABLE+$5E +; +CODEHEAPTOP EQU LINK_TABLE+$60 +; +LINK_CLASSLOAD EQU LINK_TABLE+$62 +; +LINK_GC EQU LINK_TABLE+$64 +LINK_FINALIZE EQU LINK_TABLE+$66 +; +LINK_EXITSTATUS EQU LINK_TABLE+$68 +; +; OPEN FILE REFNUM LIST SO FILES CAN BE CLEANED UP AT EXIT +; +LINK_OPENFILES EQU LINK_TABLE+$6A +; +LINK_DEVPOLL EQU LINK_TABLE+$70 +LINK_DEVREAD EQU LINK_TABLE+$70 +LINK_DEVREAD1 EQU LINK_TABLE+$72 +LINK_DEVREAD2 EQU LINK_TABLE+$74 +LINK_DEVREAD3 EQU LINK_TABLE+$76 +LINK_DEVREAD4 EQU LINK_TABLE+$78 +LINK_DEVREAD5 EQU LINK_TABLE+$7A +LINK_DEVREAD6 EQU LINK_TABLE+$7C +LINK_DEVREAD7 EQU LINK_TABLE+$7E +LINK_DEVSELECT EQU LINK_TABLE+$80 +LINK_DEVWRITE EQU LINK_TABLE+$80 +LINK_DEVWRITE1 EQU LINK_TABLE+$82 +LINK_DEVWRITE2 EQU LINK_TABLE+$84 +LINK_DEVWRITE3 EQU LINK_TABLE+$86 +LINK_DEVWRITE4 EQU LINK_TABLE+$88 +LINK_DEVWRITE5 EQU LINK_TABLE+$8A +LINK_DEVWRITE6 EQU LINK_TABLE+$8C +LINK_DEVWRITE7 EQU LINK_TABLE+$8E +LINK_VMCALL EQU LINK_TABLE+$90 +LINK_DEVCTRL EQU LINK_TABLE+$90 +LINK_DEVCTRL1 EQU LINK_TABLE+$92 +LINK_DEVCTRL2 EQU LINK_TABLE+$94 +LINK_DEVCTRL3 EQU LINK_TABLE+$96 +LINK_DEVCTRL4 EQU LINK_TABLE+$98 +LINK_DEVCTRL5 EQU LINK_TABLE+$9A +LINK_DEVCTRL6 EQU LINK_TABLE+$9C +LINK_DEVCTRL7 EQU LINK_TABLE+$9E +LINK_DEVIRQ EQU LINK_TABLE+$A0 +LINK_DEVIRQ1 EQU LINK_TABLE+$A2 +LINK_DEVIRQ2 EQU LINK_TABLE+$A4 +LINK_DEVIRQ3 EQU LINK_TABLE+$A6 +LINK_DEVIRQ4 EQU LINK_TABLE+$A8 +LINK_DEVIRQ5 EQU LINK_TABLE+$AA +LINK_DEVIRQ6 EQU LINK_TABLE+$AC +LINK_DEVIRQ7 EQU LINK_TABLE+$AE +; +;* +;* SWAPFILENAME +;* +SWAPFILE EQU $03B0 ; PUT SWAPFILE HERE SO CLEANUP IN WARM-INIT +; +ENTER_DVM EQU LINK_TABLE+$E1 +LINK_DVM EQU LINK_TABLE+$E2 +LINK_DUMPSTACK EQU LINK_TABLE+$E4 +EXIT_STATUS EQU LINK_TABLE+$E8 +LINK_REBOOT EQU LINK_TABLE+$EA +CHAIN_CMD EQU LINK_TABLE+$EC +LINK_EXIT EQU LINK_TABLE+$EE +; +.IFDEF BIGMEM +; +;########################################################## +;# +;# BIGMEM SETTINGS +;# +;########################################################## +; +;********************************************************** +;* +;* BIGMEM HANDLE/DATA TABLES/BUFFERS +;* +;********************************************************** +;* +;* BIGMEM I/O BUFFERS +;* +SWAPFILE_IO_BUFF EQU $0C00 ; MUST BE PAGE BOUNDARY I.E. LSB = $00 +CLASSFILE_IO_BUFF EQU $0800 +; +;* +;* MEMORY HANDLE TABLE +;* +HTBL_END EQU $E000 ; MUST BE PAGE BOUNDARY I.E. LSB = $00 +HMAX EQU $0800 ; MORE HANDLES IF SWAPPING +HTBL_LEN EQU HMAX*2 +HTBL EQU HTBL_END-HTBL_LEN +;* +;* TOP OF HEAP +;* +TOPOFHEAP EQU $BF00 +;* +;* STRING POOL DATA HASH TABLE: $0C00 - $0DFF +;* +HSTR_HASHL EQU $E100 +HSTR_HASHH EQU $E200 +;* +;* CLASS HANDLE TABLE: $0E00 - $0EFF +;* +HCLASS_TBLL EQU $0E000 +HCLASS_TBLH EQU $0E080 +;* +;* THREAD LOCAL STORAGE STACK: $E300 - $E3FF +;* +TLS EQU $E300 +;* +;* DVM OP TABLE: $E400 - $E4FF +;* +;* +;* AUXMEM ACCESS MACROS +;* +.MACRO AUXZP_ACCESS_ON + SEI ; TURN INTERRUPTS OFF + STA ALTZPON ; TURN ON ALT ZP AND LC +.ENDMACRO +.MACRO AUXZP_ACCESS_OFF + STA ALTZPOFF ; TURN OFF ALT ZP AND LC + CLI ; TURN INTERRUPTS BACK ON +.ENDMACRO +.MACRO AUXMEM_RDACCESS_ON + SEI + STA ALTRAMRDON +.ENDMACRO +.MACRO AUXMEM_RDACCESS_OFF + STA ALTRAMRDOFF + CLI +.ENDMACRO +.MACRO AUXMEM_WRACCESS_ON + SEI + STA ALTRAMWRON +.ENDMACRO +.MACRO AUXMEM_WRACCESS_OFF + STA ALTRAMWROFF + CLI +.ENDMACRO +.ELSE ; NON-BIGMEM +; +;########################################################## +;# +;# NON-BIGMEM SETTINGS +;# +;########################################################## +; +;********************************************************** +;* +;* HANDLE/DATA TABLES/BUFFERS +;* +;********************************************************** +;* +;* I/O BUFFERS +;* +SWAPFILE_IO_BUFF EQU $BB00 ; MUST BE PAGE BOUNDARY I.E. LSB = $00 +CLASSFILE_IO_BUFF EQU $0800 +;* +;* MEMORY HANDLE TABLE +;* +.IFDEF SWAPPING +HTBL_END EQU $BB00 ; RIGHT BELOW SWAPFILE BUFFER +.ELSE +HTBL_END EQU $BF00 ; MUST BE PAGE BOUNDARY I.E. LSB = $00 +.ENDIF ; SWAPPING +TOPOFHEAP EQU HTBL +HMAX EQU $0400 +HTBL_LEN EQU HMAX*2 +HTBL EQU HTBL_END-HTBL_LEN +;* +;* STRING POOL DATA HASH TABLE: $0C00 - $0DFF +;* +HSTR_HASHL EQU $0C00 +HSTR_HASHH EQU $0D00 +;* +;* CLASS HANDLE TABLE: $0E00 - $0EFF +;* +HCLASS_TBLL EQU $0E00 +HCLASS_TBLH EQU $0E80 +;* +;* THREAD LOCAL STORAGE STACK: $0F80 - $0FFF +;* +TLS EQU $0F80 +;* +;* AUXMEM ACCESS MACROS +;* +.MACRO AUXZP_ACCESS_ON +.ENDMACRO +.MACRO AUXZP_ACCESS_OFF +.ENDMACRO +.MACRO AUXMEM_RDACCESS_ON +.ENDMACRO +.MACRO AUXMEM_RDACCESS_OFF +.ENDMACRO +.MACRO AUXMEM_WRACCESS_ON +.ENDMACRO +.MACRO AUXMEM_WRACCESS_OFF +.ENDMACRO +.ENDIF ; BIGMEM +;########################################################## +;* +;* TYPEAHEAD BUFFER: $02B0 - $02BF +;* +TYPEBUFFLEN EQU $0280 +TYPEBUFF EQU $0281 +TYPEBUFFMAX EQU $0E +;* +;* DVM OP TABLE: $0290 +;* +; +;********************************************************** +;* +;* SYSTEM ROUTINES AND LOCATIONS +;* +;********************************************************** +;* +;* MONITOR SPECIAL LOCATIONS AND PRODOS MLI +;* +CSWL EQU $36 +CSWH EQU $37 +PROMPTCHAR EQU $33 +PRODOS EQU $BF00 +MACHID EQU $BF98 +;* +;* HARDWARE ADDRESSES +;* +KEYBD EQU $C000 +CLRKBD EQU $C010 +SPKR EQU $C030 +ROMIN EQU $C081 +LCBNK2 EQU $C083 +LCBNK1 EQU $C08B +ALTZPOFF EQU $C008 +ALTZPON EQU $C009 +ALTRAMRDOFF EQU $C002 +ALTRAMRDON EQU $C003 +ALTRAMWROFF EQU $C004 +ALTRAMWRON EQU $C005 +; +;********************************************************** +;* +;* SYSTEM TYPES +;* +;********************************************************** +;* +;* CONSTANT TYPE IDENTIFIERS +;* +CONST_UTF8 EQU 1 +CONST_INTEGER EQU 3 +CONST_FLOAT EQU 4 +CONST_LONG EQU 5 +CONST_DOUBLE EQU 6 +CONST_CLASS EQU 7 +CONST_STRING EQU 8 +CONST_FIELDREF EQU 9 +CONST_METHDREF EQU 10 +CONST_IFACEMETHDREF EQU 11 +CONST_NAMETYPE EQU 12 +;* +;* DATA TYPE IDENTIFIERS +;* +T_BOOLEAN EQU 4 ; 0 +T_CHAR EQU 5 ; 1 +T_FLOAT EQU 6 ; 2 +T_DOUBLE EQU 7 ; 3 +T_BYTE EQU 8 ; 0 +T_SHORT EQU 9 ; 1 +T_INT EQU 10 ; 2 +T_LONG EQU 11 ; 3 + ; 0 +T_ARRAY EQU 13 ; 1 +T_REF EQU 14 ; 2 +;* +;* SYSTEM CLASS INDECES +;* +CL_NULL EQU 0 +CL_OBJ EQU 1 +CL_ARRAY EQU 2 +CL_STR EQU 3 +CL_SYS EQU 3 +;* +;* THREAD STATES +;* +S_FREE EQU 0 ; NOT ALLOCATED +S_IDLE EQU 1 ; WAITING TO BE SET TO RUN +S_SUSPEND EQU 2 ; SUSPENDED +S_SLEEP EQU 3 ; SLEEPING +S_BLOCK EQU 4 ; BLOCKED ON OBJECT LOCK +S_WAITNOTIFY EQU 5 ; WAITING FOR NOTIFY +S_WAITIO EQU 8 ; WAIT FOR I/O = 8 + SLOT # +S_RUNNABLE EQU 16 ; WAITING TO RUN +S_RUNNING EQU 17 ; RUNNING +S_INTERRUPTED EQU 18 ; INTERRUPTED +;* +;* DEVICE CONTROL COMMANDS +;* COMBINED WITH SLOT NUMBER IN BITS 7-4 +;* +IOCTL_ID EQU (1<<3) ; IDENTIFY DEVICE +;IOCTL_INIT EQU (2<<3) ; INIT DEVICE +IOCTL_OPEN EQU (3<<3) ; ENABLE DEVICE FOR PROGRAM USE +IOCTL_CLOSE EQU (4<<3) ; DISABLE DEVICE FOR PROGRAM USE +IOCTL_AVAIL EQU (5<<3) ; CHARS AVAILABLE +IOCTL_SPACE EQU (6<<3) ; SPACE TO WRITE +IOCTL_INBUFF EQU (7<<3) ; IN BUFFER ADDRESS +IOCTL_INBUFFSZ EQU (8<<3) ; IN BUFFER SIZE +IOCTL_OUTBUFF EQU (9<<3) ; OUT BUFFER ADDRESS +IOCTL_OUTBUFFSZ EQU (10<<3) ; OUT BUFFER SIZE +IOCTL_DEACTIVATE EQU (11<<3) ; DEACTIVATE DEVICE COMPLETELY +; +; CONSOLE IOCTLS +; +CONCTL_HOME EQU (16<<3) +CONCTL_GOTOXY EQU (17<<3) ; XY LOC IN XY REGS +CONCTL_TEXT80 EQU (20<<3) ; SET 80 COLUMN TEXT MODE +; +; MOUSE IOCTLS +; +MOUSECTL_CALLFW EQU (16<<3) ; CALL FW FUNC IN X REG +MOUSECTL_NOIRQ EQU (17<<3) ; UNINSTALL VBL INTERRUPT +MOUSECTL_CLAMPX EQU (18<<3) +MOUSECTL_CLAMPY EQU (19<<3) +MOUSECTL_READMOUSE EQU (20<<3) ; READ MOUSE STATUS/POSITION +; +; SERIAL PORT IOCTLS +; +SERCTL_BAUD EQU (16<<3) +SERCTL_STOPBITS EQU (17<<3) +SERCTL_PARITYBITS EQU (18<<3) +SERCTL_DATABITS EQU (19<<3) +SERCTL_XONXOFF EQU (20<<3) +; +; ETHERNET IOCTLS +; +ETHRCTL_RECVPKT EQU (16<<3) +ETHRCTL_XMITPKT EQU (17<<3) +ETHRCTL_DONEPKT EQU (18<<3) +ETHRCTL_SETMAC01 EQU (19<<3) +ETHRCTL_SETMAC23 EQU (20<<3) +ETHRCTL_SETMAC45 EQU (21<<3) +; +; GRAPHICS TABLET IOCTLS +; +GTCTL_CALLFW EQU (16<<3) ; CALL FW TO READ POS W/O DELAY diff --git a/src/graphtabdrvr.s b/src/graphtabdrvr.s new file mode 100755 index 0000000..894acfa --- /dev/null +++ b/src/graphtabdrvr.s @@ -0,0 +1,66 @@ +;* +;* GRAPHICS TABLET DEVICE DRIVER +;* +TEM EQU $280 +XFLL EQU $281 +XFLH EQU $282 +YFLL EQU $283 +YFLH EQU $284 +MSLOT EQU $7F8 +ROMREAD EQU $CBF4 +ROMOFFSC EQU $CBC6 +ROMSWCHK EQU $CBD0 +ROMSW EQU $CFFF + +GT_INIT: LDA #IOCTL_CLOSE + BNE GT_CTRL +GT_DRIVER: +GT_DRVR_SZ: .WORD GT_DRVR_END - GT_DRVR_START +GT_READ_OFS: .WORD GT_READ - GT_DRVR_START +GT_WRITE_OFS: .WORD GT_WRITE - GT_DRVR_START +GT_CTRL_OFS: .WORD GT_CTRL - GT_DRVR_START +GT_IRQ_OFS: .WORD GT_IRQ - GT_DRVR_START +GT_DRVR_START: +GT_READ: +GT_WRITE: SEC + RTS +GT_CTRL: TYA + AND #$F8 ; MASK OFF SLOT # + CMP #GTCTL_CALLFW + BNE :+ + TYA + AND #$07 + ORA #$C0 + SEI + STA MSLOT + STA TMPTR+1 + BIT ROMSW + LDY #$00 + STY TMPTR + LDA (TMPTR),Y + JSR ROMREAD + CLI + BCC GTSWCHK + JMP ROMOFFSC +GTSWCHK: JMP ROMSWCHK +: CMP #IOCTL_OPEN + BNE :+ + TYA + AND #$07 + ASL + TAX + CLC + RTS +: CMP #IOCTL_CLOSE + BNE :+ + CLC + RTS +: CMP #IOCTL_ID + BNE :+ + LDA #$2F ; GRAPHICS TABLET ID + CLC + RTS +GT_IRQ: +: SEC + RTS +GT_DRVR_END EQU * diff --git a/src/io.s b/src/io.s new file mode 100755 index 0000000..be84051 --- /dev/null +++ b/src/io.s @@ -0,0 +1,872 @@ +;* +;* JAVA I/O FOR 6502 +;* + .INCLUDE "global.inc" +;* +;* HANDY ROM ROUTINES +;* +ROM_MONITOR EQU $FF65 +ROM_HOME EQU $FC58 +ROM_BELL EQU $FF3A +ROM_COUT EQU $FDED +ROM_CROUT EQU $FD8E +ROM_CROUT1 EQU $FD8B +ROM_CLREOL EQU $FC9C +ROM_PRBLNK EQU $F948 +ROM_PRBL2 EQU $F94A +ROM_PRBYTE EQU $FDDA +ROM_PRNTAX EQU $F941 +ROM_GETLN EQU $FD6A + + .IMPORT HMEM_ALLOC,HMEM_LOCK,HMEM_ALLOC_FIXED,HMEM_FREE,HMEM_PTR + .IMPORT THREAD_YIELD,THREAD_NOTIMEOUT,THREAD_NOTIFYIO,THREAD_WAITIO,SYSTEM_TIC,CURRENT_THREAD + .IMPORT THROW_IOEXCPTN,THROW_INTERNALERR,THREAD_TRACE + .IMPORT WARM_INIT,MEMCPY + .IMPORT THREAD_SELECTIO,IO_NOTIFY,SLOT2MASK + .EXPORT IO_INIT,IODEV_INIT,VBL_INIT,HOME,GETLN,PRNTAX,CROUT,PRBYTE,COUT + .EXPORT PUTS + .EXPORT PUTSLN + .EXPORT PRSTR,PRSTRLN,PRHSTR,PRHSTRLN + .EXPORT KBWAIT + .EXPORT ON_LINE + .EXPORT PREFIX_GET,PREFIX_SET,DIR_CREATE,FILE_CREATE,FILE_DESTROY,FILE_GETEOF,FILE_GETINFO + .EXPORT FILE_OPEN,FILE_SETBUFFER,FILE_SETAUX,FILE_READ,FILE_WRITE,FILE_CLOSE,FILE_BLOAD + + .SEGMENT "INIT" +IO_INIT: LDA #$00 + STA TYPEBUFFLEN + STA LCIN_MASK + LDA MACHID ; CHECK FOR II OR II+ + AND #$88 + BEQ :+ + LDA #$20 +: EOR #$DF ; LCOUT_MASK = $DF FOR II & II+, $FF FOR IIE & IIC + STA LCOUT_MASK + LDX #$0E +: LDA #UNIMPL_DRVR + STA LINK_DEVREAD+1,X + STA LINK_DEVWRITE+1,X + STA LINK_DEVCTRL+1,X + DEX + DEX + BPL :- + BIT ROMIN + JSR PRODOS + .BYTE $40 ; ALLOC INTERRUPT + .ADDR ALLOCINTPARMS +.IFDEF DEBUG + BCC :+ + JSR PUTSLN + .ASCIIZ "FAILED TO ALLOCATE INTERRUPT" +: +.ENDIF + RTS +ALLOCINTPARMS: .BYTE $02 + .BYTE $00 ; INT NUM + .ADDR IO_INTERRUPT ; INT CODE +;* +;* IO DEVICE INIT +;* +IODEV_INIT: PHP + SEI ; TURN OFF INTERRUPTS + LDA #SW_TIMER + STA LINK_YIELD+1 + LDA #PRODOS_MLI + STA LINK_PRODOS+1 + LDA #PRHSTR + STA LINK_SCRPRT+1 + LDA #PRHSTRLN + STA LINK_SCRPRTLN+1 + LDA #KEYBD_POLL + STA LINK_DEVPOLL+1 + LDA #THREAD_SELECTIO + STA LINK_DEVWRITE + STX LINK_DEVWRITE+1 + LDA #CON_DRIVER + LDY #$03 ; IN SLOT 3 + JSR LOAD_DRIVER + LDA #COUT + STA LINK_DEVWRITE+6 + STX LINK_DEVWRITE+7 + LDA WARM_INIT + BNE :+ + JSR PUTS + .ASCIIZ "Console in slot #03" + JSR CROUT +: +.IFDEF DEBUG_DUMP + LDA #DEBUG_DUMP+1 ; START WITH SLOT FOLLOWING DEBUG DUMP +.ELSE + LDA #$01 +.ENDIF + LDX #$31 ; LOOK FOR SSC + JSR SCAN_SLOTS + BCC :+ + JMP SRCHGT +: STA SSCSLOT + TAY + LDA #SSC_DRIVER + JSR LOAD_DRIVER + LDY SSCSLOT ; INIT SSC + JSR SSC_INIT + LDA SSCSLOT + ASL SSCSLOT + STA LOADSLOT + LDA WARM_INIT + BNE NEXTSSC + JSR PUTS + .ASCIIZ "SuperSerial in slot #" + LDA LOADSLOT + JSR PRBYTE + JSR CROUT +NEXTSSC: INC LOADSLOT + LDA LOADSLOT + CMP #$08 + BCS SRCHGT + LDX #$31 ; LOOK FOR MORE SSC + JSR SCAN_SLOTS + BCS SRCHGT + STA LOADSLOT + ASL + TAY + LDX SSCSLOT ; COPY DRIVER ENTRPOINTS TO ANOTHER SLOT + LDA LINK_DEVREAD,X + STA LINK_DEVREAD,Y + LDA LINK_DEVREAD+1,X + STA LINK_DEVREAD+1,Y + LDA LINK_DEVWRITE,X + STA LINK_DEVWRITE,Y + LDA LINK_DEVWRITE+1,X + STA LINK_DEVWRITE+1,Y + LDA LINK_DEVCTRL,X + STA LINK_DEVCTRL,Y + LDA LINK_DEVCTRL+1,X + STA LINK_DEVCTRL+1,Y + LDA LINK_DEVIRQ,X + STA LINK_DEVIRQ,Y + LDA LINK_DEVIRQ+1,X + STA LINK_DEVIRQ+1,Y + LDA WARM_INIT + BNE :+ + JSR PUTS + .ASCIIZ "SuperSerial in slot #" + LDA LOADSLOT + JSR PRBYTE + JSR CROUT +: JMP NEXTSSC ; LOOK FOR ALL SSC +SRCHGT: LDA #$C1 ; LOOK FOR GRAPHICS TABLET & UTHERNET CARD + STA TMPTR+1 + LDA #$00 + STA TMPTR +CHKGT: LDY #$01 ; CHECK FOR GRAPHICS TABLET + LDA (TMPTR),Y + CMP #$B0 + BNE NXTGT + LDY #$09 + LDA (TMPTR),Y + CMP #$20 + BNE NXTGT + LDA TMPTR+1 + AND #$07 + PHA + TAY + LDA #GT_DRIVER + JSR LOAD_DRIVER + LDA WARM_INIT + BNE :+ + JSR PUTS + .ASCIIZ "Graphics Tablet in slot #" + PLA + PHA + JSR PRBYTE + JSR CROUT +: PLA + JMP CHKUTHR ; SKIP IF GRAPHICS TABLET FOUND +NXTGT: INC TMPTR+1 + LDA TMPTR+1 + CMP #$C8 + BCC CHKGT +CHKUTHR: JSR UTHER_PROBE1 + BCS :+ + LDA #UTHER_DRIVER1 + LDY #$01 + BNE LOADUTHR +: JSR UTHER_PROBE2 + BCS :+ + LDA #UTHER_DRIVER2 + LDY #$02 + BNE LOADUTHR +: JSR UTHER_PROBE4 + BCS :+ + LDA #UTHER_DRIVER4 + LDY #$04 + BNE LOADUTHR +: JSR UTHER_PROBE5 + BCS :+ + LDA #UTHER_DRIVER5 + LDY #$05 + BNE LOADUTHR +: JSR UTHER_PROBE6 + BCS :+ + LDA #UTHER_DRIVER6 + LDY #$06 + BNE LOADUTHR +: JSR UTHER_PROBE7 + BCS CHKMOUSE + LDA #UTHER_DRIVER7 + LDY #$07 +LOADUTHR: STY UTHRSLOT + JSR LOAD_DRIVER + LDA DRVRADDR ; INSERT UTHER POLL INTO YIELD LINKEAGE + STA LINK_DEVPOLL + LDA DRVRADDR+1 + STA LINK_DEVPOLL+1 + LDY WARM_INIT + BNE CHKMOUSE + JSR PUTS + .ASCIIZ "Uthernet in slot #" + LDA UTHRSLOT + JSR PRBYTE + JSR CROUT +CHKMOUSE: LDX #$20 ; LOOK FOR MOUSE + LDA #$01 + JSR SCAN_SLOTS + BCS NOMOUSE + PHA ; SAVE SLOT + LDY #$13 + LDA (TMPTR),Y + STA SERVEMOUSE+1 ; FIXUP IRQ HANDLER + STX SERVEMOUSE+2 + LDY #$14 + LDA (TMPTR),Y + STA READMOUSE+1 ; FIXUP IRQ HANDLER + STX READMOUSE+2 + TXA + AND #$07 + STA MOUSE_SLOT + TAY + JSR MOUSE_INIT ; MAKE SURE MOUSE IS OFF, INTS OFF + LDA WARM_INIT + BNE :+ + JSR PUTS + .ASCIIZ "Mouse in slot #" + LDA MOUSE_SLOT + JSR PRBYTE + JSR CROUT +: PLA + TAY + LDA #MOUSE_DRIVER + JSR LOAD_DRIVER + LDA #THREAD_YIELD + STA LINK_YIELD+1 +NOMOUSE: PLP + RTS +; +; SCAN SLOTS FOR MATCHING CARD ID +; ENTRY: A = START SLOT SCAN +; X = CARD ID +; EXIT: A = SLOT # :: C = 0 +; X = SLOT PAGE +; +SCAN_SLOTS: ORA #$C0 + STA TMPTR+1 + LDA #$00 + STA TMPTR +CHKSIG: LDY #$05 + LDA (TMPTR),Y + CMP #$38 ; LOOK FOR PASCAL COMPAT SIG + BNE :+ + LDY #$07 + LDA (TMPTR),Y + CMP #$18 + BNE :+ + LDY #$0B + LDA (TMPTR),Y + CMP #$01 + BNE :+ + LDY #$0C + TXA ; LOOK FOR MATCHING ID + CMP (TMPTR),Y + BNE :+ + LDA TMPTR+1 + TAX + AND #$07 + CLC + RTS +: INC TMPTR+1 + LDA TMPTR+1 + CMP #$C8 + BCC CHKSIG + SEC + RTS +; +; LOAD DEVICE DRIVER AND INSERT INTO LINK TABLE +; ENTRY: AX = DRIVER ADDRESS +; Y = SLOT # +; +LOAD_DRIVER: STA LDPTR ; DRIVER ENTRIES + STX LDPTR+1 + CLC + ADC #$0A ; START OF CODE + STA SRCADDR + BCC :+ + INX +: STX SRCADDR+1 + TYA + ASL + STA LOADSLOT + LDY #$01 ; GET DRIVER SIZE + LDA (LDPTR),Y + DEY + TAX + LDA (LDPTR),Y + INY + JSR HMEM_ALLOC ; ALLOC THE MEMORY + JSR HMEM_LOCK ; AND LOCK IT - FOREVER + STA DSTADDR + STA DRVRADDR + STX DSTADDR+1 + STX DRVRADDR+1 + LDX LOADSLOT + LDY #$02 ; INSERT DEVICE READ ROUTINE + CLC + ADC (LDPTR),Y + INY + STA LINK_DEVREAD,X + LDA DSTADDR+1 + ADC (LDPTR),Y + INY + STA LINK_DEVREAD+1,X + LDA DSTADDR ; INSERT DEVICE WRITE ROUTINE + CLC + ADC (LDPTR),Y + INY + STA LINK_DEVWRITE,X + LDA DSTADDR+1 + ADC (LDPTR),Y + INY + STA LINK_DEVWRITE+1,X + LDA DSTADDR ; INSERT DEVICE CTRL ROUTINE + CLC + ADC (LDPTR),Y + INY + STA LINK_DEVCTRL,X + LDA DSTADDR+1 + ADC (LDPTR),Y + INY + STA LINK_DEVCTRL+1,X + LDA DSTADDR ; INSERT DEVICE IRQ ROUTINE + CLC + ADC (LDPTR),Y + INY + STA LINK_DEVIRQ,X + LDA DSTADDR+1 + ADC (LDPTR),Y + STA LINK_DEVIRQ+1,X + LDY #$01 ; GET DRIVER SIZE + LDA (LDPTR),Y + DEY + TAX + LDA (LDPTR),Y + JMP MEMCPY ; MOVE DRIVER TO LOCKED MEM AND DONE +LOADSLOT: .BYTE $00 +SSCSLOT: .BYTE $00 +UTHRSLOT: .BYTE $00 +MOUSE_SLOT: .BYTE $00 +DRVRADDR: .WORD $0000 + .INCLUDE "consoledrvr.s" + .INCLUDE "sscdrvr.s" + .INCLUDE "mousedrvr.s" + .INCLUDE "graphtabdrvr.s" +UTHERSLOT1 = 1 + .INCLUDE "utherdrvr.s" +UTHERSLOT2 = 1 + .INCLUDE "utherdrvr.s" +UTHERSLOT4 = 1 + .INCLUDE "utherdrvr.s" +UTHERSLOT5 = 1 + .INCLUDE "utherdrvr.s" +UTHERSLOT6 = 1 + .INCLUDE "utherdrvr.s" +UTHERSLOT7 = 1 + .INCLUDE "utherdrvr.s" +;* +;* TURN VBL INTS ON AFTER INIT +;* +VBL_INIT: LDA MOUSE_SLOT + BEQ NOVBL + ASL + TAX + LSR + ORA #MOUSECTL_CALLFW + TAY + SEI ; TURN OFF INTERRUPTS + LDA LINK_DEVCTRL,X + STA CALLVBLPROC+1 + LDA LINK_DEVCTRL+1,X + STA CALLVBLPROC+2 + LDA #$08 ; TURN MOUSE OFF, LEAVE VBL ON + LDX #$12 +CALLVBLPROC: JSR $0000 + CLI ; BACK ON + LDA WARM_INIT + BNE NOVBL + JSR PUTSLN + .ASCIIZ "VBlank timer active" +NOVBL: RTS +; +; CREATE DIRECTORY - ONLY NEEDED DURING INIT +; ENTRY: AX = POINTER TO DIRECTORY PATHNAME +; EXIT: C = 0 :: SUCCESS +; C = 1 :: FAILURE +; +DIR_CREATE: STA CREATEPARMS+1 + STX CREATEPARMS+2 + LDA #$0F ; DIRECTORY + STA CREATEPARMS+4 + LDA #$0D ; SUBDIRECTORY + STA CREATEPARMS+7 + BIT LCBNK1 + JSR PRODOS + .BYTE $C0 ; CREATE FILE + .ADDR CREATEPARMS + LDY #$01 + STY CREATEPARMS+7 ; SET BACK TO NORMAL FILE + JMP SETLCBNK2 +; +; VOLUMES ON LINE - ONLY NEEDED DURING INIT +; ENTRY: AX = POINTER TO 256 BYTE DATA BUFFER +; Y = UNIT NUM +; EXIT: C = 0 :: SUCCESS +; C = 1 :: FAILURE +; +ON_LINE: STA VOLPARMS+2 + STX VOLPARMS+3 + STY VOLPARMS+1 + BIT LCBNK1 + JSR PRODOS + .BYTE $C5 + .ADDR VOLPARMS + JMP SETLCBNK2 +;* +;* WRAPPERS FOR ROM ROUTINES +;* +GETLN: BIT ROMIN + JSR ROM_GETLN ; CALL GETLN + JMP SETLCBNK2 + + .CODE + +HOME: BIT ROMIN + JSR ROM_HOME + JMP SETLCBNK2 +PRNTAX: BIT ROMIN + JSR ROM_PRNTAX + JMP SETLCBNK2 +PRBYTE: BIT ROMIN + JSR ROM_PRBYTE + JMP SETLCBNK2 +CROUT: LDA #$0D +COUT: CMP #$60 ; LOWERCASE CHARACTER? + BCC :+ + AND LCOUT_MASK ; APPLY LOWER->UPPER CONVERSION +: ORA #$80 + BIT ROMIN + JSR ROM_COUT +SETLCBNK2: SEI ; THIS CANNOT BE INTERRUPTED + BIT LCBNK2 + BIT LCBNK2 + CLI + RTS +; +; PRINT ASCIIZ STRING FOLLOWING JSR PUTS +; +PUTSLN: LDX #$0D + BNE :+ +PUTS: LDX #$00 +: PLA + STA TMP + PLA + STA TMP+1 + LDY #$00 +PUTS_LP: INC TMP + BNE :+ + INC TMP+1 +: LDA (TMP),Y + BEQ PUTS_EXIT + JSR COUT + JMP PUTS_LP +PUTS_EXIT: TXA + BEQ :+ + JSR COUT +: LDA TMP+1 + PHA + LDA TMP + PHA +: RTS +; +; PRINT STRING IN AX +; +PRHSTR: CPX #$00 + BEQ :- + JSR HMEM_PTR +PRSTR: STA TMP + STX TMP+1 + LDY #$00 + LDA (TMP),Y + BEQ :- + TAX + INY + BIT ROMIN +PRSTR_LP: LDA (TMP),Y + CMP #$60 ; LOWERCASE CHARACTER? + BCC :+ + AND LCOUT_MASK ; APPLY LOWER->UPPER CONVERSION +: ORA #$80 + JSR ROM_COUT + INY + DEX + BNE PRSTR_LP + JMP SETLCBNK2 +PRHSTRLN: CPX #$00 + BEQ :+ + JSR HMEM_PTR +PRSTRLN: JSR PRSTR +: BIT ROMIN + JSR ROM_CLREOL + JSR CROUT + RTS +; +; WAIT FOR KEYPRESS +; +KBWAIT: LDA KEYBD + BPL KBWAIT + BIT CLRKBD + RTS +;* +;* I/O INTERRUPT ROUTINE +;* +IO_INTERRUPT: CLD + LDY #$02 ; SLOT #1 * 2 +FNDIRQPROC: LDA LINK_DEVIRQ+1,Y + BEQ NXTIRQPROC + STA CALLIRQPROC+2 + LDA LINK_DEVIRQ,Y + STA CALLIRQPROC+1 + TYA + LSR + PHA +CALLIRQPROC: JSR $0000 + BCS :+ + PLA + TAY + PHA + JSR THREAD_NOTIFYIO +: PLA + ASL + TAY +NXTIRQPROC: INY + INY + CPY #$10 + BCC FNDIRQPROC + CLC + RTS +; +; UNIMPLEMENTED DRIVER PROC +; +UNIMPL_DRVR: SEC + RTS +; +; SOFTWARE IMPLEMENTED (FAKED) INTERRUPT ROUTINES +; +SW_TIMER: LDA OPCNT + BEQ :+ + CLC + ADC TIMERADJUST + STA TIMERADJUST + BCC :++ +: LDX #$00 + LDA #$60 + JSR SYSTEM_TIC ; INCREMENT SYSTEM TICS BASED ON OPCNT +: JMP (LINK_DEVPOLL) ; JUMP TO IODEV_POLL +KEYBD_POLL: LDA KEYBD ; CHECK FOR PENDING KEYPRESS + BMI FAKE_IRQ + JMP THREAD_YIELD +FAKE_IRQ: PHP ; SAVE FLAGS + SEI ; MAKE SURE NO REAL INTERRUPTS HAPPEN + LDX #$06 ; SAVE AND RESTORE ZP LIKE PRODOS +: LDA $F9,X + STA SAVEZPIRQ,X + DEX + BPL :- + JSR IO_INTERRUPT + LDX #$06 +: LDA SAVEZPIRQ,X + STA $F9,X + DEX + BPL :- + PLP ; RESTORE FLAGS + JMP THREAD_YIELD +;* +;* PRODOS WRAPPERS +;* +; +; CALL PRODOS MLI +; ENTRY: AX = BYTE ARRAY REFERENCE FOR PARAM BLOCK +; Y = PRODOS COMMAND +PRODOS_MLI: STY MLI_CMD + JSR HMEM_PTR + CLC ; SKIP ARRAY LENGTH WORD + ADC #$02 + BCC :+ + INX +: STA MLI_PARAMS + STX MLI_PARAMS+1 + BIT LCBNK1 + JSR PRODOS +MLI_CMD: .BYTE $00 +MLI_PARAMS: .ADDR $0000 + JMP SETLCBNK2 +; +; GET PREFIX +; ENTRY: AX = POINTER TO PREFIX STRING +; EXIT: C = 0 :: SUCCESS +; C = 1 :: FAILURE +; +PREFIX_GET: LDY #$C7 + BNE PREFIX_OP +; +; SET PREFIX +; ENTRY: AX = POINTER TO PREFIX STRING +; EXIT: C = 0 :: SUCCESS +; C = 1 :: FAILURE +; +PREFIX_SET: LDY #$C6 + BNE PREFIX_OP +; +; DESTROY FILE +; ENTRY: AX = POINTER TO FILE PATHNAME +; EXIT: C = 0 :: SUCCESS +; C = 1 :: FAILURE +; +FILE_DESTROY: LDY #$C1 +PREFIX_OP: STY PREFIXCMD + STA PREFIXPARMS+1 + STX PREFIXPARMS+2 + BIT LCBNK1 + JSR PRODOS +PREFIXCMD: .BYTE $C1 + .ADDR PREFIXPARMS + JMP SETLCBNK2 +; +; CREATE FILE +; ENTRY: AX = POINTER TO FILE PATHNAME +; Y = FILE TYPE +; EXIT: C = 0 :: SUCCESS +; C = 1 :: FAILURE +; +FILE_SETAUX: STA CREATEPARMS+5 + STX CREATEPARMS+6 + RTS +FILE_CREATE: STA CREATEPARMS+1 + STX CREATEPARMS+2 + TYA + AND #$07 + ORA #$F0 ; USER DEFINED TYPES $F1-$F8 + STA CREATEPARMS+4 + BIT LCBNK1 + JSR PRODOS + .BYTE $C0 ; CREATE FILE + .ADDR CREATEPARMS + JMP SETLCBNK2 +; +; GET FILE INFO +; ENTRY: AX = POINTER TO FILENAME +; EXIT: AX = POINTER TO ATTRIBUTE BUFFER +; C = 0 :: SUCCESS +; C = 1 :: FAILURE +; +FILE_GETINFO: STA INFOPARMS+1 + STX INFOPARMS+2 + BIT LCBNK1 + JSR PRODOS + .BYTE $C4 ; FILE GET INFO + .ADDR INFOPARMS + BCS :+ + LDA #INFOPARMS +: JMP SETLCBNK2 +; +; OPEN FILE +; ENTRY: AX = POINTER TO FILENAME +; Y = HIGH ADDESS OF SYSTEM IO BUFFER +; EXIT: Y = REF NUM +; C = 0 :: SUCCESS +; C = 1 :: FAILURE +; +FILE_OPEN: STA OPENPARMS+1 + STX OPENPARMS+2 + STY OPENPARMS+4 + BIT LCBNK1 + JSR PRODOS + .BYTE $C8 ; OPEN FILE + .ADDR OPENPARMS + BCS :+ + LDY OPENPARMS+5 +: JMP SETLCBNK2 +; +; CLOSE FILE +; ENTRY: Y = REF NUM +; +FILE_CLOSE: STY CLOSEPARMS+1 + BIT LCBNK1 + JSR PRODOS + .BYTE $CC ; CLOSE FILE + .ADDR CLOSEPARMS + JMP SETLCBNK2 +; GET END-OF-FILE +; ENTRY: Y = REF NUM +; EXIT: AXY = EOF +; C = 0 :: SUCCESS +; C = 1 :: FAILURE +; +FILE_GETEOF: STY GETEOFPARMS+1 + BIT LCBNK1 + JSR PRODOS + .BYTE $D1 ; GET EOF (FILE LEN) + .ADDR GETEOFPARMS + BCS :+ + LDA GETEOFPARMS+2 + LDX GETEOFPARMS+3 + LDY GETEOFPARMS+4 +: JMP SETLCBNK2 +; +; SET DATA BUFFER FOR READ/WRITE +; ENTRY: AX = ADDRESS OF BUFFER +; +FILE_SETBUFFER: STA WRITEPARMS+2 + STX WRITEPARMS+3 + CLC + RTS +; +; READ FROM FILE +; ENTRY: AX = NUMBER OF BYTES TO READ +; Y = REF NUM +; EXIT: AX = NUMBER OF BYTES ACTUALLY READ +; C = 0 :: SUCCESS +; C = 1 :: FAILURE +; +FILE_READ: STA READPARMS+4 + STX READPARMS+5 + STY READPARMS+1 + BIT LCBNK1 + JSR PRODOS + .BYTE $CA ; READ FILE + .ADDR READPARMS + BCS :+ + LDA READPARMS+6 + LDX READPARMS+7 +: JMP SETLCBNK2 +; +; WRITE TO FILE +; ENTRY: AX = NUMBER OF BYTES TO WRITE +; Y = REF NUM +; EXIT: AX = NUMBER OF BYTES ACTUALLY WRITTEN +; C = 0 :: SUCCESS +; C = 1 :: FAILURE +; +FILE_WRITE: STA WRITEPARMS+4 + STX WRITEPARMS+5 + STY WRITEPARMS+1 + BIT LCBNK1 + JSR PRODOS + .BYTE $CB ; WRITE FILE + .ADDR WRITEPARMS + BCS :+ + LDA WRITEPARMS+6 + LDX WRITEPARMS+7 +: JMP SETLCBNK2 +; +; READ BINARY FILE +; ENTRY: AX = POINTER TO FILE NAME +; +FILE_BLOAD: LDY #>CLASSFILE_IO_BUFF + JSR FILE_OPEN + JSR FILE_GETEOF + LDY OPENPARMS+5 + JSR FILE_READ + LDY OPENPARMS+5 + JMP FILE_CLOSE + + .DATA + +TIMERADJUST: ;.BYTE $03 ; OVERLAP WITH SLOT2IO +SLOT2IO: .BYTE $03,$10,$20,$30,$40,$50,$60,$70 + +CLOSEPARMS: ;.BYTE $01 + ;.BYTE $00 ; REF NUM +PREFIXPARMS: .BYTE $01 + .ADDR $0000 ; PATH ADDR +CREATEPARMS: .BYTE $07 + .WORD $0000 ; PATH ADDR + .BYTE $C3 ; ACCESS BITS (FULL ACCESS) + .BYTE $00 ; FILE TYPE + .WORD $0000 ; AUX TYPE + .BYTE $01 ; STORAGE TYPE + .WORD $0000 ; CREATE DATE + .WORD $0000 ; CREATE TIME +OPENPARMS: .BYTE $03 + .ADDR $0000 ; PATH ADDR + .ADDR $0000 ; SYS BUFF ADDR + .BYTE $00 ; REF NUM +VOLPARMS: ;.BYTE $02 + ;.BYTE $00 ; UNIT NUM + ;.ADDR $0000 ; DATA BUFFER ADDR +GETEOFPARMS: .BYTE $02 + .BYTE $00 ; REF NUM + .BYTE $00,$00,$00 ; EOF L/M/H +READPARMS: +WRITEPARMS: .BYTE $04 + .BYTE $00 ; REF NUM + .ADDR $0000 ; DATA ADDR + .ADDR $0000 ; DATA LEN + .ADDR $0000 ; ACTUAL LEN +INFOPARMS: .BYTE $0A + .WORD $0000 ; PATH ADDR + .BYTE $00 ; ACCESS BITS + .BYTE $00 ; FILE TYPE + .WORD $0000 ; AUX TYPE + .BYTE $00 ; STORAGE TYPE + .WORD $0000 ; BLOCKS USED + .WORD $0000 ; DATE OF LAST MOD + .WORD $0000 ; TIME OF LAST MOD + .WORD $0000 ; CREATE DATE + .WORD $0000 ; CREATE TIME \ No newline at end of file diff --git a/src/java/io/EOFException.java b/src/java/io/EOFException.java new file mode 100755 index 0000000..2b0577f --- /dev/null +++ b/src/java/io/EOFException.java @@ -0,0 +1,10 @@ +package java.io; + +public class EOFException extends IOException +{ + public EOFException(){} + public EOFException(String message) + { + super(message); + } +} \ No newline at end of file diff --git a/src/java/io/FileInputStream.java b/src/java/io/FileInputStream.java new file mode 100755 index 0000000..779df4d --- /dev/null +++ b/src/java/io/FileInputStream.java @@ -0,0 +1,57 @@ +package java.io; +import apple2.*; + +public class FileInputStream extends InputStream +{ + byte[] datumBuffer; + int ioBuffer = 0; + int refNum = 0; + + public FileInputStream(String name) throws FileNotFoundException, IOException + { + ioBuffer = ProDOS.allocIOBuffer(); + if (ioBuffer == 0) + throw new IOException(); + refNum = ProDOS.open(name, ioBuffer); + if (refNum <= 0) + { + ProDOS.freeIOBuffer(ioBuffer); + ioBuffer = 0; + refNum = 0; + throw new FileNotFoundException(); + } + datumBuffer = new byte[1]; + } + + public void close() + { + if (ioBuffer != 0) + { + if (refNum != 0) + { + ProDOS.close(refNum); + refNum = 0; + } + ProDOS.freeIOBuffer(ioBuffer); + ioBuffer = 0; + } + datumBuffer = null; + } + public int read() throws IOException + { + if (ProDOS.read(refNum, datumBuffer, 0, 1) < 0) + throw new IOException(); + return datumBuffer[0]; + } + public int read(byte dataBuffer[]) throws IOException + { + return ProDOS.read(refNum, dataBuffer, 0, dataBuffer.length); + } + public int read(byte dataBuffer[], int off, int len) throws IOException + { + if (dataBuffer == null) + return (int)skip(len); + else + return ProDOS.read(refNum, dataBuffer, off, len); + } +} \ No newline at end of file diff --git a/src/java/io/FileNotFoundException.java b/src/java/io/FileNotFoundException.java new file mode 100755 index 0000000..d42033a --- /dev/null +++ b/src/java/io/FileNotFoundException.java @@ -0,0 +1,10 @@ +package java.io; + +public class FileNotFoundException extends IOException +{ + public FileNotFoundException(){} + public FileNotFoundException(String message) + { + super(message); + } +} \ No newline at end of file diff --git a/src/java/io/FileOutputStream.java b/src/java/io/FileOutputStream.java new file mode 100755 index 0000000..29e360e --- /dev/null +++ b/src/java/io/FileOutputStream.java @@ -0,0 +1,99 @@ +package java.io; +import apple2.*; + +public class FileOutputStream extends OutputStream +{ + byte[] datumBuffer; + int ioBuffer = 0; + int refNum = 0; + + public FileOutputStream(String name) throws FileNotFoundException, IOException + { + open(name, false); + } + public FileOutputStream(String name, boolean append) throws FileNotFoundException, IOException + { + open(name, append); + } + private void open(String name, boolean append) throws FileNotFoundException, IOException + { + byte[] fileInfo = ProDOS.getFileInfo(name); + if (fileInfo[0] == 0) + { + if (fileInfo[7] > 0x03) + // + // Can't write to a directory + // + throw new FileNotFoundException(); + if ((fileInfo[3] & 0x02) == 0x00) + // + // Write disabled + // + throw new IOException(); + } + else + { + if (fileInfo[0] == 0x46) + // + // File not found, so create it. + // + if (ProDOS.create(name, 0xC3, 0x06, 0x0000, 0x01) != 0) + throw new IOException(); + else + throw new IOException(); + } + ioBuffer = ProDOS.allocIOBuffer(); + if (ioBuffer == 0) + throw new IOException(); + refNum = ProDOS.open(name, ioBuffer); + if (refNum <= 0) + { + ProDOS.freeIOBuffer(ioBuffer); + ioBuffer = 0; + refNum = 0; + throw new FileNotFoundException(); + } + datumBuffer = new byte[1]; + if (append) + ProDOS.setMark(refNum, ProDOS.getEOF(refNum)); + else + ProDOS.setEOF(refNum, 0); + } + protected void finalize() + { + if (refNum != 0) + close(); + } + public void close() + { + if (ioBuffer != 0) + { + if (refNum != 0) + { + // + // Truncate file at current position + // + ProDOS.setEOF(refNum, ProDOS.getMark(refNum)); + ProDOS.close(refNum); + refNum = 0; + } + ProDOS.freeIOBuffer(ioBuffer); + ioBuffer = 0; + } + datumBuffer = null; + } + public void write(int b) throws IOException + { + datumBuffer[0] = (byte)b; + if (ProDOS.write(refNum, datumBuffer, 0, 1) < 0) + throw new IOException(); + } + public void write(byte dataBuffer[]) throws IOException + { + ProDOS.write(refNum, dataBuffer, 0, dataBuffer.length); + } + public void write(byte dataBuffer[], int off, int len) throws IOException + { + ProDOS.write(refNum, dataBuffer, off, len); + } +} \ No newline at end of file diff --git a/src/java/io/FilterOutputStream.java b/src/java/io/FilterOutputStream.java new file mode 100755 index 0000000..13c04d1 --- /dev/null +++ b/src/java/io/FilterOutputStream.java @@ -0,0 +1,29 @@ +package java.io; + +public class FilterOutputStream extends OutputStream { + + protected OutputStream out; + + public FilterOutputStream(OutputStream os) + { + out = os; + } + + public void close() + { + out.flush(); + out.close(); + } + public void flush() + { + out.flush(); + } + public void write(byte b) + { + out.write(b); + } + public void write(byte b[], int off, int len) throws IOException + { + out.write(b, off, len); + } +} \ No newline at end of file diff --git a/src/java/io/IOException.java b/src/java/io/IOException.java new file mode 100755 index 0000000..c7551fa --- /dev/null +++ b/src/java/io/IOException.java @@ -0,0 +1,11 @@ +package java.io; +import java.lang.*; + +public class IOException extends Exception +{ + public IOException(){} + public IOException(String message) + { + super(message); + } +} \ No newline at end of file diff --git a/src/java/io/InputStream.java b/src/java/io/InputStream.java new file mode 100755 index 0000000..415508e --- /dev/null +++ b/src/java/io/InputStream.java @@ -0,0 +1,50 @@ +package java.io; + +public class InputStream extends Object { + public InputStream() + { + } + + public int available(){return 0;} + public void close(){} + public void mark(int readLimit){} + public boolean markSupported(){return false;} + public int read() throws IOException {return 0;} + public int read(byte b[]) throws IOException + { + return read(b, 0, b.length); + } + public int read(byte b[], int off, int len) throws IOException + { + int c, i, l = off + len; + + if (b == null) + return (int)skip(len); + else + for (i = off; i < l; i++) + { + c = read(); + if (c < 0) + return (l - i); + b[i] = (byte)c; + } + return len; + } + public void reset(){}; + public long skip(long n) + { + int s = (int)n; + try + { + while ((s-- != 0) && (read() > 0)); + } + catch (IOException e) + { + n = 0; + } + finally + { + return n; + } + } +} \ No newline at end of file diff --git a/src/java/io/OutputStream.java b/src/java/io/OutputStream.java new file mode 100755 index 0000000..e9df7a6 --- /dev/null +++ b/src/java/io/OutputStream.java @@ -0,0 +1,21 @@ +package java.io; + +public class OutputStream extends Object { + public OutputStream() + { + } + + public void close(){} + public void flush(){} + public void write(byte b[]) throws IOException + { + write(b, 0, b.length); + } + public void write(byte b[], int off, int len) throws IOException + { + int i, l = off + len; + for (i = off; i < l; i++) + write(b[i]); + } + public void write(byte b){} +} \ No newline at end of file diff --git a/src/java/io/PrintStream.java b/src/java/io/PrintStream.java new file mode 100755 index 0000000..33868f9 --- /dev/null +++ b/src/java/io/PrintStream.java @@ -0,0 +1,110 @@ +package java.io; + +public class PrintStream extends FilterOutputStream { + public PrintStream(OutputStream out) + { + super(out); + } + public PrintStream(OutputStream out, boolean autoFlush) + { + super(out); + } + + public boolean checkError() + { + flush(); + return false; + } + public void print(boolean b) + { + if (b) + print("true"); + else + print("false"); + } + public void print(char c) + { + write((byte)c); + } + public void print(char s[]) + { + int i; + for (i = 0; i < s.length; i++) + write((byte)s[i]); + } + public void print(float f) + { + print(Float.toString(f)); + } + public void print(int i) + { + byte buffer[] = new byte[15]; + boolean neg = false; + int scanPos = 14; + + if (i < 0) + { + neg = true; + i = -i; + } + do + { + buffer[scanPos--] = (byte)('0' + i % 10); + i /= 10; + } while (i > 0); + if (neg) + buffer[scanPos--] = (byte)'-'; + try + { + write(buffer, scanPos + 1, 14 - scanPos); + } + catch (IOException e) + { + return; + } + } + public void print(Object o) + { + } + public void print(String s) + { + int i, l = s.length(); + for (i = 0; i < l; i++) + print(s.charAt(i)); + } + public void println(boolean b) + { + print(b); + print('\r'); + } + public void println(char c) + { + print(c); + print('\r'); + } + public void println(char s[]) + { + print(s); + print('\r'); + } + public void println(float f) + { + print(Float.toString(f)); + print('\r'); + } + public void println(int i) + { + print(i); + print('\r'); + } + public void println(Object o) + { + print(o); + print('\r'); + } + public void println(String s) + { + print(s); + print('\r'); + } +} \ No newline at end of file diff --git a/src/java/lang/ArithmeticException.java b/src/java/lang/ArithmeticException.java new file mode 100755 index 0000000..7bd29fb --- /dev/null +++ b/src/java/lang/ArithmeticException.java @@ -0,0 +1,10 @@ +package java.lang; + +public class ArithmeticException extends RuntimeException +{ + public ArithmeticException(){} + public ArithmeticException(String message) + { + super(message); + } +} \ No newline at end of file diff --git a/src/java/lang/ArrayIndexOutOfBoundsException.java b/src/java/lang/ArrayIndexOutOfBoundsException.java new file mode 100755 index 0000000..457098f --- /dev/null +++ b/src/java/lang/ArrayIndexOutOfBoundsException.java @@ -0,0 +1,10 @@ +package java.lang; + +public class ArrayIndexOutOfBoundsException extends IndexOutOfBoundsException +{ + public ArrayIndexOutOfBoundsException(){} + public ArrayIndexOutOfBoundsException(String message) + { + super(message); + } +} \ No newline at end of file diff --git a/src/java/lang/ArrayStoreException.java b/src/java/lang/ArrayStoreException.java new file mode 100755 index 0000000..bd4fe01 --- /dev/null +++ b/src/java/lang/ArrayStoreException.java @@ -0,0 +1,10 @@ +package java.lang; + +public class ArrayStoreException extends RuntimeException +{ + public ArrayStoreException(){} + public ArrayStoreException(String message) + { + super(message); + } +} \ No newline at end of file diff --git a/src/java/lang/Boolean.java b/src/java/lang/Boolean.java new file mode 100755 index 0000000..fb7ece0 --- /dev/null +++ b/src/java/lang/Boolean.java @@ -0,0 +1,20 @@ +package java.lang; + +public final class Boolean +{ + private boolean value; + public final static boolean TRUE = true; + public final static boolean FALSE = false; + + public Boolean(boolean b){value = b;} + public Boolean(String s){value = valueOf(s);} + + public boolean booleanValue(){return value;} + public static boolean getBoolean(String name) + { + char b = (name != null) ? name.charAt(0) : 'F'; + return (b == 't' || b == 'T'); + } + public String toString(){return value ? "true" : "false";} + public static Boolean valueOf(String s){return new Boolean(getBoolean(s));} +} \ No newline at end of file diff --git a/src/java/lang/Byte.java b/src/java/lang/Byte.java new file mode 100755 index 0000000..2b20086 --- /dev/null +++ b/src/java/lang/Byte.java @@ -0,0 +1,38 @@ +package java.lang; + +public final class Byte extends Number +{ + private int value; + public final static int MAX_VALUE = 0x7F; + public final static int MIN_VALUE = 0x80; + + public Byte(int i) + { + value = i; + } + public Byte(String s) + { + value = parseByte(s); + } + + + public float floatValue(){return (float)value;} + public int intValue(){return value;} + + public static int parseByte(String s){return parseByte(s, 10);} + public static int parseByte(String s, int radix) + { + return Integer.parseInt(s, radix); + } + public static String toBinaryString(int i){return toString(i, 1);} + public static String toOctalString(int i){return toString(i, 8);} + public static String toHexString(int i){return toString(i, 16);} + public String toString(){return toString(value, 10);} + public static String toString(int i){return toString(i, 10);} + public static String toString(int i, int radix) + { + return Integer.toString(i, radix); + } + public static Byte valueOf(String s){return new Byte(s);} + public static Byte valueOf(String s, int radix){return new Byte(parseByte(s, radix));} +} \ No newline at end of file diff --git a/src/java/lang/Character.java b/src/java/lang/Character.java new file mode 100755 index 0000000..d6db82e --- /dev/null +++ b/src/java/lang/Character.java @@ -0,0 +1,48 @@ +package java.lang; +import apple2.*; + +public final class Character +{ + private char value; + public final static int MAX_RADIX = 36; + public final static int MIN_RADIX = 2; + public final static char MAX_VALUE = (char)0xFFFF; + public final static char MIN_VALUE = (char)0x0000; + + public Character(char ch){value = ch;} + + public char charValue(){return value;} + public static int digit(char ch, int radix) + { + if (ch >= '0' && ch <= '9') + return ch - '0'; + if (ch >= 'a' && ch <= 'z') + return ch - 'a' + 10; + if (ch >= 'A' && ch <= 'Z') + return ch - 'A' + 10; + return -1; + } + public static char forDigit(int digit, int radix){return (char)(digit + (digit > 9 ? 'a' : '0'));} + public static boolean isDefined(char ch){return ch >= 0 && ch <= 255;} + public static boolean isDigit(char ch){return ch >= '0' && ch <= '9';} + public static boolean isJavaLetter(char ch){return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch == '$') || (ch == '_');} + public static boolean isJavaLetterOrDigit(char ch){return (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch == '$') || (ch == '_');} + public static boolean isLetter(char ch){return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch == '$') || (ch == '_');} + public static boolean isLetterOrDigit(char ch){return (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch == '$') || (ch == '_');} + public static boolean isUpperCase(char ch){return (ch >= 'A' && ch <= 'Z');} + public static boolean isLowerCase(char ch){return (ch >= 'a' && ch <= 'z');} + public static char toUpperCase(char ch){return (char)((ch >= 'a' && ch <= 'z') ? (ch - 'A' + 'a') : ch);} + public static char toLowerCase(char ch){return (char)((ch >= 'A' && ch <= 'Z') ? (ch - 'a' + 'A') : ch);} + public static char toTitleCase(char ch){return ch;} + public String toString() + { + byte buffer[] = new byte[2]; + int buffptr, refStr; + buffer[0] = 1; + buffer[2] = (byte)value; + buffptr = vm02.call(vm02.refAsBits((Object)buffer), 0x0E) + 2; // HMEM_LOCK + refStr = vm02.call(buffptr, 0x46); // HSTRPL_ADD + vm02.call(vm02.refAsBits((Object)buffer), 0x10); // HMEM_UNLOCK + return (String)vm02.bitsAsRef((refStr & 0xFFFF) | 0x00830000 | ((refStr << 8) & 0xFF000000)); + } +} \ No newline at end of file diff --git a/src/java/lang/ClassCastException.java b/src/java/lang/ClassCastException.java new file mode 100755 index 0000000..ef1353d --- /dev/null +++ b/src/java/lang/ClassCastException.java @@ -0,0 +1,10 @@ +package java.lang; + +public class ClassCastException extends RuntimeException +{ + public ClassCastException(){} + public ClassCastException(String message) + { + super(message); + } +} \ No newline at end of file diff --git a/src/java/lang/ClassFormatError.java b/src/java/lang/ClassFormatError.java new file mode 100755 index 0000000..a061211 --- /dev/null +++ b/src/java/lang/ClassFormatError.java @@ -0,0 +1,10 @@ +package java.lang; + +public class ClassFormatError extends LinkeageError +{ + public ClassFormatError(){} + public ClassFormatError(String message) + { + super(message); + } +} \ No newline at end of file diff --git a/src/java/lang/ClassNotFoundException.java b/src/java/lang/ClassNotFoundException.java new file mode 100755 index 0000000..91196cb --- /dev/null +++ b/src/java/lang/ClassNotFoundException.java @@ -0,0 +1,10 @@ +package java.lang; + +public class ClassNotFoundException extends Exception +{ + public ClassNotFoundException(){} + public ClassNotFoundException(String message) + { + super(message); + } +} \ No newline at end of file diff --git a/src/java/lang/Double.java b/src/java/lang/Double.java new file mode 100755 index 0000000..358e817 --- /dev/null +++ b/src/java/lang/Double.java @@ -0,0 +1,33 @@ +package java.lang; + +public final class Double extends Number +{ + private double value; + public Double(double d) + { + } + public Double(String s) + { + } + + + public float floatValue(){return (float)value;} + public int intValue(){return (int)value;} + + public static double parseDouble(String s){return parseDouble(s, 10);} + public static double parseDouble(String s, int radix) + { + return 0.0; + } + public static String toBinaryString(double d){return toString(d, 1);} + public static String toOctalString(double d){return toString(d, 8);} + public static String toHexString(double d){return toString(d, 16);} + public String toString(){return toString(value, 10);} + public static String toString(double d){return toString(d, 10);} + public static String toString(double d, int radix) + { + return ""; + } + public static Double valueOf(String s){return new Double(s);} + public static Double valueOf(String s, int radix){return new Double(parseDouble(s, radix));} +} diff --git a/src/java/lang/Error.java b/src/java/lang/Error.java new file mode 100755 index 0000000..7080876 --- /dev/null +++ b/src/java/lang/Error.java @@ -0,0 +1,10 @@ +package java.lang; + +public class Error extends Throwable +{ + public Error(){} + public Error(String message) + { + super(message); + } +} \ No newline at end of file diff --git a/src/java/lang/Exception.java b/src/java/lang/Exception.java new file mode 100755 index 0000000..1318f8c --- /dev/null +++ b/src/java/lang/Exception.java @@ -0,0 +1,10 @@ +package java.lang; + +public class Exception extends Throwable +{ + public Exception(){} + public Exception(String message) + { + super(message); + } +} \ No newline at end of file diff --git a/src/java/lang/Float.java b/src/java/lang/Float.java new file mode 100755 index 0000000..aecbb5a --- /dev/null +++ b/src/java/lang/Float.java @@ -0,0 +1,275 @@ +package java.lang; +import apple2.*; + +public final class Float extends Number +{ + private float value; + public final static float MAX_VALUE = 0x7FFFFFFF; + public final static float MIN_VALUE = 0x80000000; + public final static float NaN = 0x80000000; + public final static float POSITIVE_INFINITY = 0x80000000; + public final static float NEGATIVE_INFINITY = 0x80000000; + private final static float[] twoPow10 = {1E+1F,1E+2F,1E+4F,1E+8F,1E+16F,1E+32F,0F,0F}; + private final static float[] pow10 = {1E+0F,1E+1F,1E+2F,1E+3F,1E+4F,1E+5F,1E+6F,1E+7F,1E+8F, + 1E+9F,1E+10F,1E+11F,1E+12F,1E+13F,1E+14F,1E+15F,1E+16F,1E+17F, + 1E+18F,1E+19F,1E+20F,1E+21F,1E+22F,1E+23F,1E+24F,1E+25F,1E+26F, + 1E+27F,1E+28F,1E+29F,1E+30F,1E+31F,1E+32F,1E+33F,1E+34F,1E+35F,1E+36F, + 1E+37F,1E+38F}; + + public Float(float fp) + { + value = fp; + } + public Float(String s) + { + value = parseFloat(s); + } + + + public float floatValue(){return value;} + public int intValue(){return (int)value;} + public static int floatToIntBits(float fp){return vm02.floatAsBits(fp);} + public static float intToFloatBits(int i){return vm02.bitsAsFloat(i);} + public static float trunc(float fp) + { + int mask, exp, fpBits = vm02.floatAsBits(fp); + + exp = (fpBits >> 23) & 0xFF; + if (exp >= 151) // fp too big for any valid frac bits + return fp; + if (exp < 127) // fp already smaller than 1.0 + return 0.0F; + // + // Mask off fractional bits + // + mask = 0x007FFFFF >> (exp - 127); + return vm02.bitsAsFloat(fpBits & ~mask); + } + public static float frac(float fp) + { + int sign, exp, mant, fpBits = vm02.floatAsBits(fp); + + exp = (fpBits >> 23) & 0xFF; + if (exp >= 151) // fp too big for any valid frac bits + return 0.0F; + if (exp < 127) // fp already smaller than 1.0 + return fp; + sign = fpBits & 0x80000000; + mant = (fpBits & 0x00FFFFFF) | 0x00800000; + // + // Mask off bits above 1.0 + // + mant &= 0x007FFFFF >> (exp - 127); + if (mant == 0) + return 0.0F; + // + // Normalize mantissa + // + while ((mant & 0x00800000) == 0) + { + exp--; + mant <<= 1; + } + return vm02.bitsAsFloat(sign | (exp << 23) | (mant & 0x007FFFFF)); + } + public static Float valueOf(String s){return new Float(s);} + public static float parseFloat(String s) + { + float fp = 0.0F; + float scale; + char c; + int place, digit; + int scanPos = 0; + int dp = 0; + boolean neg = false; + boolean negExp = false; + + // + // Check sign + // + c = s.charAt(0); + if (c == '-') + { + neg = true; + scanPos++; + } + else if (c == '+') + scanPos++; + // + // Scan integer + // + while (scanPos < s.length()) + { + c = s.charAt(scanPos++); + digit = c - '0'; + if (digit < 0 || digit > 9) + break; + fp = (fp * 10.0F) + digit; + } + if (c == '.') + { + // + // Scan fractional + // + scanPos++; + while (scanPos < s.length()) + { + c = s.charAt(scanPos++); + digit = c - '0'; + if (digit < 0 || digit > 9) + break; + dp--; + fp = (fp * 10.0F) + digit; + } + } + if ((c == 'e' || c == 'E') && (scanPos < s.length() - 1)) + { + // + // Scan exponent + // + int exp = 0; + + scanPos++; + if (s.charAt(scanPos) == '-') + { + negExp = true; + scanPos++; + } + else if (s.charAt(scanPos) == '+') + scanPos++; + while (scanPos < s.length()) + { + c = s.charAt(scanPos++); + digit = c - '0'; + if (digit < 0 || digit > 9) + break; + exp = exp * 10 + digit; + } + if (negExp) + exp = -exp; + dp += exp; + } + if (dp < 0) + { + dp = -dp; + negExp = true; + } + else + negExp = false; + // + // Apply scale + // + for (place = 0, scale = 1.0F; dp != 0; dp >>= 1, place++) + if ((dp & 1) != 0) + scale *= twoPow10[place]; + if (negExp) + fp /= scale; + else + fp *= scale; + return neg ? -fp : fp; + } + public String toString(){return toString(value);} + public static String toString(float fp) + { + byte buffer[] = new byte[33]; + boolean skipZero, neg = false; + int buffptr, refStr, scanPos = 32; + int dp, fp10, exp10, digit, exp, mant, fpBits = vm02.floatAsBits(fp); + float fpsci = 0.0F; + + if (fpBits < 0) + { + fp = -fp; + neg = true; + } + exp = ((fpBits >> 23) & 0xFF) - 127; + mant = (fpBits & 0x00FFFFFF) | 0x00800000; + // + // Convert float to number between 1.0 and 10.0 + // with exp10 being orignal power of ten. + // + if (fp == 0.0F) + { + exp10 = 0; + fp10 = 0; + } + else + { + // + // Law of logarithms LOG10 X = LOG10 2 * LOG2 X + // = .30103 * LOG2 X + // ~ 154 / 512 * LOG2 X + // + exp10 = (exp * 154) >> 9; + fpsci = (exp10 < 0) ? (fp * pow10[-exp10]) : (fp / pow10[exp10]); + // + // Make adjustment if needed + // + if (fpsci >= 10.0F) + { + fpsci *= 0.1F; + exp10++; + } + else if (fpsci < 1.0F) + { + fpsci *= 10.0F; + exp10--; + } + } + if (exp10 < 6 && exp10 > -4) + { + // + // Standard floating point - 4 fractional digits + // + dp = ((exp10 < 0) ? -exp10 : 0) + 4; + fp10 = (int)(fp * pow10[dp] + 0.5F); + } + else + { + // + // Scientific notation - 5 fractional digits + // + dp = 5; + fp10 = (int)(fpsci * 100000.0F + 0.5F); + // + // Print exponent + // + buffer[scanPos--] = (byte)(exp10 % 10 | '0'); + buffer[scanPos--] = (byte)(exp10 / 10 | '0'); + buffer[scanPos--] = (exp10 < 0) ? (byte)'-' : (byte)'+'; + buffer[scanPos--] = (byte)'E'; + } + // + // Print fractional number + // + skipZero = true; + while (--dp > 0) + { + digit = fp10 % 10; + fp10 /= 10; + if (!skipZero || digit != 0) + { + buffer[scanPos--] = (byte)('0' + digit); + skipZero = false; + } + } + buffer[scanPos--] = (byte)('0' + fp10 % 10); + buffer[scanPos--] = (byte)'.'; + fp10 /= 10; + // + // Print integral number + // + do + { + buffer[scanPos--] = (byte)('0' + (fp10 % 10)); + fp10 /= 10; + } while (fp10 > 0); + if (neg) + buffer[scanPos--] = (byte)'-'; + buffer[scanPos] = (byte)(32 - scanPos); + buffptr = vm02.call(vm02.refAsBits((Object)buffer), 0x0E) + 2 + scanPos ; // HMEM_LOCK + refStr = vm02.call(buffptr, 0x46); // HSTRPL_ADD + vm02.call(vm02.refAsBits((Object)buffer), 0x10); // HMEM_UNLOCK + return (String)vm02.bitsAsRef((refStr & 0xFFFF) | 0x00830000 | ((refStr << 8) & 0xFF000000)); + } +} \ No newline at end of file diff --git a/src/java/lang/IllegalArgumentException.java b/src/java/lang/IllegalArgumentException.java new file mode 100755 index 0000000..22f36f8 --- /dev/null +++ b/src/java/lang/IllegalArgumentException.java @@ -0,0 +1,10 @@ +package java.lang; + +public class IllegalArgumentException extends RuntimeException +{ + public IllegalArgumentException(){} + public IllegalArgumentException(String message) + { + super(message); + } +} \ No newline at end of file diff --git a/src/java/lang/IllegalMonitorStateException.java b/src/java/lang/IllegalMonitorStateException.java new file mode 100755 index 0000000..e934aca --- /dev/null +++ b/src/java/lang/IllegalMonitorStateException.java @@ -0,0 +1,10 @@ +package java.lang; + +public class IllegalMonitorStateException extends RuntimeException +{ + public IllegalMonitorStateException(){} + public IllegalMonitorStateException(String message) + { + super(message); + } +} \ No newline at end of file diff --git a/src/java/lang/IllegalThreadStateException.java b/src/java/lang/IllegalThreadStateException.java new file mode 100755 index 0000000..0007134 --- /dev/null +++ b/src/java/lang/IllegalThreadStateException.java @@ -0,0 +1,10 @@ +package java.lang; + +public class IllegalThreadStateException extends IllegalArgumentException +{ + public IllegalThreadStateException(){} + public IllegalThreadStateException(String message) + { + super(message); + } +} \ No newline at end of file diff --git a/src/java/lang/IncompatibleClassChangeError.java b/src/java/lang/IncompatibleClassChangeError.java new file mode 100755 index 0000000..5770a6c --- /dev/null +++ b/src/java/lang/IncompatibleClassChangeError.java @@ -0,0 +1,10 @@ +package java.lang; + +public class IncompatibleClassChangeError extends LinkeageError +{ + public IncompatibleClassChangeError(){} + public IncompatibleClassChangeError(String message) + { + super(message); + } +} \ No newline at end of file diff --git a/src/java/lang/IndexOutOfBoundsException.java b/src/java/lang/IndexOutOfBoundsException.java new file mode 100755 index 0000000..79283ed --- /dev/null +++ b/src/java/lang/IndexOutOfBoundsException.java @@ -0,0 +1,10 @@ +package java.lang; + +public class IndexOutOfBoundsException extends RuntimeException +{ + public IndexOutOfBoundsException(){} + public IndexOutOfBoundsException(String message) + { + super(message); + } +} \ No newline at end of file diff --git a/src/java/lang/Integer.java b/src/java/lang/Integer.java new file mode 100755 index 0000000..d4e39c4 --- /dev/null +++ b/src/java/lang/Integer.java @@ -0,0 +1,82 @@ +package java.lang; +import apple2.*; + +public final class Integer extends Number +{ + private int value; + public final static int MAX_VALUE = 0x7FFFFFFF; + public final static int MIN_VALUE = 0x80000000; + + public Integer(int i) + { + value = i; + } + public Integer(String s) + { + value = parseInt(s); + } + + + public float floatValue(){return (float)value;} + public int intValue(){return value;} + + public static int parseInt(String s){return parseInt(s, 10);} + public static int parseInt(String s, int radix) + { + char c; + int digit, value = 0, scanPos = 0; + boolean neg = false; + + if (s.charAt(0) == '-') + { + neg = true; + scanPos++; + } + while (scanPos < s.length()) + { + c = s.charAt(scanPos++); + if (c <= '9') + digit = c - '0'; + else if (c >= 'a') + digit = c - ('a' - 10); + else + digit = c - ('A' - 10); + if (digit < 0 || digit >= radix) + break; + value = (value * radix) + digit; + } + return neg ? -value : value; + } + public static String toBinaryString(int i){return toString(i, 1);} + public static String toOctalString(int i){return toString(i, 8);} + public static String toHexString(int i){return toString(i, 16);} + public String toString(){return toString(value, 10);} + public static String toString(int i){return toString(i, 10);} + public static String toString(int i, int radix) + { + byte buffer[] = new byte[33]; + boolean neg = false; + int digit, buffptr, refStr, scanPos = 32; + + if (i < 0) + { + neg = true; + i = -i; + } + do + { + digit = i % radix; + buffer[scanPos--] = (byte)(digit + ((digit > 9) ? ('A' - 10) : '0')); + i /= radix; + } while (i > 0); + if (neg) + buffer[scanPos--] = (byte)'-'; + buffer[scanPos] = (byte)(32 - scanPos); + buffptr = vm02.call(vm02.refAsBits((Object)buffer), 0x0E) + 2 + scanPos; // HMEM_LOCK + refStr = vm02.call(buffptr, 0x46); // HSTRPL_ADD + vm02.call(vm02.refAsBits((Object)buffer), 0x10); // HMEM_UNLOCK + return (String)vm02.bitsAsRef((refStr & 0xFFFF) | 0x00830000 | ((refStr << 8) & 0xFF000000)); + } + public static Integer valueOf(String s){return new Integer(s);} + public static Integer valueOf(String s, int radix){return new Integer(parseInt(s, radix));} +} \ No newline at end of file diff --git a/src/java/lang/InternalError.java b/src/java/lang/InternalError.java new file mode 100755 index 0000000..21c6185 --- /dev/null +++ b/src/java/lang/InternalError.java @@ -0,0 +1,10 @@ +package java.lang; + +public class InternalError extends VirtualMachineError +{ + public InternalError(){} + public InternalError(String message) + { + super(message); + } +} \ No newline at end of file diff --git a/src/java/lang/InterruptedException.java b/src/java/lang/InterruptedException.java new file mode 100755 index 0000000..3a13353 --- /dev/null +++ b/src/java/lang/InterruptedException.java @@ -0,0 +1,10 @@ +package java.lang; + +public class InterruptedException extends Exception +{ + public InterruptedException(){} + public InterruptedException(String message) + { + super(message); + } +} \ No newline at end of file diff --git a/src/java/lang/LinkeageError.java b/src/java/lang/LinkeageError.java new file mode 100755 index 0000000..79750c9 --- /dev/null +++ b/src/java/lang/LinkeageError.java @@ -0,0 +1,10 @@ +package java.lang; + +public class LinkeageError extends Error +{ + public LinkeageError(){} + public LinkeageError(String message) + { + super(message); + } +} \ No newline at end of file diff --git a/src/java/lang/Long.java b/src/java/lang/Long.java new file mode 100755 index 0000000..ed96021 --- /dev/null +++ b/src/java/lang/Long.java @@ -0,0 +1,38 @@ +package java.lang; + +public final class Long extends Number +{ + private int value; + public final static int MAX_VALUE = 0x7FFFFFFF; + public final static int MIN_VALUE = 0x80000000; + + public Long(int i) + { + value = i; + } + public Long(String s) + { + value = parseLong(s); + } + + + public float floatValue(){return (float)value;} + public int intValue(){return value;} + + public static int parseLong(String s){return parseLong(s, 10);} + public static int parseLong(String s, int radix) + { + return Integer.parseInt(s, radix); + } + public static String toBinaryString(int i){return toString(i, 1);} + public static String toOctalString(int i){return toString(i, 8);} + public static String toHexString(int i){return toString(i, 16);} + public String toString(){return toString(value, 10);} + public static String toString(int i){return toString(i, 10);} + public static String toString(int i, int radix) + { + return Integer.toString(i, radix); + } + public static Long valueOf(String s){return new Long(s);} + public static Long valueOf(String s, int radix){return new Long(parseLong(s, radix));} +} \ No newline at end of file diff --git a/src/java/lang/NegativeArraySizeException.java b/src/java/lang/NegativeArraySizeException.java new file mode 100755 index 0000000..b98d97e --- /dev/null +++ b/src/java/lang/NegativeArraySizeException.java @@ -0,0 +1,10 @@ +package java.lang; + +public class NegativeArraySizeException extends RuntimeException +{ + public NegativeArraySizeException(){} + public NegativeArraySizeException(String message) + { + super(message); + } +} \ No newline at end of file diff --git a/src/java/lang/NoClassDefFoundError.java b/src/java/lang/NoClassDefFoundError.java new file mode 100755 index 0000000..658bfe9 --- /dev/null +++ b/src/java/lang/NoClassDefFoundError.java @@ -0,0 +1,10 @@ +package java.lang; + +public class NoClassDefFoundError extends LinkeageError +{ + public NoClassDefFoundError(){} + public NoClassDefFoundError(String message) + { + super(message); + } +} \ No newline at end of file diff --git a/src/java/lang/NoSuchFieldError.java b/src/java/lang/NoSuchFieldError.java new file mode 100755 index 0000000..715c789 --- /dev/null +++ b/src/java/lang/NoSuchFieldError.java @@ -0,0 +1,10 @@ +package java.lang; + +public class NoSuchFieldError extends IncompatibleClassChangeError +{ + public NoSuchFieldError(){} + public NoSuchFieldError(String message) + { + super(message); + } +} \ No newline at end of file diff --git a/src/java/lang/NoSuchMethodError.java b/src/java/lang/NoSuchMethodError.java new file mode 100755 index 0000000..481eede --- /dev/null +++ b/src/java/lang/NoSuchMethodError.java @@ -0,0 +1,10 @@ +package java.lang; + +public class NoSuchMethodError extends IncompatibleClassChangeError +{ + public NoSuchMethodError(){} + public NoSuchMethodError(String message) + { + super(message); + } +} \ No newline at end of file diff --git a/src/java/lang/NullPointerException.java b/src/java/lang/NullPointerException.java new file mode 100755 index 0000000..2c6ae2c --- /dev/null +++ b/src/java/lang/NullPointerException.java @@ -0,0 +1,10 @@ +package java.lang; + +public class NullPointerException extends RuntimeException +{ + public NullPointerException(){} + public NullPointerException(String message) + { + super(message); + } +} \ No newline at end of file diff --git a/src/java/lang/Number.java b/src/java/lang/Number.java new file mode 100755 index 0000000..4d85356 --- /dev/null +++ b/src/java/lang/Number.java @@ -0,0 +1,7 @@ +package java.lang; + +public abstract class Number +{ + public float floatValue(){return 0.0F;} + public int intValue(){return 0;} +} \ No newline at end of file diff --git a/src/java/lang/OutOfMemoryError.java b/src/java/lang/OutOfMemoryError.java new file mode 100755 index 0000000..3c8eece --- /dev/null +++ b/src/java/lang/OutOfMemoryError.java @@ -0,0 +1,10 @@ +package java.lang; + +public class OutOfMemoryError extends VirtualMachineError +{ + public OutOfMemoryError(){} + public OutOfMemoryError(String message) + { + super(message); + } +} \ No newline at end of file diff --git a/src/java/lang/Runnable.java b/src/java/lang/Runnable.java new file mode 100755 index 0000000..0c3340b --- /dev/null +++ b/src/java/lang/Runnable.java @@ -0,0 +1,6 @@ +package java.lang; + +public interface Runnable +{ + public void run(); +} diff --git a/src/java/lang/RuntimeException.java b/src/java/lang/RuntimeException.java new file mode 100755 index 0000000..3c82bfc --- /dev/null +++ b/src/java/lang/RuntimeException.java @@ -0,0 +1,10 @@ +package java.lang; + +public class RuntimeException extends Exception +{ + public RuntimeException(){} + public RuntimeException(String message) + { + super(message); + } +} \ No newline at end of file diff --git a/src/java/lang/Short.java b/src/java/lang/Short.java new file mode 100755 index 0000000..bef3ab2 --- /dev/null +++ b/src/java/lang/Short.java @@ -0,0 +1,38 @@ +package java.lang; + +public final class Short extends Number +{ + private int value; + public final static int MAX_VALUE = 0x7FFF; + public final static int MIN_VALUE = 0x8000; + + public Short(int i) + { + value = i; + } + public Short(String s) + { + value = parseShort(s); + } + + + public float floatValue(){return (float)value;} + public int intValue(){return value;} + + public static int parseShort(String s){return parseShort(s, 10);} + public static int parseShort(String s, int radix) + { + return Integer.parseInt(s, radix); + } + public static String toBinaryString(int i){return toString(i, 1);} + public static String toOctalString(int i){return toString(i, 8);} + public static String toHexString(int i){return toString(i, 16);} + public String toString(){return toString(value, 10);} + public static String toString(int i){return toString(i, 10);} + public static String toString(int i, int radix) + { + return Integer.toString(i, radix); + } + public static Short valueOf(String s){return new Short(s);} + public static Short valueOf(String s, int radix){return new Short(parseShort(s, radix));} +} \ No newline at end of file diff --git a/src/java/lang/StackOverflowError.java b/src/java/lang/StackOverflowError.java new file mode 100755 index 0000000..6ff2b75 --- /dev/null +++ b/src/java/lang/StackOverflowError.java @@ -0,0 +1,10 @@ +package java.lang; + +public class StackOverflowError extends VirtualMachineError +{ + public StackOverflowError(){} + public StackOverflowError(String message) + { + super(message); + } +} \ No newline at end of file diff --git a/src/java/lang/StringBuilder.java b/src/java/lang/StringBuilder.java new file mode 100755 index 0000000..b59e1ec --- /dev/null +++ b/src/java/lang/StringBuilder.java @@ -0,0 +1,99 @@ +package java.lang; +import apple2.*; + +public class StringBuilder +{ + private short bufLen; + private byte buffer[]; + + public StringBuilder() + { + newBuffer(16); + } + public StringBuilder(int len) + { + newBuffer(len); + } + public StringBuilder(String str) + { + int bufSize; + if (str.length() > 240) + bufSize = 255; + else + bufSize = str.length() + 16; + newBuffer(bufSize); + append(str); + } + private void newBuffer(int size) + { + buffer = new byte[size]; + bufLen = 0; // Set working string length + } + private void expandBuffer(int newSize) + { + if (newSize > 255) + newSize = 255; + if (newSize > buffer.length) + { + byte bigBuff[] = new byte[newSize]; + for (int i = buffer.length - 1; i >= 0 ; i--) + bigBuff[i] = buffer[i]; + buffer = bigBuff; + } + } + public StringBuilder append(boolean b) + { + append(b ? " true " : " false "); + return this; + + } + public StringBuilder append(char c) + { + if (buffer.length == bufLen) + expandBuffer(buffer.length + 16); + if (bufLen < 255) + buffer[bufLen++] = (byte)c; + return this; + } + public StringBuilder append(float f) + { + return append(Float.toString(f)); + } + public StringBuilder append(int i) + { + return append(Integer.toString(i)); + } + public StringBuilder append(Object obj) + { + // return append(Object.toString(obj)); + return this; + } + public StringBuilder append(String str) + { + int i; + if (str != null) + { + if (buffer.length < (bufLen + str.length())) + expandBuffer(buffer.length + str.length() + 16); + for (i = 0; i < str.length(); i++) + if (bufLen < 255) + buffer[bufLen++] = (byte)str.charAt(i); + } + return this; + } + public int capacity() + { + return buffer.length; + } + public int length() + { + return bufLen; + } + public String toString() + { + // + // Create a String object ref from buffer array. + // + return new String(buffer, 0, bufLen); + } +} \ No newline at end of file diff --git a/src/java/lang/StringIndexOutOfBoundsException.java b/src/java/lang/StringIndexOutOfBoundsException.java new file mode 100755 index 0000000..2306c74 --- /dev/null +++ b/src/java/lang/StringIndexOutOfBoundsException.java @@ -0,0 +1,10 @@ +package java.lang; + +public class StringIndexOutOfBoundsException extends IndexOutOfBoundsException +{ + public StringIndexOutOfBoundsException(){} + public StringIndexOutOfBoundsException(String message) + { + super(message); + } +} \ No newline at end of file diff --git a/src/java/lang/System.java b/src/java/lang/System.java new file mode 100755 index 0000000..98092ee --- /dev/null +++ b/src/java/lang/System.java @@ -0,0 +1,39 @@ +package java.lang; +import apple2.*; + +public final class System extends Object { + public static java.io.PrintStream err = new apple2.PrintConsole(); + public static java.io.InputStream in = new apple2.InputConsole(); + public static java.io.PrintStream out = new apple2.PrintConsole(); + + public static void arraycopy(Object src, int srcpos, + Object dst, int dstpos, + int len){}; + public static long currentTimeMillis() + { + int msh, msl; + do + { + msh = vm02.call(0, 0x3C) << 16; // THREAD_GETTICH + msl = vm02.call(0, 0x3A) & 0xFFFF; // THREAD_GETTICL + } while (msh != (vm02.call(0, 0x3C) << 16)); // THREAD_GETTICH + return (msl | msh); + } + public static void exit(int status) + { + vm02.call(status, 0xEE); + } + public static void gc() + { + vm02.call(256, 0x64); + vm02.call(0, 0x00); // THREAD_YIELD + } + public static void load(String filename) + { + vm02.call(vm02.refAsBits(filename), 0x62); + } + public static void runFinalization() + { + gc(); + } +} \ No newline at end of file diff --git a/src/java/lang/Thread.java b/src/java/lang/Thread.java new file mode 100755 index 0000000..63ee69d --- /dev/null +++ b/src/java/lang/Thread.java @@ -0,0 +1,111 @@ +package java.lang; +import apple2.*; + +public class Thread implements Runnable +{ + private int tid; + private String tname; + private Runnable ttarget; + public final static int MAX_PRIORITY = 10; + public final static int MIN_PRIORITY = 5; + public final static int NORM_PRIORITY = 1; + + public Thread() + { + int tparam; + ttarget = this; + tid = vm02.call(vm02.refAsBits(this), 0x12) & 0x00FF0000; // THREAD_NEW + tparam = (vm02.refAsBits(this) >> 16) & 0xFFFF; + vm02.call(tid | tparam, 0x2C); // THREAD_SETCLASS +// vm02.call(vm02.refAsBits(this), 0x56); // HMEM_REF_INC + + } + public Thread(Runnable target){} + public Thread(Runnable target, String name){} + public Thread(String name){} + public Thread(ThreadGroup group, Runnable target){} + public Thread(ThreadGroup group, Runnable target, String name){} + public Thread(ThreadGroup group, String name){} + private Thread(int forcetid) + { + int tparam; + tid = forcetid; + tparam = vm02.refAsBits(this) & 0xFFFF; + vm02.call(forcetid | tparam, 0x2E); // THREAD_SETREF + tparam = (vm02.refAsBits(this) >> 16) & 0xFFFF; + vm02.call(forcetid | tparam, 0x2C); // THREAD_SETCLASS + vm02.call(vm02.refAsBits(this), 0x56); // HMEM_REF_INC + } + public static int activeCount(){return 0;} + public void checkAccess(){} + public int countStackFrames(){return 0;} + public static Thread currentThread() + { + Thread curobj; + int curtid = vm02.call(0, 0x1C) & 0x00FF0000; // THREAD_GET_CURRENT + int tref = vm02.call(curtid, 0x32) & 0xFFFF; // THREAD_GETREF + tref |= vm02.call(curtid, 0x30) << 16; // THREAD_GETCLASS + if (tref == 0) + curobj = new Thread(curtid); // Force Thread object for current thread which doesn't have one + else + curobj = (Thread)vm02.bitsAsRef(tref); + return curobj; + } + public void destroy(){} + public static void dumpStack() + { + vm02.call(0, 0xE4); // THREAD_DUMPSTACK + } + public static int enumerate(Thread tarray[]){return 0;} + public final String getName(){return null;} + public final int getPriority(){return 0;} + public final ThreadGroup getThreadGroup(){return null;} + public void interrupt(){} + public static boolean interrupted(){return false;} + public final boolean isAlive(){return true;} + public final boolean isDaemon(){return true;} + public boolean isInterrupted(){return true;} + public final void join(){} + public final void join(long millis){} + public final void join(long millis, int nanos){} + public final void resume(){} + public void run(){} + public final void setDaemon(boolean on){} + public final void setName(String name){} + public final void setPriority(int newPriority) + { + int curtid = vm02.call(0, 0x1C) & 0x00FF0000; // THREAD_GET_CURRENT + vm02.call(curtid | newPriority, 0x28); // THREAD_SETPRIORITY + } + public static void sleep(long millis) + { + int tparam = (int)millis; + int curtid = vm02.call(0, 0x1C) & 0x00FF0000; // THREAD_GET_CURRENT + vm02.call(curtid | (tparam & 0xFFFF), 0x1E); // THREAD_SETTIMEOUTL + vm02.call(curtid | (tparam >> 16 ), 0x20); // THREAD_SETTIMEOUTH + vm02.call(curtid | 0x03, 0x24); // THREAD_SETSTATE = S_SLEEP + } + public static void sleep(long millis, int nanos){} + public void start() + { + int tparam = vm02.refAsBits(ttarget); + int pushparamh, pushparaml; + + ttarget = null; // Unref self + pushparamh = ((tparam >> 24) & 0x00FF) + | ((tparam >> 16) & 0xFF00); + pushparaml = ((tparam >> 8) & 0x00FF) + | ((tparam << 8) & 0xFF00); + vm02.call(tid | pushparamh, 0x14); // THREAD_PUSH + vm02.call(tid | pushparaml, 0x14); // THREAD_PUSH + vm02.call(tid | ((tparam >> 16) & 0xFF), 0x16); // THREAD_START + } + public final void stop(){} + public final void stop(Throwable obj){} + public final void suspend(){} + public String toString(){return null;} + public static void yield() + { + vm02.call(0, 0x00); // THREAD_YIELD + } +} diff --git a/src/java/lang/ThreadDeath.java b/src/java/lang/ThreadDeath.java new file mode 100755 index 0000000..76bc64f --- /dev/null +++ b/src/java/lang/ThreadDeath.java @@ -0,0 +1,6 @@ +package java.lang; + +public class ThreadDeath extends Error +{ + public ThreadDeath(){} +} \ No newline at end of file diff --git a/src/java/lang/ThreadGroup.java b/src/java/lang/ThreadGroup.java new file mode 100755 index 0000000..4ef0857 --- /dev/null +++ b/src/java/lang/ThreadGroup.java @@ -0,0 +1,5 @@ +package java.lang; +public class ThreadGroup +{ + public ThreadGroup(String name) {} +} diff --git a/src/java/lang/Throwable.java b/src/java/lang/Throwable.java new file mode 100755 index 0000000..5c6215f --- /dev/null +++ b/src/java/lang/Throwable.java @@ -0,0 +1,23 @@ +package java.lang; + +import apple2.*; + +public class Throwable +{ + private String msg; + + public Throwable(){} + public Throwable(String message) + { + msg = message; + } + + public String getMessage() + { + return msg; + } + public void printStackTrace() + { + vm02.call(0, 0xEC); // THREAD_DUMPSTACK + } +} \ No newline at end of file diff --git a/src/java/lang/VirtualMachineError.java b/src/java/lang/VirtualMachineError.java new file mode 100755 index 0000000..7d88dca --- /dev/null +++ b/src/java/lang/VirtualMachineError.java @@ -0,0 +1,10 @@ +package java.lang; + +public class VirtualMachineError extends Error +{ + public VirtualMachineError(){} + public VirtualMachineError(String message) + { + super(message); + } +} \ No newline at end of file diff --git a/src/java/net/Loopback.java b/src/java/net/Loopback.java new file mode 100755 index 0000000..02c422c --- /dev/null +++ b/src/java/net/Loopback.java @@ -0,0 +1,171 @@ +package java.net; +/* + * This class implements the loopback device. + */ + +public class Loopback extends NetworkDevice +{ + static private final int IDLE_OP = 0; + static private final int WRITE_OP = 1; + static private final int READ_OP = 2; + static private int readOffset, writeOffset, xferOp, packetLen; + static private Thread readThread; + static private byte[] packet; + + public static boolean enable() + { + xferOp = IDLE_OP; + readOffset = 0; + writeOffset = 0; + packetLen = 0; + packet = null; + return true; + } + public static void disable() + { + packet = null; + if (readThread != null) + readThread.notify(); + } + public static int minDataSize() + { + return 0; + } + public static int maxDataSize() + { + return 2000; + } + public static byte[] localAddr() + { + return null; + } + public static byte[] broadcastAddr() + { + return null; + } + public static byte[] newAddr() + { + return null; + } + public static boolean isEqualAddr(byte[] addr1, byte[] addr2) + { + return true; + } + public static void copyAddr(byte[] src, byte[] dst) + { + } + public static byte[] newHeader() + { + return new byte[2]; + } + public static void setHeaderSrcAddr(byte[] header, byte[] addr) + { + } + public static void setHeaderDstAddr(byte[] header, byte[] addr) + { + } + public static void copyHeaderSrcAddr(byte[] header, byte[] addr) + { + } + public static void copyHeaderDstAddr(byte[] header, byte[] addr) + { + } + public static byte[] getHeaderSrcAddr(byte[] header) + { + return null; + } + public static byte[] getHeaderDstAddr(byte[] header) + { + return null; + } + public static int getHeaderType(byte[] header) + { + return ((char)header[0] << 8) | (char)header[1]; + } + public static void setHeaderType(byte[] header, int type) + { + header[0] = (byte)(type >> 8); + header[1] = (byte)type; + } + public static boolean sendHeader(byte[] header, int dataSize) + { + while (xferOp != 0) + Thread.sleep(20); + packetLen = dataSize + 2; + packet = new byte[packetLen]; + packet[0] = header[0]; + packet[1] = header[1]; + writeOffset = 2; + xferOp = WRITE_OP; + return true; + } + public static boolean sendHeader(byte[] dst, int type, int dataSize) + { + byte[] header = new byte[2]; + header[0] = (byte)(type >> 8); + header[1] = (byte)type; + return sendHeader(header, dataSize); + } + public static void sendData(byte[] data, int offset, int size) + { + int len = offset + size; + for (int i = offset; i < len; i++) + packet[writeOffset++] = data[i]; + } + public static void sendData(byte[] data) + { + for (int i = 0; i < data.length; i++) + packet[writeOffset++] = data[i]; + } + public static int recvHeader(byte[] header) + { + if ((packet == null || packetLen == 0) || (xferOp != 0)) + { + readThread = Thread.currentThread(); + try + { + readThread.wait(); + } + catch (Exception e) + { + + } + readThread = null; + } + if (packet != null && packetLen > 2) + { + header[0] = packet[0]; + header[1] = packet[1]; + readOffset = 2; + xferOp = READ_OP; + return packetLen - 2; + } + return 0; + } + public static void recvData(byte[] data, int offset, int size) + { + int len = offset + size; + for (int i = offset; i < len; i++) + data[i] = packet[readOffset++]; + } + public static void recvData(byte[] data) + { + for (int i = 0; i < data.length; i++) + data[i] = packet[readOffset++]; + } + public static void xferComplete() + { + switch (xferOp) + { + case 1: // send + xferOp = IDLE_OP; + if (readThread != null) + readThread.notify(); + break; + case 2: // recv + xferOp = IDLE_OP; + packet = null; + packetLen = 0; + } + } +} \ No newline at end of file diff --git a/src/java/net/NetworkDevice.java b/src/java/net/NetworkDevice.java new file mode 100755 index 0000000..5cd2c39 --- /dev/null +++ b/src/java/net/NetworkDevice.java @@ -0,0 +1,99 @@ +package java.net; +/* + * This class is the base class for network devices. + */ +public class NetworkDevice +{ + public static boolean enable() + { + return false; + } + public static void disable() + { + } + public static int minDataSize() + { + return 0; + } + public static int maxDataSize() + { + return 0; + } + public static byte[] localAddr() + { + return null; + } + public static byte[] broadcastAddr() + { + return null; + } + public static byte[] newAddr() + { + return null; + } + public static boolean isEqualAddr(byte[] addr1, byte[] addr2) + { + return false; + } + public static void copyAddr(byte[] src, byte[] dst) + { + } + public static byte[] newHeader() + { + return null; + } + public static void setHeaderSrcAddr(byte[] header, byte[] addr) + { + } + public static void setHeaderDstAddr(byte[] header, byte[] addr) + { + } + public static void copyHeaderSrcAddr(byte[] header, byte[] addr) + { + } + public static void copyHeaderDstAddr(byte[] header, byte[] addr) + { + } + public static byte[] getHeaderSrcAddr(byte[] header) + { + return null; + } + public static byte[] getHeaderDstAddr(byte[] header) + { + return null; + } + public static int getHeaderType(byte[] header) + { + return 0; + } + public static void setHeaderType(byte[] header, int type) + { + } + public static boolean sendHeader(byte[] header, int dataSize) + { + return true; + } + public static boolean sendHeader(byte[] dst, int type, int dataSize) + { + return true; + } + public static void sendData(byte[] data, int offset, int size) + { + } + public static void sendData(byte[] data) + { + } + public static int recvHeader(byte[] header) + { + return 0; + } + public static void recvData(byte[] data, int offset, int size) + { + } + public static void recvData(byte[] data) + { + } + public static void xferComplete() + { + } +} \ No newline at end of file diff --git a/src/javabin.cfg b/src/javabin.cfg new file mode 100755 index 0000000..b8811e0 --- /dev/null +++ b/src/javabin.cfg @@ -0,0 +1,11 @@ +MEMORY { + RAM: start = $1000, size = $BF00, file = %O; +} +SEGMENTS { + CODE: load = RAM, type = rw; + DATA: load = RAM, type = rw; + BSS: load = RAM, type = rw; + INIT: load = RAM, type = rw; +} + + diff --git a/src/loader.cfg b/src/loader.cfg new file mode 100755 index 0000000..5d855e1 --- /dev/null +++ b/src/loader.cfg @@ -0,0 +1,10 @@ +MEMORY { + RAM: start = $2000, size = $1000, file = %O; +} +SEGMENTS { + CODE: load = RAM, type = rw; + DATA: load = RAM, type = rw; + BSS: load = RAM, type = rw; +} + + diff --git a/src/loader.s b/src/loader.s new file mode 100755 index 0000000..300898d --- /dev/null +++ b/src/loader.s @@ -0,0 +1,420 @@ +;* +;* JAVA LOADER FOR 6502 +;* +.MACRO PSTR MSG + JSR PUTS + .ASCIIZ MSG +.ENDMACRO +.MACRO PSTRLN MSG + JSR PUTSLN + .ASCIIZ MSG +.ENDMACRO +;* +;* HARDWARE ADDRESSES +;* +KEYBD = $C000 +CLRKBD = $C010 +SPKR = $C030 +ROMIN = $C081 +LCBNK2 = $C083 +LCBNK1 = $C08B +;* +;* HANDY ROM ROUTINES +;* +MONITOR = $FF65 +HOME = $FC58 +BELL = $FF3A +COUT = $FDED +CROUT = $FD8E +CROUT1 = $FD8B +PRBLNK = $F948 +PRBL2 = $F94A +PRBYTE = $FDDA +PRNTAX = $F941 +GETLN = $FD6A +;* +;* PRODOS +;* +PRODOS = $BF00 +DEVCNT = $BF31 ; GLOBAL PAGE DEVICE COUNT +DEVLST = $BF32 ; GLOBAL PAGE DEVICE LIST +MACHID = $BF98 ; GLOBAL PAGE MACHINE ID BYTE +RAMSLOT = $BF26 ; SLOT 3, DRIVE 2 IS /RAM'S DRIVER VECTOR +NODEV = $BF10 +;* +;* ZERO PAGE LOCATIONS +;* +SRCADDR = $DA +DSTADDR = $DC +TMP = $DE +TMPTR = $DE +;* +;* LOW MEMORY AREAS +;* +PBUFF = $0800 ; PARAMETER BUFFER +RLOADER = $0C00 ; RELOCATED LOADER + .CODE +;* +;* LOAD 64K VM02 OR 128K VM02E +;* +ENTRY: JMP LOADER ; SET UP ARG PASSING FROM LAUNCHER + .BYTE $EE,$EE + .BYTE 65 +ARGSTR: .BYTE 0 + .RES 64 +LOADER: LDA #26 ; DEACTIVATE 80 COL CARDS + JSR COUT ; THIS SHOULD BE IN CONSOLE DEACTIVATE + LDA #'1'|$80 + JSR COUT + LDA #8 ; PRINT BACKSPACE IN CASE 1 SHOWED UP + JSR COUT + LDA #' '|$80 + JSR COUT + LDA #21 + JSR COUT + BIT $C054 ; SET TEXT MODE + BIT $C051 + BIT $C058 + STA $C05F ; TURN OFF 80 COL ON IIE & IIC + JSR HOME + SEI ; DISABLE /RAM + LDA MACHID + AND #$30 + CMP #$30 + BNE RAMDONE + INC VM02FILE ; LOAD 128K VERSION OF VM02 + LDA RAMSLOT + CMP NODEV + BNE RAMCONT + LDA RAMSLOT+1 + CMP NODEV+1 + BEQ RAMDONE +RAMCONT: LDY DEVCNT +RAMLOOP: LDA DEVLST,Y + AND #$F3 + CMP #$B3 + BEQ GETLOOP + DEY + BPL RAMLOOP + BMI RAMDONE +GETLOOP: LDA DEVLST+1,Y + STA DEVLST,Y + BEQ RAMEXIT + INY + BNE GETLOOP +RAMEXIT: LDA NODEV + STA RAMSLOT + LDA NODEV+1 + STA RAMSLOT+1 + DEC DEVCNT +RAMDONE: CLI + LDA #RELOC + JSR MEMSRC + LDA #RLOADER + JSR MEMDST + LDA #<(BLOAD_END-MOUSE_INIT) + LDX #>(BLOAD_END-MOUSE_INIT) + JSR MEMCPY + LDA #VM02FILE + JSR MEMSRC + LDA #FILENAME + JSR MEMDST + LDA VM02FILE + CLC + ADC #$01 + LDX #$00 + JSR MEMCPY + LDY #$01 ; STUFF ARG STRING INTO PARAMETER BUFFER + LDA ARGSTR + STA PBUFF +: LDA ARGSTR,Y + ORA #$80 + STA PBUFF,Y + CPY ARGSTR + BCS :+ + INY + BNE :- +: JMP RLOADER +VM02FILE: .BYTE 4,"VM02E" ; JUST INC VM02FILE TO LOAD BIGMEM VERSION +;* +;* PRINT ASCIIZ STRING FOLLOWING JSR PUTS +;* +PUTSLN: LDX #$0D + BNE :+ +PUTS: LDX #$00 +: PLA + STA TMP + PLA + STA TMP+1 + LDY #$00 +PUTS_LP: INC TMP + BNE :+ + INC TMP+1 +: LDA (TMP),Y + BEQ PUTS_EXIT + JSR COUT + JMP PUTS_LP +PUTS_EXIT: TXA + BEQ :+ + JSR COUT +: LDA TMP+1 + PHA + LDA TMP + PHA + RTS +;* +;* PRINT STRING IN AX +;* +PRSTR: STA TMP + STX TMP+1 + LDY #$00 + LDA (TMP),Y + TAX + INY +PRSTR_LP: LDA (TMP),Y + JSR COUT + INY + DEX + BNE PRSTR_LP + RTS +PRSTRLN: JSR PRSTR + JSR CROUT + RTS +;* +;* WAIT FOR KEYPRESS +;* +KBWAIT: LDA KEYBD + BPL KBWAIT + LDA CLRKBD + RTS +;* +;* SET MEMORY SRC OPERAND +;* ENTRY: AX = ADDRESS +;* +MEMSRC: STA SRCADDR + STX SRCADDR+1 + RTS +;* +;* SET MEMORY DST OPERAND +;* ENTRY: AX = ADDRESS +;* +MEMDST: STA DSTADDR + STX DSTADDR+1 + RTS +;* +;* COPY MEMORY +;* +;* ENTRY: SRCADDR = SOURCE ADDRESS +;* DSTADDR = DESTINATION ADDRESS +;* AX = LENGTH IN BYTES +;* +MEMCPY: TAY + LDA SRCADDR+1 + CMP DSTADDR+1 + BEQ :+ + BCS FORCPY + BCC REVCPY +: LDA SRCADDR + CMP DSTADDR + BCS FORCPY +REVCPY: TXA ; REVERSE DIRECTION COPY + CLC + ADC SRCADDR+1 + STA SRCADDR+1 + TXA + CLC + ADC DSTADDR+1 + STA DSTADDR+1 + INX + CPY #$00 + BEQ :++ + DEY + BEQ :+ +REVCPY_LOOP: LDA (SRCADDR),Y + STA (DSTADDR),Y + DEY + BNE REVCPY_LOOP +: LDA (SRCADDR),Y ; DO ONE MORE COPY, Y = #$00 + STA (DSTADDR),Y ; (THIS MAKES FOR A SLIGHTLY FASTER INNER LOOP) +: DEY ; NOW Y = #$FF + DEX + BEQ :+ + DEC SRCADDR+1 + DEC DSTADDR+1 + BNE REVCPY_LOOP +: RTS +FORCPY: TYA ; FORWARD DIRECTION COPY + EOR #$FF + TAY + INY + BNE :+ + DEX +: LDA SRCADDR + STY SRCADDR + SEC + SBC SRCADDR + STA SRCADDR + LDA SRCADDR+1 + SBC #$00 + STA SRCADDR+1 + LDA DSTADDR + STY DSTADDR + SEC + SBC DSTADDR + STA DSTADDR + LDA DSTADDR+1 + SBC #$00 + STA DSTADDR+1 + INX +FORCPY_LOOP: LDA (SRCADDR),Y + STA (DSTADDR),Y + INY + BNE FORCPY_LOOP + DEX + BEQ :+ + INC SRCADDR+1 + INC DSTADDR+1 + BNE FORCPY_LOOP +: RTS +;* +;* RELOC FROM HERE +;* +RELOC: + .ORG RLOADER +;* +;* MOUSE INIT ROUTINES. MUST HAPPEN HERE BECAUSE II/II+ WILL CLEAR $2000-$4000 FOR +;* VBL CALCULATION +;* +MOUSE_INIT: SEI + LDX #$20 ; LOOK FOR MOUSE + LDA #$01 + JSR SCAN_SLOTS + BCS BLOAD + STX INITMOUSE+2 + STX SETMOUSE1+2 + STX SETMOUSE2+2 + LDY #$19 + LDA (TMPTR),Y + STA INITMOUSE+1 + LDY #$12 + LDA (TMPTR),Y + STA SETMOUSE1+1 + STA SETMOUSE2+1 + LDX TMPTR+1 + TXA + ASL + ASL + ASL + ASL + STA TMPTR + TAY +INITMOUSE: JSR $C400 + LDX TMPTR+1 + LDY TMPTR + LDA #$08 ; TURN MOUSE OFF, VBL ACTIVE +SETMOUSE1: JSR $C400 + LDA #$00 ; TURN MOUSE OFF, VBL INACTIVE +SETMOUSE2: JSR $C400 +;* +;* READ BINARY FILE +;* ENTRY: AX = POINTER TO FILE NAME/ADDRESS +;* +BLOAD: LDA #FILENAME + STA OPENPARMS+2 + LDA #$00 ; SET DATA ADDRESS + STA READPARMS+2 + LDA #$10 + STA READPARMS+3 + JSR PRODOS + .BYTE $C8 ; OPEN FILE + .ADDR OPENPARMS + BCS :+ + LDA OPENPARMS+5 + STA GETEOFPARMS+1 + STA READPARMS+1 + STA CLOSEPARMS+1 + JSR PRODOS + .BYTE $D1 ; GET EOF (FILE LEN) + .ADDR GETEOFPARMS + BCS :+ + LDA GETEOFPARMS+2 + STA READPARMS+4 + LDA GETEOFPARMS+3 + STA READPARMS+5 + JSR PRODOS + .BYTE $CA ; READ FILE + .ADDR READPARMS + BCS :+ + JSR PRODOS + .BYTE $CC ; CLOSE FILE + .ADDR CLOSEPARMS +: LDY #$00 ; STUFF ARG STRING INTO INPUT BUFFER +: LDA PBUFF,Y + STA $01FF,Y + CPY PBUFF + BEQ :+ + INY + BNE :- +: LDX #$FE ; LEAVE BUFFER SIZE AT TOP OF STACK + TXS + JMP $1000 ; JUMP TO VM02 +OPENPARMS: .BYTE $03 + .ADDR $0000 ; PATH ADDR + .ADDR $B000 ; BUFF ADDR + .BYTE $00 ; REF NUM +GETEOFPARMS: .BYTE $02 + .BYTE $00 ; REF NUM + .BYTE $00,$00,$00 ; EOF L/M/H +READPARMS: .BYTE $04 + .BYTE $00 ; REF NUM + .ADDR $0000 ; DATA ADDR + .ADDR $0000 ; DATA LEN + .ADDR $0000 ; ACTUAL LEN +CLOSEPARMS: .BYTE $01 + .BYTE $00 ; REF NUM +FILENAME: .RES 65 +; +; SCAN SLOTS FOR MATCHING CARD ID +; ENTRY: A = START SLOT SCAN +; X = CARD ID +; EXIT: A = SLOT # :: C = 0 +; X = SLOT PAGE +; +SCAN_SLOTS: ORA #$C0 + STA TMPTR+1 + LDA #$00 + STA TMPTR +CHKSIG: LDY #$05 + LDA (TMPTR),Y + CMP #$38 ; LOOK FOR PASCAL COMPAT SIG + BNE :+ + LDY #$07 + LDA (TMPTR),Y + CMP #$18 + BNE :+ + LDY #$0B + LDA (TMPTR),Y + CMP #$01 + BNE :+ + LDY #$0C + TXA ; LOOK FOR MATCHING ID + CMP (TMPTR),Y + BNE :+ + LDA TMPTR+1 + TAX + AND #$07 + CLC + RTS +: INC TMPTR+1 + LDA TMPTR+1 + CMP #$C8 + BCC CHKSIG + SEC + RTS +BLOAD_END = * \ No newline at end of file diff --git a/src/makefile b/src/makefile new file mode 100755 index 0000000..417e7d5 --- /dev/null +++ b/src/makefile @@ -0,0 +1,731 @@ +.SUFFIXES = +JAVAC = javac +AFLAGS = -o $@ +LFLAGS = -C javabin.cfg +JFLAGS = -g:none -bootclasspath java -extdirs apple2 +VM02FILE = vm02.bin +VM02EFILE = vm02e.bin +OBJS = vm02.o memmgr.o codemgr.o strpool.o classclass.o sysclass.o string.o classload.o utils.o frame.o thread.o io.o ops.o except.o dvm.o +OBJSE = vm02_e.o memmgr_e.o codemgr_e.o strpool_e.o classclass_e.o sysclass.o string.o classload.o utils.o frame.o thread_e.o io.o ops_e.o except.o dvm_e.o +LOADER = java.system.sys +A2CLASSES = apple2/vm02.class apple2/conio.class apple2/AppleStuff.class apple2/OutputConsole.class apple2/PrintConsole.class apple2/InputConsole.class apple2/ProDOS.class apple2/SystemException.class \ + apple2/OutputSSC.class apple2/InputSSC.class apple2/Mouse.class apple2/Ethernet.class +DUMMYCLASSES = java/lang/Object.class java/lang/Array.class java/lang/String.class +LANGCLASSES = java/lang/Runnable.class java/lang/ThreadGroup.class java/lang/Thread.class java/lang/System.class java/lang/Throwable.class java/lang/Error.class java/lang/ThreadDeath.class java/lang/VirtualMachineError.class \ + java/lang/RuntimeException.class java/lang/InternalError.class java/lang/OutOfMemoryError.class java/lang/StackOverflowError.class java/lang/LinkeageError.class java/lang/NoClassDefFoundError.class \ + java/lang/ClassFormatError.class java/lang/IncompatibleClassChangeError.class java/lang/NoSuchFieldError.class java/lang/NoSuchMethodError.class \ + java/lang/Exception.class java/lang/ClassCastException.class java/lang/IllegalArgumentException.class java/lang/IllegalMonitorStateException.class java/lang/IllegalThreadStateException.class java/lang/ClassNotFoundException.class \ + java/lang/InterruptedException.class java/lang/NullPointerException.class java/lang/IndexOutOfBoundsException.class java/lang/ArrayIndexOutOfBoundsException.class java/lang/StringIndexOutOfBoundsException.class \ + java/lang/NegativeArraySizeException.class java/lang/ArrayStoreException.class java/lang/ArithmeticException.class \ + java/lang/Number.class java/lang/Byte.class java/lang/Short.class java/lang/Long.class java/lang/Boolean.class java/lang/Character.class java/lang/Integer.class java/lang/Float.class java/lang/StringBuilder.class +IOCLASSES = java/io/OutputStream.class java/io/FilterOutputStream.class java/io/PrintStream.class java/io/InputStream.class java/io/FileInputStream.class java/io/FileOutputStream.class \ + java/io/IOException.class java/io/FileNotFoundException.class java/io/EOFException.class +NETCLASSES = java/net/NetworkDevice.class java/net/Loopback.class +CLASSES = $(DUMMYCLASSES) $(A2CLASSES) $(LANGCLASSES) $(IOCLASSES) $(NETCLASSES) +SAMPLES = samples/Hello.class samples/HelloWorld.class samples/SimplePong.class samples/Moire.class samples/RodsColors.class samples/HiResDemo.class samples/List.class samples/Terminal.class samples/Volumes.class \ + samples/Catalog.class samples/TestArp.class samples/StressMem.class samples/TestChain.class samples/NextChain.class samples/TestSelect.class +FAVAC = org/vm02/favac/Scanner.class org/vm02/favac/favac.class org/vm02/favac/fasm.class +CUI = org/vm02/cui/cuiDriver.class org/vm02/cui/cui.class org/vm02/cui/cuiControl.class org/vm02/cui/cuiWindow.class org/vm02/cui/cuiButton.class org/vm02/cui/cuiPopUp.class org/vm02/cui/cuiPopUpMenu.class \ + org/vm02/cui/cuiMenuBar.class org/vm02/cui/cuiDropDownMenu.class org/vm02/cui/cuiTopLevelWindow.class org/vm02/cui/cuiConsole.class \ + org/vm02/cui/cuiScrollBar.class org/vm02/cui/cuiListBox.class org/vm02/cui/cuiTextEntry.class org/vm02/cui/cuiMessageBox.class org/vm02/cui/cuiApp.class samples/TestCUI.class \ + org/vm02/cui/Launcher.class +VERSION = rel1 +RELEASEDIR = ../$(VERSION) +SAMPLESDIR = $(RELEASEDIR)/SAMPLES +ORGDIR = $(RELEASEDIR)/ORG +ORGVM02DIR = $(ORGDIR)/VM02 +# +# Image filetypes for Virtual ][ +# +JVMTYPE = .\$$ED +BINTYPE = .BIN +SYSTYPE = .SYS +TXTTYPE = .TXT +# +# Image filetypes for CiderPress +# +#JVMTYPE = \#ed0000 +#BINTYPE = \#060000 +#SYSTYPE = \#ff0000 +#TXTTYPE = \#040000 + +all: $(VM02FILE) $(VM02EFILE) $(LOADER) $(CLASSES) $(SAMPLES) $(FAVAC) $(CUI) + +vm02: $(VM02FILE) $(VM02EFILE) $(LOADER) + +samples: $(SAMPLES) + +classes: $(CLASSES) + +clean: + rm -f $(VM02FILE) $(OBJS) $(LOADER) loader.o $(CLASSES) apple2/vm02.o $(SAMPLES) $(FAVAC) $(CUI) + rm -rf $(RELEASEDIR) + rm -rf $(SAMPLESDIR) + mkdir $(RELEASEDIR) + mkdir $(RELEASEDIR)/APPLE2 + mkdir $(RELEASEDIR)/JAVA + mkdir $(RELEASEDIR)/JAVA/LANG + mkdir $(RELEASEDIR)/JAVA/IO + mkdir $(RELEASEDIR)/JAVA/NET + mkdir $(SAMPLESDIR) + mkdir $(SAMPLESDIR)/SOURCE + mkdir $(ORGDIR) + mkdir $(ORGVM02DIR) + mkdir $(ORGVM02DIR)/FAVAC + mkdir $(ORGVM02DIR)/CUI + +image: + cp java.system.sys $(RELEASEDIR)/JAVA.SYSTEM$(SYSTYPE) + cp vm02.bin $(RELEASEDIR)/VM02$(BINTYPE) + cp vm02e.bin $(RELEASEDIR)/VM02E$(BINTYPE) + cp samples/List.class $(RELEASEDIR)/STARTUP$(JVMTYPE) + cp ../README.TXT $(RELEASEDIR)/README.TXT$(TXTTYPE) + cp apple2/conio.class $(RELEASEDIR)/APPLE2/CONIO$(JVMTYPE) + cp apple2/ProDOS.class $(RELEASEDIR)/APPLE2/PRODOS$(JVMTYPE) + cp apple2/SystemException.class $(RELEASEDIR)/APPLE2/SYSTEMEXCEPTION$(JVMTYPE) + cp apple2/OutputConsole.class $(RELEASEDIR)/APPLE2/OUTPUTCONSOLE$(JVMTYPE) + cp apple2/PrintConsole.class $(RELEASEDIR)/APPLE2/PRINTCONSOLE$(JVMTYPE) + cp apple2/InputConsole.class $(RELEASEDIR)/APPLE2/INPUTCONSOLE$(JVMTYPE) + cp apple2/OutputSSC.class $(RELEASEDIR)/APPLE2/OUTPUTSSC$(JVMTYPE) + cp apple2/InputSSC.class $(RELEASEDIR)/APPLE2/INPUTSSC$(JVMTYPE) + cp apple2/Mouse.class $(RELEASEDIR)/APPLE2/MOUSE$(JVMTYPE) + cp apple2/Ethernet.class $(RELEASEDIR)/APPLE2/ETHERNET$(JVMTYPE) + cp java/lang/Runnable.class $(RELEASEDIR)/JAVA/LANG/RUNNABLE$(JVMTYPE) + cp java/lang/ThreadGroup.class $(RELEASEDIR)/JAVA/LANG/THREADGROUP$(JVMTYPE) + cp java/lang/Thread.class $(RELEASEDIR)/JAVA/LANG/THREAD$(JVMTYPE) + cp java/lang/System.class $(RELEASEDIR)/JAVA/LANG/SYSTEM$(JVMTYPE) + cp java/lang/Throwable.class $(RELEASEDIR)/JAVA/LANG/THROWABLE$(JVMTYPE) + cp java/lang/Error.class $(RELEASEDIR)/JAVA/LANG/ERROR$(JVMTYPE) + cp java/lang/ThreadDeath.class $(RELEASEDIR)/JAVA/LANG/THREADDEATH$(JVMTYPE) + cp java/lang/VirtualMachineError.class $(RELEASEDIR)/JAVA/LANG/VIRTUALMACHINEERROR$(JVMTYPE) + cp java/lang/OutOfMemoryError.class $(RELEASEDIR)/JAVA/LANG/OUTOFMEMORYERROR$(JVMTYPE) + cp java/lang/StackOverflowError.class $(RELEASEDIR)/JAVA/LANG/STACKOVERFLOWERROR$(JVMTYPE) + cp java/lang/LinkeageError.class $(RELEASEDIR)/JAVA/LANG/LINKEAGEERROR$(JVMTYPE) + cp java/lang/NoClassDefFoundError.class $(RELEASEDIR)/JAVA/LANG/NOCLASSDEFFOUNDERROR$(JVMTYPE) + cp java/lang/ClassFormatError.class $(RELEASEDIR)/JAVA/LANG/CLASSFORMATERROR$(JVMTYPE) + cp java/lang/IncompatibleClassChangeError.class $(RELEASEDIR)/JAVA/LANG/INCOMPATIBLECLASSCHANGEERROR$(JVMTYPE) + cp java/lang/NoSuchMethodError.class $(RELEASEDIR)/JAVA/LANG/NOSUCHMETHODERROR$(JVMTYPE) + cp java/lang/NoSuchFieldError.class $(RELEASEDIR)/JAVA/LANG/NOSUCHFIELDERROR$(JVMTYPE) + cp java/lang/Exception.class $(RELEASEDIR)/JAVA/LANG/EXCEPTION$(JVMTYPE) + cp java/lang/RuntimeException.class $(RELEASEDIR)/JAVA/LANG/RUNTIMEEXCEPTION$(JVMTYPE) + cp java/lang/IllegalArgumentException.class $(RELEASEDIR)/JAVA/LANG/ILLEGALARGUMENTEXCEPTION$(JVMTYPE) + cp java/lang/IllegalMonitorStateException.class $(RELEASEDIR)/JAVA/LANG/ILLEGALMONITORSTATEEXCEPTION$(JVMTYPE) + cp java/lang/IllegalThreadStateException.class $(RELEASEDIR)/JAVA/LANG/ILLEGALTHREADSTATEEXCEPTION$(JVMTYPE) + cp java/lang/ClassCastException.class $(RELEASEDIR)/JAVA/LANG/CLASSCASTEXCEPTION$(JVMTYPE) + cp java/lang/InterruptedException.class $(RELEASEDIR)/JAVA/LANG/INTERRUPTEDEXCEPTION$(JVMTYPE) + cp java/lang/ClassNotFoundException.class $(RELEASEDIR)/JAVA/LANG/CLASSNOTFOUNDEXCEPTION$(JVMTYPE) + cp java/lang/NullPointerException.class $(RELEASEDIR)/JAVA/LANG/NULLPOINTEREXCEPTION$(JVMTYPE) + cp java/lang/IndexOutOfBoundsException.class $(RELEASEDIR)/JAVA/LANG/INDEXOUTOFBOUNDSEXCEPTION$(JVMTYPE) + cp java/lang/ArrayIndexOutOfBoundsException.class $(RELEASEDIR)/JAVA/LANG/ARRAYINDEXOUTOFBOUNDSEXCEPTION$(JVMTYPE) + cp java/lang/StringIndexOutOfBoundsException.class $(RELEASEDIR)/JAVA/LANG/STRINGINDEXOUTOFBOUNDSEXCEPTION$(JVMTYPE) + cp java/lang/NegativeArraySizeException.class $(RELEASEDIR)/JAVA/LANG/NEGATIVEARRAYSIZEEXCEPTION$(JVMTYPE) + cp java/lang/ArrayStoreException.class $(RELEASEDIR)/JAVA/LANG/ARRAYSTOREEXCEPTION$(JVMTYPE) + cp java/lang/ArithmeticException.class $(RELEASEDIR)/JAVA/LANG/ARITHMETICEXCEPTION$(JVMTYPE) + cp java/lang/Byte.class $(RELEASEDIR)/JAVA/LANG/BYTE$(JVMTYPE) + cp java/lang/Short.class $(RELEASEDIR)/JAVA/LANG/SHORT$(JVMTYPE) + cp java/lang/Long.class $(RELEASEDIR)/JAVA/LANG/LONG$(JVMTYPE) + cp java/lang/Boolean.class $(RELEASEDIR)/JAVA/LANG/BOOLEAN$(JVMTYPE) + cp java/lang/Character.class $(RELEASEDIR)/JAVA/LANG/CHARACTER$(JVMTYPE) + cp java/lang/Number.class $(RELEASEDIR)/JAVA/LANG/NUMBER$(JVMTYPE) + cp java/lang/Integer.class $(RELEASEDIR)/JAVA/LANG/INTEGER$(JVMTYPE) + cp java/lang/Float.class $(RELEASEDIR)/JAVA/LANG/FLOAT$(JVMTYPE) + cp java/lang/StringBuilder.class $(RELEASEDIR)/JAVA/LANG/STRINGBUILDER$(JVMTYPE) + cp java/io/OutputStream.class $(RELEASEDIR)/JAVA/IO/OUTPUTSTREAM$(JVMTYPE) + cp java/io/FileOutputStream.class $(RELEASEDIR)/JAVA/IO/FILEOUTPUTSTREAM$(JVMTYPE) + cp java/io/FilterOutputStream.class $(RELEASEDIR)/JAVA/IO/FILTEROUTPUTSTREAM$(JVMTYPE) + cp java/io/PrintStream.class $(RELEASEDIR)/JAVA/IO/PRINTSTREAM$(JVMTYPE) + cp java/io/InputStream.class $(RELEASEDIR)/JAVA/IO/INPUTSTREAM$(JVMTYPE) + cp java/io/FileInputStream.class $(RELEASEDIR)/JAVA/IO/FILEINPUTSTREAM$(JVMTYPE) + cp java/io/IOException.class $(RELEASEDIR)/JAVA/IO/IOEXCEPTION$(JVMTYPE) + cp java/io/FileNotFoundException.class $(RELEASEDIR)/JAVA/IO/FILENOTFOUNDEXCEPTION$(JVMTYPE) + cp java/io/EOFException.class $(RELEASEDIR)/JAVA/IO/EOFEXCEPTION$(JVMTYPE) + cp java/net/NetworkDevice.class $(RELEASEDIR)/JAVA/NET/NETWORKDEVICE$(JVMTYPE) + cp java/net/Loopback.class $(RELEASEDIR)/JAVA/NET/LOOPBACK$(JVMTYPE) + cp samples/Hello.class $(SAMPLESDIR)/HELLO$(JVMTYPE) + cp samples/HelloWorld.class $(SAMPLESDIR)/HELLOWORLD$(JVMTYPE) + cp samples/List.class $(SAMPLESDIR)/LIST$(JVMTYPE) + cp samples/SimplePong.class $(SAMPLESDIR)/SIMPLEPONG$(JVMTYPE) + cp samples/Moire.class $(SAMPLESDIR)/MOIRE$(JVMTYPE) + cp samples/HiResDemo.class $(SAMPLESDIR)/HIRESDEMO$(JVMTYPE) + cp samples/RodsColors.class $(SAMPLESDIR)/RODSCOLORS$(JVMTYPE) + cp samples/Terminal.class $(SAMPLESDIR)/TERMINAL$(JVMTYPE) + cp samples/Volumes.class $(SAMPLESDIR)/VOLUMES$(JVMTYPE) + cp samples/Catalog.class $(SAMPLESDIR)/CATALOG$(JVMTYPE) + cp samples/TestArp.class $(SAMPLESDIR)/TESTARP$(JVMTYPE) + cp samples/StressMem.class $(SAMPLESDIR)/STRESSMEM$(JVMTYPE) + cp samples/TestChain.class $(SAMPLESDIR)/TESTCHAIN$(JVMTYPE) + cp samples/NextChain.class $(SAMPLESDIR)/NEXTCHAIN$(JVMTYPE) + cp samples/TestSelect.class $(SAMPLESDIR)/TESTSELECT$(JVMTYPE) + cp samples/TestCUI.class $(SAMPLESDIR)/TESTCUI$(JVMTYPE) + cp samples/HelloWorld.java $(SAMPLESDIR)/SOURCE/HelloWorld.java$(TXTTYPE) + cp samples/List.java $(SAMPLESDIR)/SOURCE/List.java$(TXTTYPE) + cp samples/SimplePong.java $(SAMPLESDIR)/SOURCE/SimplePong.java$(TXTTYPE) + cp samples/Moire.java $(SAMPLESDIR)/SOURCE/Moire.java$(TXTTYPE) + cp samples/Terminal.java $(SAMPLESDIR)/SOURCE/Terminal.java$(TXTTYPE) + cp samples/HiResDemo.java $(SAMPLESDIR)/SOURCE/HiResDemo.java$(TXTTYPE) + cp samples/RodsColors.java $(SAMPLESDIR)/SOURCE/RodsColors.java$(TXTTYPE) + cp samples/Volumes.java $(SAMPLESDIR)/SOURCE/Volumes.java$(TXTTYPE) + cp samples/Catalog.java $(SAMPLESDIR)/SOURCE/Catalog.java$(TXTTYPE) + cp samples/TestArp.java $(SAMPLESDIR)/SOURCE/TestArp.java$(TXTTYPE) + cp samples/StressMem.java $(SAMPLESDIR)/SOURCE/StressMem.java$(TXTTYPE) + cp samples/TestSelect.java $(SAMPLESDIR)/SOURCE/TestSelect.java$(TXTTYPE) + cp samples/TestCUI.java $(SAMPLESDIR)/SOURCE/TestCUI.java$(TXTTYPE) + cp samples/TestChain.java $(SAMPLESDIR)/SOURCE/TestChain.java$(TXTTYPE) + cp samples/NextChain.java $(SAMPLESDIR)/SOURCE/NextChain.java$(TXTTYPE) + cp org/vm02/favac/Scanner.class $(ORGVM02DIR)/FAVAC/SCANNER$(JVMTYPE) + cp org/vm02/favac/favac.class $(ORGVM02DIR)/FAVAC/FAVAC$(JVMTYPE) + cp org/vm02/favac/fasm.class $(ORGVM02DIR)/FAVAC/FASM$(JVMTYPE) + cp org/vm02/cui/cui.class $(ORGVM02DIR)/CUI/CUI$(JVMTYPE) + cp org/vm02/cui/cuiControl.class $(ORGVM02DIR)/CUI/CUICONTROL$(JVMTYPE) + cp org/vm02/cui/cuiWindow.class $(ORGVM02DIR)/CUI/CUIWINDOW$(JVMTYPE) + cp org/vm02/cui/cuiTopLevelWindow.class $(ORGVM02DIR)/CUI/CUITOPLEVELWINDOW$(JVMTYPE) + cp org/vm02/cui/cuiConsole.class $(ORGVM02DIR)/CUI/CUICONSOLE$(JVMTYPE) + cp org/vm02/cui/cuiButton.class $(ORGVM02DIR)/CUI/CUIBUTTON$(JVMTYPE) + cp org/vm02/cui/cuiPopUp.class $(ORGVM02DIR)/CUI/CUIPOPUP$(JVMTYPE) + cp org/vm02/cui/cuiPopUpMenu.class $(ORGVM02DIR)/CUI/CUIPOPUPMENU$(JVMTYPE) + cp org/vm02/cui/cuiMenuBar.class $(ORGVM02DIR)/CUI/CUIMENUBAR$(JVMTYPE) + cp org/vm02/cui/cuiDropDownMenu.class $(ORGVM02DIR)/CUI/CUIDROPDOWNMENU$(JVMTYPE) + cp org/vm02/cui/cuiMessageBox.class $(ORGVM02DIR)/CUI/CUIMESSAGEBOX$(JVMTYPE) + cp org/vm02/cui/cuiScrollBar.class $(ORGVM02DIR)/CUI/CUISCROLLBAR$(JVMTYPE) + cp org/vm02/cui/cuiTextEntry.class $(ORGVM02DIR)/CUI/CUITEXTENTRY$(JVMTYPE) + cp org/vm02/cui/cuiApp.class $(ORGVM02DIR)/CUI/CUIAPP$(JVMTYPE) + cp org/vm02/cui/Launcher.class $(RELEASEDIR)/LAUNCHER$(JVMTYPE) + +$(LOADER): loader.o + ld65 -C loader.cfg loader.o -o $(LOADER) + cp $(LOADER) $(RELEASEDIR)/JAVA.SYSTEM$(SYSTYPE) + +$(VM02FILE): $(OBJS) + ld65 $(LFLAGS) -m vm02.map $(OBJS) -o $(VM02FILE) + cp $(VM02FILE) $(RELEASEDIR)/VM02$(BINTYPE) + +$(VM02EFILE): $(OBJSE) + ld65 $(LFLAGS) -m vm02e.map $(OBJSE) -o $(VM02EFILE) + cp $(VM02EFILE) $(RELEASEDIR)/VM02E$(BINTYPE) + +# +# VM02 source +# + +loader.o: loader.s + ca65 $(AFLAGS) $< + +vm02.o: vm02.s global.inc + ca65 $(AFLAGS) $< + +vm02_e.o: vm02.s global.inc + ca65 $(AFLAGS) -D BIGMEM=1 $< + +memmgr.o: memmgr.s global.inc + ca65 $(AFLAGS) $< + +memmgr_e.o: memmgr.s global.inc + ca65 $(AFLAGS) -D BIGMEM=1 $< + +codemgr.o: codemgr.s global.inc + ca65 $(AFLAGS) $< + +codemgr_e.o: codemgr.s global.inc + ca65 $(AFLAGS) -D BIGMEM=1 $< + +strpool.o: strpool.s global.inc + ca65 $(AFLAGS) $< + +strpool_e.o: strpool.s global.inc + ca65 $(AFLAGS) -D BIGMEM=1 $< + +thread.o: thread.s global.inc + ca65 $(AFLAGS) $< + +thread_e.o: thread.s global.inc + ca65 $(AFLAGS) -D BIGMEM=1 $< + +frame.o: frame.s global.inc frame.inc + ca65 $(AFLAGS) $< + +classclass.o: classclass.s global.inc + ca65 $(AFLAGS) $< + +classclass_e.o: classclass.s global.inc + ca65 $(AFLAGS) -D BIGMEM=1 $< + +sysclass.o: sysclass.s global.inc object.clasm array.clasm + ca65 $(AFLAGS) $< + +string.o: string.s global.inc string.clasm + ca65 $(AFLAGS) $< + +classload.o: classload.s global.inc + ca65 $(AFLAGS) $< + +ops.o: ops.s global.inc + ca65 $(AFLAGS) $< + +ops_e.o: ops.s global.inc + ca65 $(AFLAGS) -D BIGMEM=1 $< + +io.o: io.s consoledrvr.s sscdrvr.s mousedrvr.s global.inc + ca65 $(AFLAGS) $< + +except.o: except.s global.inc class.inc frame.inc + ca65 $(AFLAGS) $< + +utils.o: utils.s global.inc + ca65 $(AFLAGS) $< + +dvm.o: dvm.s global.inc + ca65 $(AFLAGS) $< + +dvm_e.o: dvm.s global.inc + ca65 $(AFLAGS) -D BIGMEM=1 $< + +# +# Dummy Java base classes +# + +java/lang/Object.class: ObjectObj.s + ca65 ObjectObj.s + ld65 --target apple2 -o java/lang/Object.class ObjectObj.o + +java/lang/Array.class: ArrayObj.s + ca65 ArrayObj.s + ld65 --target apple2 -o java/lang/Array.class ArrayObj.o + +java/lang/String.class: StringObj.s + ca65 StringObj.s + ld65 --target apple2 -o java/lang/String.class StringObj.o + +# +# Apple II classes +# + +apple2/vm02.class: apple2/vm02.java apple2/vm02.clasm + $(JAVAC) $(JFLAGS) $< + ca65 apple2/vm02.clasm + ld65 -C clasm.cfg apple2/vm02.o -o $(RELEASEDIR)/APPLE2/VM02$(JVMTYPE) + +apple2/conio.class: apple2/conio.java apple2/vm02.java + $(JAVAC) $(JFLAGS) $< + cp apple2/conio.class $(RELEASEDIR)/APPLE2/CONIO$(JVMTYPE) + +apple2/AppleStuff.class: apple2/AppleStuff.java apple2/vm02.java + $(JAVAC) $(JFLAGS) $< + ca65 apple2/AppleStuff.clasm + ld65 -C clasm.cfg apple2/AppleStuff.o -o $(RELEASEDIR)/APPLE2/APPLESTUFF$(JVMTYPE) + +apple2/ProDOS.class: apple2/ProDOS.java apple2/vm02.java + $(JAVAC) $(JFLAGS) $< + cp apple2/ProDOS.class $(RELEASEDIR)/APPLE2/PRODOS$(JVMTYPE) + +apple2/SystemException.class: apple2/SystemException.java + $(JAVAC) $(JFLAGS) $< + cp apple2/SystemException.class $(RELEASEDIR)/APPLE2/SYSTEMEXCEPTION$(JVMTYPE) + +apple2/OutputConsole.class: apple2/OutputConsole.java java/io/OutputStream.java + $(JAVAC) $(JFLAGS) $< + cp apple2/OutputConsole.class $(RELEASEDIR)/APPLE2/OUTPUTCONSOLE$(JVMTYPE) + +apple2/PrintConsole.class: apple2/PrintConsole.java java/io/PrintStream.java + $(JAVAC) $(JFLAGS) $< + cp apple2/PrintConsole.class $(RELEASEDIR)/APPLE2/PRINTCONSOLE$(JVMTYPE) + +apple2/InputConsole.class: apple2/InputConsole.java java/io/InputStream.java + $(JAVAC) $(JFLAGS) $< + cp apple2/InputConsole.class $(RELEASEDIR)/APPLE2/INPUTCONSOLE$(JVMTYPE) + +apple2/OutputSSC.class: apple2/OutputSSC.java java/io/OutputStream.java + $(JAVAC) $(JFLAGS) $< + cp apple2/OutputSSC.class $(RELEASEDIR)/APPLE2/OUTPUTSSC$(JVMTYPE) + +apple2/InputSSC.class: apple2/InputSSC.java java/io/InputStream.java + $(JAVAC) $(JFLAGS) $< + cp apple2/InputSSC.class $(RELEASEDIR)/APPLE2/INPUTSSC$(JVMTYPE) + +apple2/Mouse.class: apple2/Mouse.java + $(JAVAC) $(JFLAGS) $< + cp apple2/Mouse.class $(RELEASEDIR)/APPLE2/MOUSE$(JVMTYPE) + +apple2/Ethernet.class: apple2/Ethernet.java + $(JAVAC) $(JFLAGS) $< + cp apple2/Ethernet.class $(RELEASEDIR)/APPLE2/ETHERNET$(JVMTYPE) + +# +# Standard Java lang classes +# + +java/lang/Runnable.class: java/lang/Runnable.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/Runnable.class $(RELEASEDIR)/JAVA/LANG/RUNNABLE$(JVMTYPE) + +java/lang/ThreadGroup.class: java/lang/ThreadGroup.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/ThreadGroup.class $(RELEASEDIR)/JAVA/LANG/THREADGROUP$(JVMTYPE) + +java/lang/Thread.class: java/lang/Thread.java apple2/vm02.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/Thread.class $(RELEASEDIR)/JAVA/LANG/THREAD$(JVMTYPE) + +java/lang/System.class: java/lang/System.java apple2/vm02.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/System.class $(RELEASEDIR)/JAVA/LANG/SYSTEM$(JVMTYPE) + +java/lang/Throwable.class: java/lang/Throwable.java apple2/vm02.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/Throwable.class $(RELEASEDIR)/JAVA/LANG/THROWABLE$(JVMTYPE) + +java/lang/Error.class: java/lang/Error.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/Error.class $(RELEASEDIR)/JAVA/LANG/ERROR$(JVMTYPE) + +java/lang/InternalError.class: java/lang/InternalError.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/InternalError.class $(RELEASEDIR)/JAVA/LANG/INTERNALERROR$(JVMTYPE) + +java/lang/ThreadDeath.class: java/lang/ThreadDeath.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/ThreadDeath.class $(RELEASEDIR)/JAVA/LANG/THREADDEATH$(JVMTYPE) + +java/lang/VirtualMachineError.class: java/lang/VirtualMachineError.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/VirtualMachineError.class $(RELEASEDIR)/JAVA/LANG/VIRTUALMACHINEERROR$(JVMTYPE) + +java/lang/OutOfMemoryError.class: java/lang/OutOfMemoryError.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/OutOfMemoryError.class $(RELEASEDIR)/JAVA/LANG/OUTOFMEMORYERROR$(JVMTYPE) + +java/lang/StackOverflowError.class: java/lang/StackOverflowError.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/StackOverflowError.class $(RELEASEDIR)/JAVA/LANG/STACKOVERFLOWERROR$(JVMTYPE) + +java/lang/LinkeageError.class: java/lang/LinkeageError.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/LinkeageError.class $(RELEASEDIR)/JAVA/LANG/LINKEAGEERROR$(JVMTYPE) + +java/lang/NoClassDefFoundError.class: java/lang/NoClassDefFoundError.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/NoClassDefFoundError.class $(RELEASEDIR)/JAVA/LANG/NOCLASSDEFFOUNDERROR$(JVMTYPE) + +java/lang/ClassFormatError.class: java/lang/ClassFormatError.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/ClassFormatError.class $(RELEASEDIR)/JAVA/LANG/CLASSFORMATERROR$(JVMTYPE) + +java/lang/IncompatibleClassChangeError.class: java/lang/IncompatibleClassChangeError.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/IncompatibleClassChangeError.class $(RELEASEDIR)/JAVA/LANG/INCOMPATIBLECLASSCHANGEERROR$(JVMTYPE) + +java/lang/NoSuchFieldError.class: java/lang/NoSuchFieldError.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/NoSuchFieldError.class $(RELEASEDIR)/JAVA/LANG/NOSUCHFIELDERROR$(JVMTYPE) + +java/lang/NoSuchMethodError.class: java/lang/NoSuchMethodError.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/NoSuchMethodError.class $(RELEASEDIR)/JAVA/LANG/NOSUCHMETHODERROR$(JVMTYPE) + +java/lang/Exception.class: java/lang/Exception.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/Exception.class $(RELEASEDIR)/JAVA/LANG/EXCEPTION$(JVMTYPE) + +java/lang/RuntimeException.class: java/lang/RuntimeException.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/RuntimeException.class $(RELEASEDIR)/JAVA/LANG/RUNTIMEEXCEPTION$(JVMTYPE) + +java/lang/IllegalArgumentException.class: java/lang/IllegalArgumentException.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/IllegalArgumentException.class $(RELEASEDIR)/JAVA/LANG/ILLEGALARGUMENTEXCEPTION$(JVMTYPE) + +java/lang/IllegalMonitorStateException.class: java/lang/IllegalMonitorStateException.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/IllegalMonitorStateException.class $(RELEASEDIR)/JAVA/LANG/ILLEGALMONITORSTATEEXCEPTION$(JVMTYPE) + +java/lang/IllegalThreadStateException.class: java/lang/IllegalThreadStateException.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/IllegalThreadStateException.class $(RELEASEDIR)/JAVA/LANG/ILLEGALTHREADSTATEEXCEPTION$(JVMTYPE) + +java/lang/ClassCastException.class: java/lang/ClassCastException.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/ClassCastException.class $(RELEASEDIR)/JAVA/LANG/CLASSCASTEXCEPTION$(JVMTYPE) + +java/lang/InterruptedException.class: java/lang/InterruptedException.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/InterruptedException.class $(RELEASEDIR)/JAVA/LANG/INTERRUPTEDEXCEPTION$(JVMTYPE) + +java/lang/ClassNotFoundException.class: java/lang/ClassNotFoundException.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/ClassNotFoundException.class $(RELEASEDIR)/JAVA/LANG/CLASSNOTFOUNDEXCEPTION$(JVMTYPE) + +java/lang/NullPointerException.class: java/lang/NullPointerException.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/NullPointerException.class $(RELEASEDIR)/JAVA/LANG/NULLPOINTEREXCEPTION$(JVMTYPE) + +java/lang/IndexOutOfBoundsException.class: java/lang/IndexOutOfBoundsException.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/IndexOutOfBoundsException.class $(RELEASEDIR)/JAVA/LANG/INDEXOUTOFBOUNDSEXCEPTION$(JVMTYPE) + +java/lang/ArrayIndexOutOfBoundsException.class: java/lang/ArrayIndexOutOfBoundsException.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/ArrayIndexOutOfBoundsException.class $(RELEASEDIR)/JAVA/LANG/ARRAYINDEXOUTOFBOUNDSEXCEPTION$(JVMTYPE) + +java/lang/StringIndexOutOfBoundsException.class: java/lang/StringIndexOutOfBoundsException.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/StringIndexOutOfBoundsException.class $(RELEASEDIR)/JAVA/LANG/STRINGINDEXOUTOFBOUNDSEXCEPTION$(JVMTYPE) + +java/lang/NegativeArraySizeException.class: java/lang/NegativeArraySizeException.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/NegativeArraySizeException.class $(RELEASEDIR)/JAVA/LANG/NEGATIVEARRAYSIZEEXCEPTION$(JVMTYPE) + +java/lang/ArrayStoreException.class: java/lang/ArrayStoreException.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/ArrayStoreException.class $(RELEASEDIR)/JAVA/LANG/ARRAYSTOREEXCEPTION$(JVMTYPE) + +java/lang/ArithmeticException.class: java/lang/ArithmeticException.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/ArithmeticException.class $(RELEASEDIR)/JAVA/LANG/ARITHMETICEXCEPTION$(JVMTYPE) + +java/lang/Boolean.class: java/lang/Boolean.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/Boolean.class $(RELEASEDIR)/JAVA/LANG/BOOLEAN$(JVMTYPE) + +java/lang/Byte.class: java/lang/Byte.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/Byte.class $(RELEASEDIR)/JAVA/LANG/BYTE$(JVMTYPE) + +java/lang/Short.class: java/lang/Short.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/Short.class $(RELEASEDIR)/JAVA/LANG/SHORT$(JVMTYPE) + +java/lang/Long.class: java/lang/Long.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/Long.class $(RELEASEDIR)/JAVA/LANG/LONG$(JVMTYPE) + +java/lang/Character.class: java/lang/Character.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/Character.class $(RELEASEDIR)/JAVA/LANG/CHARACTER$(JVMTYPE) + +java/lang/Number.class: java/lang/Number.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/Number.class $(RELEASEDIR)/JAVA/LANG/NUMBER$(JVMTYPE) + +java/lang/Integer.class: java/lang/Integer.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/Integer.class $(RELEASEDIR)/JAVA/LANG/INTEGER$(JVMTYPE) + +java/lang/Float.class: java/lang/Float.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/Float.class $(RELEASEDIR)/JAVA/LANG/FLOAT$(JVMTYPE) + +java/lang/Void.class: java/lang/Void.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/Void.class $(RELEASEDIR)/JAVA/LANG/VOID$(JVMTYPE) + +java/lang/Class.class: java/lang/Class.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/Class.class $(RELEASEDIR)/JAVA/LANG/CLASS$(JVMTYPE) + +java/lang/StringBuilder.class: java/lang/StringBuilder.java + $(JAVAC) $(JFLAGS) $< + cp java/lang/StringBuilder.class $(RELEASEDIR)/JAVA/LANG/STRINGBUILDER$(JVMTYPE) + +# +# Standard Java I/O classes +# + +java/io/OutputStream.class: java/io/OutputStream.java + $(JAVAC) $(JFLAGS) $< + cp java/io/OutputStream.class $(RELEASEDIR)/JAVA/IO/OUTPUTSTREAM$(JVMTYPE) + +java/io/FileOutputStream.class: java/io/FileOutputStream.java + $(JAVAC) $(JFLAGS) $< + cp java/io/FileOutputStream.class $(RELEASEDIR)/JAVA/IO/FILEOUTPUTSTREAM$(JVMTYPE) + +java/io/FilterOutputStream.class: java/io/FilterOutputStream.java java/io/OutputStream.java + $(JAVAC) $(JFLAGS) $< + cp java/io/FilterOutputStream.class $(RELEASEDIR)/JAVA/IO/FILTEROUTPUTSTREAM$(JVMTYPE) + +java/io/PrintStream.class: java/io/PrintStream.java java/io/FilterOutputStream.java + $(JAVAC) $(JFLAGS) $< + cp java/io/PrintStream.class $(RELEASEDIR)/JAVA/IO/PRINTSTREAM$(JVMTYPE) + +java/io/InputStream.class: java/io/InputStream.java + $(JAVAC) $(JFLAGS) $< + cp java/io/InputStream.class $(RELEASEDIR)/JAVA/IO/INPUTSTREAM$(JVMTYPE) + +java/io/FileInputStream.class: java/io/FileInputStream.java + $(JAVAC) $(JFLAGS) $< + cp java/io/FileInputStream.class $(RELEASEDIR)/JAVA/IO/FILEINPUTSTREAM$(JVMTYPE) + +java/io/IOException.class: java/io/IOException.java + $(JAVAC) $(JFLAGS) $< + cp java/io/IOException.class $(RELEASEDIR)/JAVA/IO/IOEXCEPTION$(JVMTYPE) + +java/io/FileNotFoundException.class: java/io/FileNotFoundException.java + $(JAVAC) $(JFLAGS) $< + cp java/io/FileNotFoundException.class $(RELEASEDIR)/JAVA/IO/FILENOTFOUNDEXCEPTION$(JVMTYPE) + +java/io/EOFException.class: java/io/EOFException.java + $(JAVAC) $(JFLAGS) $< + cp java/io/EOFException.class $(RELEASEDIR)/JAVA/IO/EOFEXCEPTION$(JVMTYPE) + +# +# Java networking classes +# + +java/net/NetworkDevice.class: java/net/NetworkDevice.java + $(JAVAC) $(JFLAGS) $< + cp java/net/NetworkDevice.class $(RELEASEDIR)/JAVA/NET/NETWORKDEVICE$(JVMTYPE) + +java/net/Loopback.class: java/net/Loopback.java + $(JAVAC) $(JFLAGS) $< + cp java/net/Loopback.class $(RELEASEDIR)/JAVA/NET/LOOPBACK$(JVMTYPE) + +# +# Sample classes +# + +samples/Hello.class: samples/Hello.java + $(JAVAC) $(JFLAGS) $< + cp samples/Hello.class $(SAMPLESDIR)/HELLO$(JVMTYPE) + +samples/HelloWorld.class: samples/HelloWorld.java + $(JAVAC) $(JFLAGS) $< + cp samples/HelloWorld.class $(SAMPLESDIR)/HELLOWORLD$(JVMTYPE) + +samples/List.class: samples/List.java + $(JAVAC) $(JFLAGS) $< + cp samples/List.class $(SAMPLESDIR)/LIST$(JVMTYPE) + +samples/SimplePong.class: samples/SimplePong.java + $(JAVAC) $(JFLAGS) $< + cp samples/SimplePong.class $(SAMPLESDIR)/SIMPLEPONG$(JVMTYPE) + +samples/Moire.class: samples/Moire.java + $(JAVAC) $(JFLAGS) $< + cp samples/Moire.class $(SAMPLESDIR)/MOIRE$(JVMTYPE) + +samples/HiResDemo.class: samples/HiResDemo.java + $(JAVAC) $(JFLAGS) $< + cp samples/HiResDemo.class $(SAMPLESDIR)/HIRESDEMO$(JVMTYPE) + +samples/RodsColors.class: samples/RodsColors.java + $(JAVAC) $(JFLAGS) $< + cp samples/RodsColors.class $(SAMPLESDIR)/RODSCOLORS$(JVMTYPE) + +samples/Terminal.class: samples/Terminal.java + $(JAVAC) $(JFLAGS) $< + cp samples/Terminal.class $(SAMPLESDIR)/TERMINAL$(JVMTYPE) + +samples/Volumes.class: samples/Volumes.java + $(JAVAC) $(JFLAGS) $< + cp samples/Volumes.class $(SAMPLESDIR)/VOLUMES$(JVMTYPE) + +samples/Catalog.class: samples/Catalog.java + $(JAVAC) $(JFLAGS) $< + cp samples/Catalog.class $(SAMPLESDIR)/CATALOG$(JVMTYPE) + +samples/TestArp.class: samples/TestArp.java + $(JAVAC) $(JFLAGS) $< + cp samples/TestArp.class $(SAMPLESDIR)/TESTARP$(JVMTYPE) + +samples/StressMem.class: samples/StressMem.java + $(JAVAC) $(JFLAGS) $< + cp samples/StressMem.class $(SAMPLESDIR)/STRESSMEM$(JVMTYPE) + +samples/TestChain.class: samples/TestChain.java + $(JAVAC) $(JFLAGS) $< + cp samples/TestChain.class $(SAMPLESDIR)/TESTCHAIN$(JVMTYPE) + +samples/NextChain.class: samples/NextChain.java + $(JAVAC) $(JFLAGS) $< + cp samples/NextChain.class $(SAMPLESDIR)/NEXTCHAIN$(JVMTYPE) + +samples/TestSelect.class: samples/TestSelect.java + $(JAVAC) $(JFLAGS) $< + cp samples/TestSelect.class $(SAMPLESDIR)/TESTSELECT$(JVMTYPE) +# +# Fava compiler +# +org/vm02/favac/Scanner.class: org/vm02/favac/Scanner.java + $(JAVAC) $(JFLAGS) $< + cp org/vm02/favac/Scanner.class $(ORGVM02DIR)/FAVAC/SCANNER$(JVMTYPE) + +org/vm02/favac/favac.class: org/vm02/favac/favac.java org/vm02/favac/Scanner.java + $(JAVAC) $(JFLAGS) $< + cp org/vm02/favac/favac.class $(ORGVM02DIR)/FAVAC/FAVAC$(JVMTYPE) + +org/vm02/favac/fasm.class: org/vm02/favac/fasm.java org/vm02/favac/Scanner.java + $(JAVAC) $(JFLAGS) $< + cp org/vm02/favac/fasm.class $(ORGVM02DIR)/FAVAC/FASM$(JVMTYPE) +# +# Character User Interface +# +org/vm02/cui/cuiDriver.class: org/vm02/cui/cuiDriver.java org/vm02/cui/cuiDriver.clasm + $(JAVAC) $(JFLAGS) $< + ca65 org/vm02/cui/cuiDriver.clasm + ld65 -C clasm.cfg org/vm02/cui/cuiDriver.o -o \$(ORGVM02DIR)/CUI/CUIDRIVER$(JVMTYPE) + +org/vm02/cui/cui.class: org/vm02/cui/cui.java + $(JAVAC) $(JFLAGS) $< + cp org/vm02/cui/cui.class $(ORGVM02DIR)/CUI/CUI$(JVMTYPE) + +org/vm02/cui/cuiControl.class: org/vm02/cui/cuiControl.java + $(JAVAC) $(JFLAGS) $< + cp org/vm02/cui/cuiControl.class $(ORGVM02DIR)/CUI/CUICONTROL$(JVMTYPE) + +org/vm02/cui/cuiButton.class: org/vm02/cui/cuiButton.java + $(JAVAC) $(JFLAGS) $< + cp org/vm02/cui/cuiButton.class $(ORGVM02DIR)/CUI/CUIBUTTON$(JVMTYPE) + +org/vm02/cui/cuiWindow.class: org/vm02/cui/cuiWindow.java + $(JAVAC) $(JFLAGS) $< + cp org/vm02/cui/cuiWindow.class $(ORGVM02DIR)/CUI/CUIWINDOW$(JVMTYPE) + +org/vm02/cui/cuiTopLevelWindow.class: org/vm02/cui/cuiTopLevelWindow.java + $(JAVAC) $(JFLAGS) $< + cp org/vm02/cui/cuiTopLevelWindow.class $(ORGVM02DIR)/CUI/CUITOPLEVELWINDOW$(JVMTYPE) + +org/vm02/cui/cuiConsole.class: org/vm02/cui/cuiConsole.java + $(JAVAC) $(JFLAGS) $< + cp org/vm02/cui/cuiConsole.class $(ORGVM02DIR)/CUI/CUICONSOLE$(JVMTYPE) + +org/vm02/cui/cuiPopUp.class: org/vm02/cui/cuiPopUp.java + $(JAVAC) $(JFLAGS) $< + cp org/vm02/cui/cuiPopUp.class $(ORGVM02DIR)/CUI/CUIPOPUP$(JVMTYPE) + +org/vm02/cui/cuiPopUpMenu.class: org/vm02/cui/cuiPopUpMenu.java + $(JAVAC) $(JFLAGS) $< + cp org/vm02/cui/cuiPopUpMenu.class $(ORGVM02DIR)/CUI/CUIPOPUPMENU$(JVMTYPE) + +org/vm02/cui/cuiListBox.class: org/vm02/cui/cuiListBox.java + $(JAVAC) $(JFLAGS) $< + cp org/vm02/cui/cuiListBox.class $(ORGVM02DIR)/CUI/CUILISTBOX$(JVMTYPE) + +org/vm02/cui/cuiMenuBar.class: org/vm02/cui/cuiMenuBar.java + $(JAVAC) $(JFLAGS) $< + cp org/vm02/cui/cuiMenuBar.class $(ORGVM02DIR)/CUI/CUIMENUBAR$(JVMTYPE) + +org/vm02/cui/cuiDropDownMenu.class: org/vm02/cui/cuiDropDownMenu.java + $(JAVAC) $(JFLAGS) $< + cp org/vm02/cui/cuiDropDownMenu.class $(ORGVM02DIR)/CUI/CUIDROPDOWNMENU$(JVMTYPE) + +org/vm02/cui/cuiMessageBox.class: org/vm02/cui/cuiMessageBox.java + $(JAVAC) $(JFLAGS) $< + cp org/vm02/cui/cuiMessageBox.class $(ORGVM02DIR)/CUI/CUIMESSAGEBOX$(JVMTYPE) + +org/vm02/cui/cuiScrollBar.class: org/vm02/cui/cuiScrollBar.java + $(JAVAC) $(JFLAGS) $< + cp org/vm02/cui/cuiScrollBar.class $(ORGVM02DIR)/CUI/CUISCROLLBAR$(JVMTYPE) + +org/vm02/cui/cuiTextEntry.class: org/vm02/cui/cuiTextEntry.java + $(JAVAC) $(JFLAGS) $< + cp org/vm02/cui/cuiTextEntry.class $(ORGVM02DIR)/CUI/CUITEXTENTRY$(JVMTYPE) + +org/vm02/cui/cuiApp.class: org/vm02/cui/cuiApp.java + $(JAVAC) $(JFLAGS) $< + cp org/vm02/cui/cuiApp.class $(ORGVM02DIR)/CUI/CUIAPP$(JVMTYPE) + +org/vm02/cui/Launcher.class: org/vm02/cui/Launcher.java + $(JAVAC) $(JFLAGS) $< + cp org/vm02/cui/Launcher.class $(RELEASEDIR)/LAUNCHER$(JVMTYPE) + +samples/TestCUI.class: samples/TestCUI.java + $(JAVAC) $(JFLAGS) $< + cp samples/TestCUI.class $(SAMPLESDIR)/TESTCUI$(JVMTYPE) diff --git a/src/memmgr.s b/src/memmgr.s new file mode 100755 index 0000000..62925f3 --- /dev/null +++ b/src/memmgr.s @@ -0,0 +1,3096 @@ +;* +;* JAVA MEMORY MANAGER FOR 6502 +;* +;* +;* HANDLE TABLE IS A TABLE OF POINTERS TO MEMORY BLOCKS +;* +;* THE LOW ORDER 3 BITS ARE STATE BITS FOR THE MEMORY BLOCK +;* 1 (001) = IN USE +;* 3 (011) = FIXED - HAS TO REMAIN IN PLACE +;* 5 (101) = CODE +;* 7 (111) = SWAPPED - NEEDS TO BE RELOADED FROM SOURCE OR SWAP +;* +;* +;* MEMORY BLOCKS ARE ALIGNED ON 64 BIT BOUNDARIES +;* +;* +;* A MEMORY HANDLE IS A POINTER TO THE ENTRY IN THE TABLE +;* +;* AN ALLOCATED MEMORY BLOCK IS ORGANIZED AS: +;* OFFSET SIZE FUNCTION +;* 0 2 SIZE +;* 2 2 REF CNT - MSB = ACCESSED BIT +;* 4 ? DATA +;* A FREE MEMORY BLOCK IS ORGANIZED AS: +;* OFFSET SIZE FUNCTION +;* 0 2 SIZE +;* 2 2 HNEXT + .INCLUDE "global.inc" + .INCLUDE "dvm.inc" + .IMPORT INIT_START,INIT_END,WARM_INIT + .IMPORT PRNTAX,COUT,CROUT,PUTS,PUTSLN,PRBYTE,PRSTR,PRSTRLN,MEMCPY,MEMCLR,KBWAIT + .IMPORT SYSTHROW,THROW_INTERNALERR +.IFDEF SWAPPING + .IMPORT PREFIX_GET,DIR_CREATE,FILE_GETINFO,FILE_CREATE,FILE_DESTROY,FILE_OPEN,FILE_CLOSE + .IMPORT FILE_GETEOF,FILE_READ,FILE_WRITE,FILE_SETBUFFER,FILE_SETAUX,ON_LINE + .EXPORT HMEM_CLRACCESS,HMEM_SWAP_CLEANUP +.ENDIF + .EXPORT HMEM_INIT + .EXPORT HMEM_ALLOC,HMEM_ALLOC_CODE,HMEM_ALLOC_FIXED,HMEM_FREE + .EXPORT HMEM_PTR,HMEM_REF_INC,HMEM_REF_DEC,HMEM_CLR + .EXPORT HMEM_LOCK,HMEM_UNLOCK,HMEM_UNLOCK_CODE,HMEM_GC +.IFDEF IDLE_GC + .EXPORT HMEM_GC_IDLE +.ENDIF + +.MACRO CHKAUXLC +.IFDEF DEBUG_MEMMGR +.IFDEF BIGMEM + PHA + LDA $C016 + BPL :+ + AUXZP_ACCESS_OFF + PERR "AUXZP ENABLED" + BRK +: PLA +.ENDIF +.ENDIF +.ENDMACRO +.MACRO CHKHNDL +.IFDEF DEBUG + CPX #>HTBL + BCS :+ + CPX #>HTBL_END + BCC :+ + AUXZP_ACCESS_OFF + PERR "BAD HNDL" + BRK +: +.ENDIF +.ENDMACRO + + .SEGMENT "INIT" +;* +;* CREATE EXTERNAL LINKEAGE TABLE AT $302 +;* +HMEM_INIT: LDA #HMEM_PTR + STA LINK_HMEMPTR+1 + LDA #HMEM_ALLOC + STA LINK_HMEMALLOC+1 + LDA #HMEM_ALLOC_FIXED + STA LINK_HMEMALLOCFIXED+1 + LDA #HMEM_FREE + STA LINK_HMEMFREE+1 + LDA #HMEM_LOCK + STA LINK_HMEMLOCK+1 + LDA #HMEM_UNLOCK + STA LINK_HMEMUNLOCK+1 + LDA #HMEM_REF_INC + STA LINK_HMEMREFINC+1 + LDA #HMEM_REF_DEC + STA LINK_HMEMREFDEC+1 + LDA #HMEM_GC + STA LINK_GC+1 +.IFDEF BIGMEM + LDA #$00 ; TOP OF FREE MEMORY IN AUX SPACE + STA CODEHEAPTOP + LDA #$BF + STA CODEHEAPTOP+1 +.ENDIF + +;* +;* INITIALIZE THE HANDLE TABLE +;* + AUXZP_ACCESS_ON + BIT LCBNK2 ; MAKE SURE LCBANK2 SET UP + BIT LCBNK2 + LDX #HTBL + STA HUNUSED+1 +LINK_UNUSED: STX HNDL + STA HNDL+1 + LDA HNDL + CLC ; MAKE UNUSED HANDLE LIST + ADC #$02 + STA (HNDL),Y + TAX + INY + LDA HNDL+1 + ADC #$00 + STA (HNDL),Y + DEY + CMP #>HTBL_END + BNE LINK_UNUSED + TYA + STA (HNDL),Y ; NULL OUT LAST IN LIST + INY + STA (HNDL),Y + JSR HMEM_NEW ; GET NEXT AVAIL HANDLE + STA HFREE ; MAKE INITAL FREE BLOCK + STX HFREE+1 +.IFDEF DEBUG_MEMMGR + STA HFREEBAK ; MAKE INITAL FREE BLOCK + STX HFREEBAK+1 +.ENDIF + LDY #$00 ; SET FREE MEM PTR + LDA #INIT_START + ADC #$00 + STA MPTR+1 + STA (HFREE),Y + DEY ; SET FREE MEM SIZE + LDA #TOPOFHEAP + SBC MPTR+1 + STA (MPTR),Y + INY + LDA #$00 ; NULL OUT NEXT FREE HANDLE + STA (MPTR),Y + INY + STA (MPTR),Y + AUXZP_ACCESS_OFF + LDA WARM_INIT + BNE :+ + LDA #'$' + JSR COUT + AUXZP_ACCESS_ON + LDY #$00 + LDA (MPTR),Y + INY + TAX + LDA (MPTR),Y + AUXZP_ACCESS_OFF + JSR PRNTAX + PSTRLN " bytes available" +: +.IFDEF DEBUG + AUXZP_ACCESS_ON + LDY #$00 + LDA (MPTR),Y + INY + STA RAMAVAIL + LDA (MPTR),Y + STA RAMAVAIL+1 + AUXZP_ACCESS_OFF +.ENDIF +.IFDEF DEBUG_MEMMGR +; JSR HMEM_DUMP +; JSR CROUT +.ENDIF +.IFDEF SWAPPING +; +; FIND THE MOST APPROPRIATE SWAP VOLUME +; +.IFDEF DEBUG_SWAP + PSTRLN "SWAPPING ENABLED" +; JSR KBWAIT +.ENDIF + LDX #$0F +FINDBESTVOL: STX VCNT + TXA + AND #$07 + BEQ :+ + CMP SKIPSLOT + BNE :++ +: JMP VOLNXT +: TXA + ASL + ASL + ASL + ASL + TAY + LDX #>CLASSFILE_IO_BUFF + JSR ON_LINE + LDX VCNT + JSR CPYVOL + BCC :+ + JMP VOLNXT +: LDA #SWAPFILE + JSR FILE_GETINFO + BCC :+ + JSR PUTS + .ASCIIZ "ERROR GETING VOLUME INFO:" + LDA #SWAPFILE + JSR PRSTRLN + BRK +: STA TMPTR + STX TMPTR+1 + LDY #$05 + LDA (TMPTR),Y + LDY #$08 + SEC + SBC (TMPTR),Y + STA HBEST + LDY #$06 + LDA (TMPTR),Y + LDY #$09 + SBC (TMPTR),Y + STA HBEST+1 + LDA SWAPFILE+2 + AND #$7F + CMP #'R' + BNE CHKFREE + LDA SWAPFILE+3 + AND #$7F + CMP #'A' + BNE CHKFREE + LDA SWAPFILE+4 + AND #$7F + CMP #'M' + BNE CHKFREE + LDY #$00 ; OFFSET FOR BEST RAM VOL + BEQ :+ +CHKFREE: LDY #$03 ; OFFSET FOR BEST DEV VOL +: LDA HBEST+1 + CMP BESTFREE+1,Y + BCC VOLNXT + BEQ :+ + BCS SAVEVOL +: LDA HBEST + CMP BESTFREE,Y + BCC VOLNXT + BEQ VOLNXT +SAVEVOL: LDA HBEST + STA BESTFREE,Y + LDA HBEST+1 + STA BESTFREE+1,Y + LDA VCNT + STA BESTVOL,Y +VOLNXT: LDX VCNT + DEX + BEQ :+ + JMP FINDBESTVOL +: LDX BESTRAMVOL + LDA BESTRAMFREE+1 ; RAM VOL MUST HAVE AT LEAST 64K FREE + BNE SAVEBESTVOL + LDA BESTRAMFREE + BMI SAVEBESTVOL + LDX BESTDEVVOL + BPL SAVEBESTVOL + LDA SKIPSLOT ; NO WORKABLE DEVICES FOUND, REMOVE SLOT 6 SKIP + BNE :+ ; AND TRY AGAIN + PSTRLN "HALT: NO SWAP VOLUME AVAILABLE!" + BRK +: LDA #$00 + STA SKIPSLOT + STA BESTRAMVOL + STA BESTDEVVOL + STA BESTRAMFREE + STA BESTRAMFREE+1 + STA BESTDEVFREE + STA BESTDEVFREE+1 + LDX #$0F + JMP FINDBESTVOL +SAVEBESTVOL: JSR CPYVOL + INC SWAPFILE + LDX SWAPFILE + LDA #'/' + STA SWAPFILE,X + LDY #$00 +CPYSWPDIR: LDA SWAPDIR,Y + BEQ :+ + INX + STA SWAPFILE,X + INY + BNE CPYSWPDIR +: STX SWAPFILE + LDA #SWAPFILE + JSR DIR_CREATE + LDX SWAPFILE + LDA #'/' + STA SWAPFILE+1,X +;.IFDEF DEBUG_SWAP + INX + STX SWAPFILE + LDA WARM_INIT + BNE :+ + JSR PUTS + .ASCIIZ "Swap path:" + LDA #SWAPFILE + JSR PRSTRLN +: LDX SWAPFILE + DEX +;.ENDIF + TXA + CLC + ADC #$05 ; ADD SPACE FOR SWAPFILE NAME + STA SWAPFILE + RTS +CPYVOL: TXA + ASL + ASL + ASL + ASL + TAY + LDA CLASSFILE_IO_BUFF,Y + AND #$0F + BNE :+ + SEC + RTS +: STA SWAPFILE + TAX + TYA + CLC + ADC SWAPFILE + TAY + INC SWAPFILE + LDA #'/' + STA SWAPFILE+1 +: LDA CLASSFILE_IO_BUFF,Y + STA SWAPFILE+1,X + DEY + DEX + BNE :- + CLC + RTS +;* +;* CLEANUP SWAP DIRECTORY +;* CALLED AFTER RELOADING VM02 FOR WARM INIT/RESET +;* +HMEM_SWAP_CLEANUP: +.IFDEF DEBUG_SWAP + JSR PUTSLN + .ASCIIZ "CLEAN UP SWAP FILES" +.ENDIF + LDX #>HTBL + LDA #SWAPFILE + JSR FILE_DESTROY ; REMOVE ANY EXISTING FILE + AUXZP_ACCESS_ON + PLA + STA HNDL+1 + PLA + STA HNDL +SWPCLNNXT: LDA HNDL + LDX HNDL+1 ; NEXT HANDLE + AUXZP_ACCESS_OFF + CLC + ADC #$02 + BCC :+ + INX +: CPX #>HTBL_END + BCC SWPCLNLP + LDA SWAPFILE + SEC + SBC #$05 + STA SWAPFILE + LDA #SWAPFILE + JMP FILE_DESTROY ; REMOVE SWAP DIRECTORY +SWAPDIR: .ASCIIZ "SWAP" +BESTVOL: +BESTRAMVOL: .BYTE $FF +BESTFREE: +BESTRAMFREE: .WORD $0000 +BESTDEVVOL: .BYTE $FF +BESTDEVFREE: .WORD $0000 +SKIPSLOT: .BYTE $06 ; SKIP SLOT SIX SWAP TEST INITIALLY + + .DATA +SWAPHNDL: .WORD $0000 +SWAPREF: .BYTE $00 +SWPAXED: .BYTE $00 ; MASK FOR ACCESSED TEST +SWPMINSIZE: .BYTE $00 +SWPLEN: .WORD $0000 +.ELSE + RTS +.ENDIF +;* +;* MEMORY MANAGER +;* + + .CODE +;* +;* CONVERT HANDLE TO POINTER +;* ENTRYY: AX = HANDLE +;* EXIT: AX = POINTER +;* +HMEM_PTR: CHKAUXLC + CHKHNDL + AUXZP_ACCESS_ON + STA HNDL + STX HNDL+1 +.IFDEF DEBUG_MEMMGR + JSR HMEM_VALIDATE +.ENDIF +.IFDEF SWAPPING + LDY #$00 + LDA (HNDL),Y +.IFDEF DEBUG + LSR + BCS :+ + AUXZP_ACCESS_OFF + JSR PUTS + .ASCIIZ "HMEM_PTR BEING CALLED ON FREE HANDLE: $" + AUXZP_ACCESS_ON + LDA HNDL+1 + LDX HNDL + AUXZP_ACCESS_OFF + JSR PRNTAX + JSR CROUT + BRK +; JMP THROW_INTERNALERR +: ROL +.ENDIF + AND #$07 + CMP #$07 + BEQ HMEM_SWAPIN + LDA (HNDL),Y + AND #$F8 + STA MPTR + INY + LDA (HNDL),Y + STA MPTR+1 + TAX + LDY #$03 + LDA (MPTR),Y + ORA #$80 ; SET ACCESSED FLAG + STA (MPTR),Y + LDA MPTR +.ELSE + LDY #$01 + LDA (HNDL),Y + DEY + TAX + LDA (HNDL),Y + AND #$F8 +.ENDIF + AUXZP_ACCESS_OFF + ORA #$04 ; RETURN POINTER + RTS +.IFDEF SWAPPING +;* +;* SWAP IN HANDLE MEMORY FROM FILE +;* ENTRY: HNDL = HANDLE +;* +HMEM_SWAPIN: +.IFDEF DEBUG_SWAP + AUXZP_ACCESS_OFF + JSR CROUT + JSR PUTS + .ASCIIZ "SWAPPING IN MEMORY HANDLE: " + AUXZP_ACCESS_ON + LDA HNDL+1 + LDX HNDL + AUXZP_ACCESS_OFF + JSR PRNTAX +; JSR KBWAIT + AUXZP_ACCESS_ON +.ENDIF + LDA HNDL + STA SWAPHNDL + LDX HNDL+1 + STX SWAPHNDL+1 + LDY #$00 ; PULL BLOCK SIZE FROM HANDLE + LDA (HNDL),Y + INY + AND #$F8 + SEC +.IFDEF DEBUG_MEMMGR + STA SWPLENBAK + LDA (HNDL),Y + STA SWPLENBAK+1 + LDA SWPLENBAK + SBC #$06 +.ELSE + SBC #$04 +.ENDIF + PHA ; AND PUSH IT FOR LATER + STA TMP + LDA (HNDL),Y + SBC #$00 + TAX + PHA + LDA TMP + +.IFDEF DEBUG_SWAP + PHA + TXA + PHA + AUXZP_ACCESS_OFF + JSR PUTS + .ASCIIZ ", LENGTH: " + AUXZP_ACCESS_ON + PLA + STA TMP+1 + PLA + STA TMP + TAX + LDA TMP+1 + LDX TMP + AUXZP_ACCESS_OFF + JSR PRNTAX + AUXZP_ACCESS_ON + LDA TMP + LDX TMP+1 + LDY #$00 +.ENDIF + AUXZP_ACCESS_OFF + JSR HMEM_ALLOC ; ALLOCATE MEMORY + AUXZP_ACCESS_ON + STA HNDL + STX HNDL+1 + LDY #$00 + LDA (HNDL),Y + INY + AND #$F8 + STA MPTR + LDA (HNDL),Y + STA MPTR+1 ; SAVE POINTER +.IFDEF DEBUG_MEMMGR + LDY #$00 + LDA (MPTR),Y + CMP SWPLENBAK + BNE :+ + INY + LDA (MPTR),Y + CMP SWPLENBAK+1 + BEQ :++ +: LDX SWPLENBAK + LDA SWPLENBAK+1 + AUXZP_ACCESS_OFF + JSR PRNTAX + JSR PUTS + .ASCIIZ " SWAPIN SIZE != ALLOC SIZE " + AUXZP_ACCESS_ON + LDY #$00 + LDA (MPTR),Y + INY + TAX + LDA (MPTR),Y + AUXZP_ACCESS_OFF + JSR PRNTAX + JSR CROUT + BRK +SWPLENBAK: .WORD 0 +: +.ENDIF +.IFDEF DEBUG_SWAP + AUXZP_ACCESS_OFF + JSR PUTS + .ASCIIZ ", ADDRESS: " + AUXZP_ACCESS_ON + LDA MPTR+1 + LDX MPTR + AUXZP_ACCESS_OFF + JSR PRNTAX + JSR CROUT + AUXZP_ACCESS_ON + LDY #$01 +.ENDIF + LDA HUNUSED+1 ; RETURN HANDLE TO UNUSED LIST + STA (HNDL),Y + DEY + LDA HUNUSED + STA (HNDL),Y + LDA HNDL + STA HUNUSED + LDA HNDL+1 + STA HUNUSED+1 + LDA SWAPHNDL ; ATTACH MEMORY TO SWAPIN HANDLE + STA HNDL + LDX SWAPHNDL+1 + STX HNDL+1 + JSR SETSWAPFILE + LDY #$00 + LDA MPTR + STA (HNDL),Y + INY + LDA MPTR+1 + STA (HNDL),Y + AUXZP_ACCESS_OFF + LDA #SWAPFILE + JSR FILE_GETINFO + BCS SWAPINERR + AUXZP_ACCESS_ON + STA TMPTR + STX TMPTR+1 + LDY #$04 ; READ FILE TYPE + LDA (TMPTR),Y + LDY #$00 + AND #$07 ; RESTORE HANDLE TYPE BITS + ORA (HNDL),Y + STA (HNDL),Y +; LDY #$06 ; RESTORE MEMORY BLOCK REF COUNTS +; LDA (TMPTR),Y +; DEY +; TAX +; LDA (TMPTR),Y +; LDY #$02 +; STA (MPTR),Y +; INY +; TXA +; ORA #$80 ; SET ACCESSED FLAG +; STA (MPTR),Y + LDY #$03 + LDA (MPTR),Y + ORA #$80 ; SET ACCESSED FLAG + STA (MPTR),Y + AUXZP_ACCESS_OFF + LDA #SWAPFILE + LDY #>SWAPFILE_IO_BUFF + JSR FILE_OPEN ; READ SWAPFILE + BCS SWAPINERR + STY SWAPREF + AUXZP_ACCESS_ON + LDA MPTR +; ORA #$04 + ORA #$02 + LDX MPTR+1 + JSR FILE_SETBUFFER ; SET DESTINATION FOR READ + PLA ; PULL SIZE + TAX + PLA + AUXZP_ACCESS_OFF + CLC + ADC #$02 ; ADD SIZE OF REF COUNT + BCC :+ + INX +: LDY SWAPREF + JSR FILE_READ ; READ IT! + BCS SWAPINERR + LDY SWAPREF + JSR FILE_CLOSE + LDA #SWAPFILE + JSR FILE_DESTROY ; REMOVE EXISTING FILE +.IF 0 + JSR PUTS + .ASCIIZ "SWAPIN AUX REF COUNT: " + AUXZP_ACCESS_ON + LDY #$02 + LDA (MPTR),Y ; GET REFERENCE COUNTS OF MEMORY BLOCK + INY + TAX + LDA (MPTR),Y + AUXZP_ACCESS_OFF + JSR PRNTAX + JSR CROUT +.ENDIF + AUXZP_ACCESS_ON +.IFDEF DEBUG_MEMMGR + LDA SWAPHNDL + LDX SWAPHNDL+1 + JSR HMEM_VALIDATE +.ENDIF + LDA MPTR + ORA #$04 + LDX MPTR+1 + AUXZP_ACCESS_OFF + RTS +SWAPINERR: +.IFDEF DEBUG_SWAP + AUXZP_ACCESS_OFF + PHA + JSR PUTS + .ASCIIZ "ERROR " + PLA + JSR PRBYTE + JSR PUTS + .ASCIIZ " READING FROM SWAPFILE: " + LDA #SWAPFILE + JSR PRSTRLN +.ENDIF + JMP THROW_INTERNALERR +;* +;* SET SWAP FILE NAME BASED ON HANDLE +;* ENTRY: AX = HANDLE +;* +SETSWAPFILE: PHA + TXA + JSR BYTE2ASCII + LDX SWAPFILE ; GET SWAPFILE NAME LENGTH + STA SWAPFILE-3,X + TYA + STA SWAPFILE-2,X + PLA + JSR BYTE2ASCII + STA SWAPFILE-1,X + TYA + STA SWAPFILE-0,X + RTS +;* +;* CONVERT BYTE VALUE TO ASCII REPRESENTATION +;* ENTRY: A = BYTE +;* EXIT: A = ASCII HI NIBBLE +;* Y = ASCII LO NIBBLE +;* +BYTE2ASCII: PHA + AND #$0F + CLC + ADC #'0' + CMP #'9'+1 + BCC :+ + ADC #'A'-'9'-2 +: TAY + PLA + LSR + LSR + LSR + LSR + CLC + ADC #'0' + CMP #'9'+1 + BCC :+ + ADC #'A'-'9'-2 +: RTS +.ENDIF +;* +;* CLEAR MEMORY BLOCK +;* ENTRY: AX = HANDLE +;* EXIT: AX = HANDLE +;* +HMEM_CLR: CHKAUXLC + CHKHNDL +.IFDEF BIGMEM + STA HNDL ; THIS IS SAVED TO MAIN ZP, NOT AUX + STX HNDL+1 +.ENDIF + JSR HMEM_PTR + STA DSTADDR + STX DSTADDR+1 + AND #$F8 ; POINT BACK TO HEADER + STA MPTR + STX MPTR+1 + LDY #$01 + LDA (MPTR),Y + DEY + TAX + LDA (MPTR),Y + SEC +.IFDEF DEBUG_MEMMGR + SBC #$06 ; SUBTRACT FENCE+HEADER SIZE +.ELSE + SBC #$04 ; SUBTRACT HEADER SIZE +.ENDIF + BCS :+ + DEX +: JSR MEMCLR ; CLEAR BLOCK + LDA HNDL ; RELOAD HANDLE INTO AX + LDX HNDL+1 + RTS +;* +;* INCREMENT REFERENCE COUNT +;* ENTRY: AX = HANDLE +;* EXIT: AX = HANDLE +;* +HMEM_REF_INC: CHKAUXLC + CHKHNDL +.IFDEF DEBUG_MEMMGR + AUXZP_ACCESS_ON + STA HNDL + STX HNDL+1 + JSR HMEM_VALIDATE + LDA HNDL + LDX HNDL+1 + AUXZP_ACCESS_OFF +.ENDIF +.IF 0 + STA HNDL + STX HNDL+1 + JSR PUTS + .ASCIIZ "INC REF: $" + LDA HNDL+1 + LDX HNDL + JSR PRNTAX + JSR CROUT + LDA HNDL + LDX HNDL+1 +.ENDIF +.IFDEF SWAPPING + JSR HMEM_PTR + AUXZP_ACCESS_ON + LDX HNDL+1 + LDY #$02 +.ELSE + AUXZP_ACCESS_ON + STA HNDL + STX HNDL+1 + LDY #$00 + LDA (HNDL),Y + INY + AND #$F8 + STA MPTR + LDA (HNDL),Y + INY + STA MPTR+1 +.ENDIF + LDA (MPTR),Y + CLC + ADC #$01 + STA (MPTR),Y + INY + LDA (MPTR),Y + ADC #$00 +.IFDEF SWAPPING + ORA #$80 ; SET ACCESSED FLAG +.ENDIF + STA (MPTR),Y + LDA HNDL + AUXZP_ACCESS_OFF + RTS +;* +;* DECREMENT REFERENCE COUNT +;* ENTRY: AX = HANDLE +;* EXIT: AX = REF COUNT +;* +HMEM_REF_DEC: CHKAUXLC + CHKHNDL +.IFDEF DEBUG_MEMMGR + AUXZP_ACCESS_ON + STA HNDL + STX HNDL+1 + JSR HMEM_VALIDATE + LDA HNDL + LDX HNDL+1 + AUXZP_ACCESS_OFF +.ENDIF +.IF 0 + STA HNDL + STX HNDL+1 + JSR PUTS + .ASCIIZ "DEC REF: $" + LDA HNDL+1 + LDX HNDL + JSR PRNTAX + JSR CROUT + LDA HNDL + LDX HNDL+1 +.ENDIF +.IFDEF SWAPPING + JSR HMEM_PTR + LDY #$02 + AUXZP_ACCESS_ON +.ELSE + AUXZP_ACCESS_ON + STA HNDL + STX HNDL+1 + LDY #$00 ; DEREF HANDLE + LDA (HNDL),Y + INY + AND #$F8 + STA MPTR + LDA (HNDL),Y + INY + STA MPTR+1 +.ENDIF + LDA (MPTR),Y + SEC ; DEC REF COUNT + SBC #$01 + STA (MPTR),Y + INY + PHA + LDA (MPTR),Y + AND #$7F + SBC #$00 + TAX +.IFDEF SWAPPING + ORA #$80 ; SET ACCESSED FLAG +.ENDIF + STA (MPTR),Y + PLA + AUXZP_ACCESS_OFF + RTS +;* +;* LOCK MEMORY BLOCK IN PLACE +;* ENTRY: AX = HANDLE +;* EXIT: AX = POINTER +;* +HMEM_LOCK: JSR HMEM_PTR ; MAKE SURE MEM BLOCK PRESENT +.IF 0 + JSR PUTS + .ASCIIZ "LOCKING HANDLE: " + AUXZP_ACCESS_ON + LDA HNDL+1 + LDX HNDL + AUXZP_ACCESS_OFF + JSR PRNTAX + JSR CROUT + AUXZP_ACCESS_ON + LDY #$01 + LDA (HNDL),Y + DEY + TAX + LDA (HNDL),Y +.ENDIF + LDY #$00 + AND #$F8 + ORA #$03 ; CHANGE FLAGS TO LOCKED + AUXZP_ACCESS_ON + STA (HNDL),Y ; AND SAVE + AUXZP_ACCESS_OFF + AND #$F8 + ORA #$04 + RTS +;* +;* UNLOCK MEMORY BLOCK +;* ENTRY: AX = HANDLE +;* +HMEM_UNLOCK: CHKHNDL + AUXZP_ACCESS_ON + STA HNDL + STX HNDL+1 +.IF 0 + AUXZP_ACCESS_OFF + JSR PUTS + .ASCIIZ "UNLOCKING HANDLE: " + AUXZP_ACCESS_ON + LDA HNDL+1 + LDX HNDL + AUXZP_ACCESS_OFF + JSR PRNTAX + JSR CROUT + AUXZP_ACCESS_ON + LDA HNDL + LDX HNDL+1 +.ENDIF +.IFDEF DEBUG_MEMMGR + JSR HMEM_VALIDATE +.ENDIF + LDY #$00 + LDA (HNDL),Y +.IFDEF DEBUG_MEMMGR + TAX + AND #$07 + CMP #$03 + BEQ :+ + AUXZP_ACCESS_OFF + JSR PUTS + .ASCIIZ "UNLOCKING UNLOCKED HANDLE :" + AUXZP_ACCESS_ON + LDA HNDL+1 + LDX HNDL + AUXZP_ACCESS_OFF + JSR PRNTAX + JSR CROUT + JMP THROW_INTERNALERR +: TXA + LDY #$00 +.ENDIF + AND #$F8 +.IFDEF SWAPPING + STA MPTR +.ENDIF + ORA #$01 + STA (HNDL),Y + AUXZP_ACCESS_OFF + RTS +;* +;* UNLOCK CODE MEMORY BLOCK +;* ENTRY: AX = HANDLE +;* +HMEM_UNLOCK_CODE: JSR HMEM_UNLOCK + LDY #$00 + AUXZP_ACCESS_ON + LDA (HNDL),Y + ORA #$04 + STA (HNDL),Y + AUXZP_ACCESS_OFF + RTS +;* +;* GET NEXT AVAILABLE HANDLE +;* +HMEM_NEW: LDA HUNUSED + LDX HUNUSED+1 + BEQ HNEW_GC + PHA + LDY #$00 + LDA (HUNUSED),Y + PHA + INY + LDA (HUNUSED),Y + STA HUNUSED+1 + PLA + STA HUNUSED + PLA + CLC + RTS +HNEW_GC: AUXZP_ACCESS_OFF + JSR HMEM_COALESCE ; ATTEMPT EASY FREE SPACE COMBINE + AUXZP_ACCESS_ON + BCC HMEM_NEW + AUXZP_ACCESS_OFF + JSR HMEM_COMPACT ; ATTEMPT FREE SPACE COMPACTION + AUXZP_ACCESS_ON + BCC HNEW_GC + AUXZP_ACCESS_OFF + PERR "OUT OF MEMORY HANDLES" +; JSR HMEM_DUMP +; BRK + JMP THROW_INTERNALERR +;* +;* UNLINK FREE BLOCK FROM LIST +;* +HFREE_UNLINK: CMP HFREE + BNE :+ + CPX HFREE+1 + BNE :+ + LDY #$00 + LDA (HFREE),Y + INY + TAX + LDA (HFREE),Y + INY + STX HFREE + STA HFREE+1 +.IFDEF DEBUG_MEMMGR + STX HFREEBAK ; SAVE BACKUP + STA HFREEBAK+1 +.ENDIF + LDA (HFREE),Y ; UNLINK FROM HEAD-OF-LIST + INY + TAX + LDA (HFREE),Y + STX HFREE + STA HFREE+1 +.IFDEF DEBUG_MEMMGR + STX HFREEBAK ; SAVE BACKUP + STA HFREEBAK+1 +.ENDIF + RTS +: STA TMP + STX TMP+1 + LDA HNDL ; SAVE HANDLE + PHA + LDA HNDL+1 + PHA + LDA HFREE + LDX HFREE+1 +LOOP_UNLINK: STA HNDL ; STORE HANDLE + STX HNDL+1 + LDY #$01 ; DEREF HANDLE FOR POINTER + LDA (HNDL),Y + DEY + TAX + LDA (HNDL),Y + STA HNDL + STX HNDL+1 + LDY #$03 ; CHECK NEXT HANDLE + LDA (HNDL),Y +.IFDEF DEBUG_MEMMGR + BNE :+ + AUXZP_ACCESS_OFF + PERR "UNLINK FREE BLOCK NOT IN LIST" + JMP THROW_INTERNALERR +: +.ENDIF + DEY + TAX + LDA (HNDL),Y + CMP TMP + BNE LOOP_UNLINK + CPX TMP+1 + BNE LOOP_UNLINK + DEY ; HANDLES EQUAL + LDA (TMP),Y ; DEREF TMP + DEY + TAX + LDA (TMP),Y + STA TMPTR + STX TMPTR+1 + LDY #$03 + LDA (TMPTR),Y ; MOVE NEXT LINK TO PREVIOUS + STA (HNDL),Y + DEY + LDA (TMPTR),Y + STA (HNDL),Y +.IFDEF DEBUG_MEMMGR + JSR HFREE_VALIDATE +.ENDIF + PLA ; RESTORE HNDL + STA HNDL+1 + PLA + STA HNDL + RTS +;* +;* ALLOCATE A MEMORY BLOCK +;* ENTRY: AX (LH) = SIZE +;* Y = INITIAL REF COUNT +;* EXIT: AX = HANDLE :: C == 0 +;* ERR :: C == 1 +;* +HMEM_ALLOC: CHKAUXLC +.IFDEF DEBUG + CPX #$10 + BCC :+ + STA MLEN + STX MLEN+1 + PERR "Big alloc: $" + LDX MLEN + LDA MLEN+1 + JSR PRNTAX + JSR CROUT + LDA MLEN + LDX MLEN+1 +; JMP THROW_INTERNALERR +: +.ENDIF + AUXZP_ACCESS_ON + STY REFCNT + CLC ; ADD SIZE OF HEADER (4 + 7) +.IFDEF DEBUG_MEMMGR + ADC #$0D ; AND ROUND TO MULTIPLE OF 8 BYTES +.ELSE + ADC #$0B ; AND ROUND TO MULTIPLE OF 8 BYTES +.ENDIF + BCC :+ + INX +: AND #$F8 + STA MLEN + STX MLEN+1 +.IFDEF DEBUG_MEMMGR + STA MLENBAK + STX MLENBAK+1 + JMP SEARCH_FREE +MLENBAK: .WORD $0000 +.ENDIF +SEARCH_FREE: LDA HFREE ; SEARCH FREE LIST FOR AVAILABLE SPACE + STA HNDL + LDA HFREE+1 + STA HNDL+1 + BEQ MAKE_FREE_AVAIL + LDA #$00 ; CLEAR OUT BEST MATCH +; STA HBEST + STA HBEST+1 +LOOP_FREE: AUXZP_ACCESS_ON + LDY #$01 ; DEREF HANDLE + LDA (HNDL),Y + DEY + STA MPTR+1 + LDA (HNDL),Y + STA MPTR + LDA (MPTR),Y + INY + SEC + SBC MLEN + TAX + LDA (MPTR),Y + SBC MLEN+1 + BCC NEXT_FREE + BNE :+ + CPX #$00 + BNE :+ + JMP MATCH_FREE +: LDA HBEST+1 ; CHECK FOR EXISTING BEST MATCH + BEQ SAVE_BEST ; SAVE ONE WITH HIGHEST ADDRESS + LDA (HNDL),Y ; COMPARE FREE BLOCK ADDRESSES + CMP (HBEST),Y + BCC NEXT_FREE + BNE SAVE_BEST + DEY + LDA (HNDL),Y + CMP (HBEST),Y + BCC NEXT_FREE +SAVE_BEST: LDA HNDL + STA HBEST + LDA HNDL+1 + STA HBEST+1 +NEXT_FREE: LDY #$02 ; FOLLOW LINKED FREE LIST + LDA (MPTR),Y + INY + STA HNDL + LDA (MPTR),Y + STA HNDL+1 + AUXZP_ACCESS_OFF + BNE LOOP_FREE ; CONTINUE UNTIL NULL NEXT + AUXZP_ACCESS_ON + LDA HBEST+1 + BEQ :+ + JMP BEST_FREE +: +.IFDEF SWAPPING + LDA #$FF + LDX MLEN+1 + BNE :+ + LDA MLEN +: STA SWPMINSIZE +.ENDIF +MAKE_FREE_AVAIL: AUXZP_ACCESS_OFF + JSR HMEM_COALESCE ; ATTEMPT EASY FREE SPACE COMBINE + AUXZP_ACCESS_ON + BCS :+ + LDA GCMLEN ; ONLY ATTEMPT SEARCH FREE IF COALESCED + CMP MLEN ; BLOCK IS GREATER OR EQUAL TO REQUESTED SIZE + LDA GCMLEN+1 + SBC MLEN+1 + BCC MAKE_FREE_AVAIL + JMP SEARCH_FREE +: +.IFDEF SWAPPING +SWAPRETRY: AUXZP_ACCESS_OFF + JSR HMEM_SWAPOUT_UNAXED ; ATTEMPT SWAPPING OUT UNACCESSED BLOCKS + BCC :++ +: JSR HMEM_COMPACT ; ATTEMPT FREE SPACE COMPACTION + BCC :- + JSR HMEM_SWAPOUT_UNLOCKED ; ATTEMPT SWAPPING OUT UNLOCKED BLOCKS +: AUXZP_ACCESS_ON + BCS :+ + LDA SWPLEN ; ONLY ATTEMPT SEARCH FREE IF COALESCED + CMP MLEN ; BLOCK IS GREATER OR EQUAL TO REQUESTED SIZE + LDA SWPLEN+1 + SBC MLEN+1 + BCC MAKE_FREE_AVAIL + JMP SEARCH_FREE +: LSR SWPMINSIZE + BNE SWAPRETRY +.ELSE + AUXZP_ACCESS_OFF + JSR HMEM_COMPACT ; ATTEMPT FREE SPACE COMPACTION + AUXZP_ACCESS_ON ; ONLY DO THIS AS A LAST RESORT + BCC MAKE_FREE_AVAIL +.ENDIF + JMP ALLOC_ERR +MATCH_FREE: LDA HNDL ; EXACT FIT - USE IT + LDX HNDL+1 + JSR HFREE_UNLINK + LDY #$00 + LDA (HNDL),Y + ORA #$01 ; SET ALLOCED FLAG + STA (HNDL),Y + LDY #$02 ; SET INITIAL REFERENCE COUNT + LDA REFCNT +.IFDEF DEBUG_MEMMGR + CMP #$02 + BCC :+ + AUXZP_ACCESS_OFF + PERR "LARGE REFCNT IN MEMALLOC" + JSR KBWAIT + AUXZP_ACCESS_ON + LDY #$02 ; SET INITIAL REFERENCE COUNT + LDA REFCNT +: +.ENDIF + STA (MPTR),Y + INY +.IFDEF SWAPPING + LDA #$80 ; SET ACCESSED FLAG +.ELSE + LDA #$00 +.ENDIF + STA (MPTR),Y +.IFDEF DEBUG_MEMMGR + LDA MLEN ; WRITE FENCE + LDX MLEN+1 + CMP MLENBAK + BNE :+ + CPX MLENBAK+1 + BEQ :++ +: AUXZP_ACCESS_OFF + PERR "BAD MLEN" + BRK +: SEC + SBC #$02 + BCS :+ + DEX +: CLC + ADC MPTR + STA MPTR + TXA + ADC MPTR+1 + STA MPTR+1 + LDY #$00 + LDA #$CA + STA (MPTR),Y + INY + LDA #$FE + STA (MPTR),Y + JSR HFREE_VALIDATE + LDA HNDL ; RETURN HANDLE, NO ERR + LDX HNDL+1 + JSR HMEM_VALIDATE +.ENDIF +.IFDEF DEBUG + LDA RAMAVAIL ; UPDATE AVAILABLE RAM + SEC + SBC MLEN + STA RAMAVAIL + LDA RAMAVAIL+1 + SBC MLEN+1 + STA RAMAVAIL+1 + JSR PRNTRAM +.ENDIF + LDA HNDL ; RETURN HANDLE, NO ERR + LDX HNDL+1 + AUXZP_ACCESS_OFF + CLC + RTS +BEST_FREE: LDY #$00 ; DEREF FREE HANDLE + LDA (HBEST),Y + INY + STA TMPTR + LDA (HBEST),Y + DEY + STA TMPTR+1 + LDA (TMPTR),Y + SEC ; SUB MLEN FROM FREE SIZE + SBC MLEN + STA (TMPTR),Y + INY + LDA (TMPTR),Y + SBC MLEN+1 + STA (TMPTR),Y + DEY ; CALC ALLOCED POINTER + CLC + LDA TMPTR + ADC (TMPTR),Y + INY + STA MPTR + LDA TMPTR+1 + ADC (TMPTR),Y + DEY ; SET LENGTH IN ALLOCED BLOCK + STA MPTR+1 + LDA MLEN + STA (MPTR),Y + INY + LDA MLEN+1 + STA (MPTR),Y + INY ; SET REFERENCE COUNT + LDA REFCNT +.IFDEF DEBUG_MEMMGR + CMP #$02 + BCC :+ + AUXZP_ACCESS_OFF + PERR "LARGE REFCNT IN MEMALLOC" + JSR KBWAIT + AUXZP_ACCESS_ON + LDY #$02 ; SET INITIAL REFERENCE COUNT + LDA REFCNT +: +.ENDIF + STA (MPTR),Y + INY +.IFDEF SWAPPING + LDA #$80 ; SET ACCESSED FLAG +.ELSE + LDA #$00 +.ENDIF + STA (MPTR),Y + JSR HMEM_NEW ; GET NEW HANDLE +.IFDEF DEBUG_MEMMGR + BCC :+ + JMP ALLOC_ERR +: +.ELSE + BCS ALLOC_ERR +.ENDIF + STA HNDL + STX HNDL+1 + LDY #$00 ; UPDATE HANDLE POINTERS + LDA MPTR + ORA #$01 ; SET ALLOCED FLAG + STA (HNDL),Y ; SET POINTER IN HANDLE TABLE + INY + LDA MPTR+1 + STA (HNDL),Y +.IFDEF DEBUG_MEMMGR + LDA MLEN ; WRITE FENCE + LDX MLEN+1 + CMP MLENBAK + BNE :+ + CPX MLENBAK+1 + BEQ :++ +: AUXZP_ACCESS_OFF + PERR "BAD MLEN" + BRK +: SEC + SBC #$02 + BCS :+ + DEX +: CLC + ADC MPTR + STA MPTR + TXA + ADC MPTR+1 + STA MPTR+1 + LDY #$00 + LDA #$CA + STA (MPTR),Y + INY + LDA #$FE + STA (MPTR),Y + LDA HNDL + LDX HNDL+1 + JSR HMEM_VALIDATE + LDX HNDL+1 +.ENDIF +.IFDEF DEBUG + LDA RAMAVAIL ; UPDATE AVAILABLE RAM + SEC + SBC MLEN + STA RAMAVAIL + LDA RAMAVAIL+1 + SBC MLEN+1 + STA RAMAVAIL+1 + JSR PRNTRAM +.ENDIF + LDA HNDL ; RETURN HANDLE, NO ERR + AUXZP_ACCESS_OFF + CLC + RTS +ALLOC_ERR: +.IFDEF DEBUG_MEMMGR + AUXZP_ACCESS_OFF + PERR "CANT ALLOC SIZE:" + AUXZP_ACCESS_ON + LDA MLEN+1 + LDX MLEN + AUXZP_ACCESS_OFF + JSR PRNTAX + JSR CROUT + AUXZP_ACCESS_ON + JSR HMEM_DUMP + BRK +.ENDIF + AUXZP_ACCESS_OFF + LDA #4 ; OUT OF MEMORY + JMP SYSTHROW +;* +;* ALLOC CODE MEMORY +;* ENTRY: AX (LH) = SIZE +;* Y = INITIAL REF COUNT +;* EXIT: AX = HANDLE :: C == 0 +;* ERR :: C == 1 +;* +HMEM_ALLOC_CODE: CHKAUXLC + JSR HMEM_ALLOC + BCS :+ + AUXZP_ACCESS_ON + LDY #$00 + LDA (HNDL),Y + ORA #$04 ; SET CODE FLAG IN ALLOC BLOCK FLAGS + STA (HNDL),Y + LDA HNDL + AUXZP_ACCESS_OFF +: RTS + +;* +;* ALLOCATE A MEMORY BLOCK AT FIXED ADDRESS +;* ENTRY: X = PAGE ADDRESS +;* A = SIZE IN PAGES +;* Y = INITIAL REF COUNT +;* EXIT: AX = HANDLE :: C == 0 +;* ERR :: C == 1 +;* +HMEM_ALLOC_FIXED: CHKAUXLC + AUXZP_ACCESS_ON + STY REFCNT + STA MEND+1 + TXA + CLC + ADC MEND+1 + STA MEND+1 ; MEND = END ADDRESS OF BLOCK +.IFDEF DEBUG_MEMMGR + LDA #$08 ; LEAVE ROOM FOR DEBUG FENCE + STA MEND +.ELSE + LDA #$00 + STA MEND +.ENDIF + LDA #$F8 ; SUBTRACT 8 BYTE MIN ALIGNED HEADER + DEX + STA MPTR + STX MPTR+1 + DVM_BEGIN + LDZPW MEND + LDZPW MPTR + SUBW + STZPW MLEN +SEARCH_FIXED: LDZPW HFREE +LOOP_FIXED: DUPW + STZPW HNDL + BRZW ALLOC_FIXED_ERR + LDZPW MPTR + LDPW (HNDL),0 + DUPW + STZPW TMPTR + BRBW NEXT_FIXED ; SKIP IF REQUESTED RANGE STARTS BELOW FREE + LDZPW TMPTR ; FIND END OF FREE BLOCK + LDPW (TMPTR),0 + ADDW + LDZPW MEND + SUBW + DUPW + BRPOSW FOUND_FIXED ; THIS FREE BLOCK ENCOMPASSES REQUESTED RANGE + POPW ; RE-ENABLE INTERRUPTS FOR A MOMENT +NEXT_FIXED: LDPW (TMPTR),2 + BRNCH LOOP_FIXED +ALLOC_FIXED_ERR: DVM_END + AUXZP_ACCESS_OFF +.IFDEF DEBUG_MEMMGR +; PERR "ALLOC_FIXED PAGES UNAVAILABLE" +; JSR KBWAIT +.ENDIF + SEC ; RETURN WITH ERR + RTS +FOUND_FIXED: DUPW + BRZW FRONT_FREE_FIXED +END_FREE_FIXED: STPW (MEND),0 ; SET SIZE OF NEW FREE END BLOCK + LDZPW HFREE + STPW (MEND),2 ; ADD TO FREE LIST + DVM_END + JSR HMEM_NEW ; GET NEW HANDLE FOR END FREE BLOCK + BCS ALLOC_FIXED_ERR+1 + STA HFREE + STX HFREE+1 +.IFDEF DEBUG_MEMMGR + STA HFREEBAK ; SAVE BACKUP + STX HFREEBAK+1 +.ENDIF + DVM_BEGIN + LDZPW MEND + DUPW + STPW (HFREE),0 +FRONT_FREE_FIXED: POPW + LDZPW MPTR + LDZPW TMPTR + SUBW + DUPW + BRZW FRONT_EQUAL_FIXED ; EQUAL START ADDRESSES + STPW (TMPTR),0 + DVM_END + JSR HMEM_NEW ; GET NEW HANDLE FOR ALLOCED BLOCK + BCS ALLOC_FIXED_ERR+1 + STA HNDL + STX HNDL+1 + DVM_BEGIN + LDZPW MPTR + LD3W + ORW ; SET FIXED AND ALLOCED FLAGS + STPW (HNDL),0 ; SAVE POINTER IN NEW HANDLE + BRNCH SET_ALLOC_FIXED +FRONT_EQUAL_FIXED: POPW + DVM_END + LDA HNDL ; SAME START ADDRESS FOR FREE AND ALLOC BLOCK + LDX HNDL+1 ; RE-USE FREE BLOCK + JSR HFREE_UNLINK ; UNLINK FREE BLOCK + DVM_BEGIN + LDPB (HNDL),0 + LD3B + ORB ; SET FIXED AND ALLOCED FLAGS + STPB (HNDL),0 +SET_ALLOC_FIXED: LDZPW MLEN + STPW (MPTR),0 + LDB REFCNT + ZEXTB + STPW (MPTR),2 + DVM_END +.IFDEF DEBUG_MEMMGR + LDA MLEN ; WRITE FENCE + LDX MLEN+1 + SEC + SBC #$02 + BCS :+ + DEX +: CLC + ADC MPTR + STA MPTR + TXA + ADC MPTR+1 + STA MPTR+1 + LDY #$00 + LDA #$CA + STA (MPTR),Y + INY + LDA #$FE + STA (MPTR),Y + LDA HNDL ; RETURN HANDLE, NO ERR + LDX HNDL+1 + JSR HMEM_VALIDATE +.ENDIF +.IFDEF DEBUG + LDA RAMAVAIL ; UPDATE AVAILABLE RAM + SEC + SBC MLEN + STA RAMAVAIL + LDA RAMAVAIL+1 + SBC MLEN+1 + STA RAMAVAIL+1 + JSR PRNTRAM +.ENDIF + LDA HNDL ; RETURN HANDLE, NO ERR + LDX HNDL+1 + AUXZP_ACCESS_OFF + CLC + RTS +.IFDEF SWAPPING +;* +;* INCREMENTALLY CLEAR ACCESSED FLAG ON ALL IN-USE BLOCKS +;* CALLED FROM THREAD_YEILD +;* +CLRACCHNDL: .ADDR HTBL +HMEM_CLRACCESS: CHKAUXLC + LDA CLRACCHNDL + LDX CLRACCHNDL+1 + CLC + ADC #$02 + BCC :++ + INX + CPX #>HTBL_END + BCC :+ + LDA #HTBL +: STX CLRACCHNDL+1 +: STA CLRACCHNDL + CHKHNDL + AUXZP_ACCESS_ON + STA HNDL + STX HNDL+1 + LDY #$00 + LDA (HNDL),Y + AND #$03 ; SKIP FREE, FIXED OR SWAPPED BLOCKS + CMP #$01 + BNE :+ +.IFDEF DEBUG_MEMMGR + LDA HNDL + JSR HNDL_VALIDATE + LDY #$00 +.ENDIF + LDA (HNDL),Y ; CLEAR ACCESSED FLAG + INY + AND #$F8 + STA MPTR + LDA (HNDL),Y + STA MPTR+1 + LDY #$03 + LDA (MPTR),Y + AND #$7F + STA (MPTR),Y +: AUXZP_ACCESS_OFF + RTS +;* +;* SWAP OUT UNLOCKED BLOCKS LARGER THAN SWAPMINSIZE +;* +SWPBESTHNDL: .WORD HTBL +HMEM_SWAPOUT_UNLOCKED: +.IFDEF DEBUG_SWAP + JSR PUTSLN + .ASCIIZ "SWAP OUT UNLOCKED BLOCKS" +.ENDIF + LDA #$00 + BEQ SWAPOUT_BEST +;* +;* SWAP OUT UNACCESSED BLOCKS +;* +HMEM_SWAPOUT_UNAXED: +.IFDEF DEBUG_SWAP + JSR PUTSLN + .ASCIIZ "SWAP OUT UNACCESSED BLOCKS" +.ENDIF + LDA #$80 +SWAPOUT_BEST: STA SWPAXED + LDA SWPBESTHNDL + LDX SWPBESTHNDL+1 + CLC + ADC #$02 + BCC :++ + INX + CPX #>HTBL_END + BCC :+ + LDA #HTBL +: STX SWPBESTHNDL+1 +: STA SWPBESTHNDL +SWPBESTLP: AUXZP_ACCESS_ON + STA HNDL + STX HNDL+1 + LDY #$00 + LDA (HNDL), Y + AND #$03 ; SKIP FREE, FIXED OR SWAPPED BLOCKS + CMP #$01 + BNE SWPBESTNXT + LDA (HNDL),Y + INY + AND #$F8 + STA MPTR + LDA (HNDL),Y + STA MPTR+1 + LDY #$03 ; CHECK ACCESSED BIT + LDA (MPTR),Y + AND SWPAXED ; TEST MASK FOR UNACCESSED VS UNLOCKED + BMI SWPBESTNXT ; SKIP ACCESSED BLOCKS + LDY #$01 + LDA (MPTR),Y ; COMPARE BLOCK SIZE FOR > SWAPMINSIZE + BNE SWPBEST + DEY + LDA (MPTR),Y + CMP SWPMINSIZE + BCS SWPBEST +SWPBESTNXT: LDA HNDL +; LDX HNDL+1 ; NEXT HANDLE + AUXZP_ACCESS_OFF +SWPBESTINC: CLC + ADC #$02 + BCC :+ + INX + CPX #>HTBL_END + BCC :+ + LDA #HTBL +: CMP SWPBESTHNDL ; EXIT AFTER LOOPING ONCE + BNE SWPBESTLP + CPX SWPBESTHNDL+1 + BNE SWPBESTLP + SEC + RTS +SWPBEST: LDA HNDL + STA SWPBESTHNDL + STX SWPBESTHNDL+1 +; JMP HMEM_SWAPOUT ; SWAP BLOCK OUT +;* +;* SWAP OUT MEMORY BLOCK TO FILE +;* ENTRY: AX = HANDLE +;* +HMEM_SWAPOUT: AUXZP_ACCESS_ON + STA HNDL + STX HNDL+1 +.IFDEF DEBUG_SWAP + AUXZP_ACCESS_OFF + JSR CROUT + JSR PUTS + .ASCIIZ "SWAPPING OUT MEMORY HANDLE: " + AUXZP_ACCESS_ON + LDA HNDL+1 + LDX HNDL + AUXZP_ACCESS_OFF + JSR PRNTAX +; JSR CROUT +; JSR KBWAIT + AUXZP_ACCESS_ON + LDA HNDL + LDX HNDL+1 +.ENDIF +.IFDEF DEBUG_MEMMGR + LDA HNDL + LDX HNDL+1 + JSR HMEM_VALIDATE + LDA HNDL + LDX HNDL+1 +.ENDIF +; LDY #$FF +; STY SWAPREF +; LDA HNDL +; LDX HNDL+1 + JSR SETSWAPFILE +; AUXZP_ACCESS_OFF +; LDA #SWAPFILE +; JSR FILE_DESTROY ; REMOVE ANY EXISTING FILE +; AUXZP_ACCESS_ON + LDY #$00 ; GET POINTER TO MEMORY BLOCK + LDA (HNDL),Y + INY + PHA + AND #$F8 + STA MPTR + LDA (HNDL),Y + STA MPTR+1 +; LDY #$03 +; LDA (MPTR),Y ; GET REFERENCE COUNTS OF MEMORY BLOCK +; DEY +; TAX +; LDA (MPTR),Y +; JSR FILE_SETAUX ; SET AUX TYPE FOR FILE +.IF 0 + AUXZP_ACCESS_OFF + JSR PUTS + .ASCIIZ "SWAPOUT AUX REF COUNT: " + AUXZP_ACCESS_ON + LDY #$02 + LDA (MPTR),Y ; GET REFERENCE COUNTS OF MEMORY BLOCK + INY + TAX + LDA (MPTR),Y + AUXZP_ACCESS_OFF + JSR PRNTAX + JSR CROUT + AUXZP_ACCESS_ON +.ENDIF + PLA ; GET FILE TYPE BITS FROM BLOCK BITS + TAY + AUXZP_ACCESS_OFF + LDA #SWAPFILE + JSR FILE_CREATE +; BCS SWAPOUTERR + LDA #SWAPFILE + LDY #>SWAPFILE_IO_BUFF + JSR FILE_OPEN ; OPEN NEWLY CREATED FILE +; DSS BCS SWAPOUTERR + STY SWAPREF + AUXZP_ACCESS_ON + LDX MPTR+1 + TXA + PHA + LDA MPTR + PHA +; ORA #$04 + ORA #$02 + JSR FILE_SETBUFFER + LDY #$01 ; GET SIZE OF BLOCK + LDA (MPTR),Y + DEY + TAX + LDA (MPTR),Y + STA SWPLEN + STX SWPLEN+1 +.IFDEF DEBUG_SWAP + AUXZP_ACCESS_OFF + JSR PUTS + .ASCIIZ " LENGTH: " + AUXZP_ACCESS_ON + LDA SWPLEN+1 + LDX SWPLEN + AUXZP_ACCESS_OFF + JSR PRNTAX + JSR CROUT +; JSR KBWAIT + AUXZP_ACCESS_ON + LDA SWPLEN + LDX SWPLEN+1 +.ENDIF + SEC ; SUBTRACT OFF BLOCK HEADER SIZE +.IFDEF DEBUG_MEMMGR +; SBC #$06 + SBC #$04 +.ELSE +; SBC #$04 + SBC #$02 +.ENDIF + BCS :+ + DEX +: AUXZP_ACCESS_OFF + LDY SWAPREF + JSR FILE_WRITE + BCS SWAPOUTERR + LDY SWAPREF + JSR FILE_CLOSE + BCS SWAPOUTERR + AUXZP_ACCESS_ON + LDY #$00 + LDA (HNDL),Y + LDA #$07 ; SET SWAPPED BITS FOR HANDLE + ORA SWPLEN ; STICK BLOCK SIZE IN HANDLE DATA + STA (HNDL),Y + INY + LDA SWPLEN+1 ; CLEVER, HUH? + STA (HNDL),Y + JSR HMEM_NEW ; GET NEW HANDLE TO POINT TO OLD MEMORY + STA HNDL + STX HNDL+1 + STA COMPGCHNDL ; FOCUS COMPACTOR HERE + STX COMPGCHNDL+1 + LDY #$00 ; MOVE BLOCK POINTER TO NEW HANDLE + PLA + ORA #$01 + STA (HNDL),Y + INY + PLA + STA (HNDL),Y +.IFDEF DEBUG + LDY #$02 ; ZERO OUT REF COUNT + LDA #$00 + STA (MPTR),Y + INY + STA (MPTR),Y +.ENDIF +.IF 0 + AUXZP_ACCESS_OFF + JSR PUTS + .ASCIIZ "SWAPOUT FREE HANDLE: $" + AUXZP_ACCESS_ON + LDX HNDL + LDA HNDL+1 + AUXZP_ACCESS_OFF + JSR PRNTAX + JSR CROUT + AUXZP_ACCESS_ON +.ENDIF + LDA HNDL + LDX HNDL+1 + AUXZP_ACCESS_OFF + ;JMP HMEM_FREE ; NOW FREE THE OLD BLOCK AND NEW HANDLE + BNE HMEM_FREE ; NOW FREE THE OLD BLOCK AND NEW HANDLE +SWAPOUTERR: + AUXZP_ACCESS_OFF +.IFDEF DEBUG_SWAP + PHA + JSR PUTS + .ASCIIZ "ERROR " + PLA + JSR PRBYTE + JSR PUTS + .ASCIIZ " WRITING TO SWAPFILE: " + LDA #SWAPFILE + JSR PRSTRLN +.ENDIF + LDY SWAPREF ; ATTEMPT CLEAN-UP + BMI :+ + JSR FILE_CLOSE +: LDA #SWAPFILE + JSR FILE_DESTROY + SEC ; SET CARRY AND EXIT - NO ERROR + RTS +.ENDIF +;* +;* FREE MEMORY BLOCK +;* ENTRY: AX = HANDLE +;* EXIT: C = 0 :: NO ERROR +;* +HMEM_FREE: CHKAUXLC + CHKHNDL +.IF 0 + AUXZP_ACCESS_ON + STA HNDL + STX HNDL+1 + AUXZP_ACCESS_OFF + JSR PUTS + .ASCIIZ "FREE HANDLE: " + AUXZP_ACCESS_ON + LDA HNDL+1 + LDX HNDL + AUXZP_ACCESS_OFF + JSR PRNTAX + LDA #'-' + JSR COUT + LDA #'>' + JSR COUT + AUXZP_ACCESS_ON + LDY #$00 + LDA (HNDL),Y + INY + AND #$F8 + TAX + LDA (HNDL),Y + STA $71 + STX $70 + AUXZP_ACCESS_OFF + JSR PRNTAX + JSR PUTS + .ASCIIZ ": LEN:" + AUXZP_ACCESS_ON + LDY #$00 + LDA ($70),Y + INY + TAX + LDA ($70),Y + AUXZP_ACCESS_OFF + JSR PRNTAX + JSR PUTS + .ASCIIZ " REF:" + AUXZP_ACCESS_ON + LDY #$02 + LDA ($70),Y + INY + TAX + LDA ($70),Y + AUXZP_ACCESS_OFF + JSR PRNTAX + JSR CROUT +; JSR KBWAIT + AUXZP_ACCESS_ON +; LDA HNDL +; LDX HNDL+1 +; JSR HMEM_VALIDATE +; JSR HFREE_VALIDATE + LDA HNDL + LDX HNDL+1 + AUXZP_ACCESS_OFF +.ENDIF +.IFDEF SWAPPING + JSR HMEM_PTR + LDY #$01 + STY GCNEEDED + DEY ; FREE ALLOCED MEMORY BLOCK + AUXZP_ACCESS_ON + LDA (HNDL),Y + AND #$F8 + STA (HNDL),Y ; CLEAR ALLOCED FLAGS + INY +.ELSE + LDY #$01 + STY GCNEEDED + DEY + AUXZP_ACCESS_ON + STA HNDL + STX HNDL+1 + LDA (HNDL),Y + AND #$F8 + STA (HNDL),Y ; CLEAR ALLOCED FLAG + INY + STA MPTR + LDA (HNDL),Y + STA MPTR+1 +.ENDIF + INY +.IFDEF DEBUG + LDA (MPTR),Y + BEQ :+ + AUXZP_ACCESS_OFF + JSR PUTS + .ASCIIZ "FREE NON_ZERO REF COUNT. HANDLE/ADDRESS: $" + AUXZP_ACCESS_ON + LDA HNDL+1 + LDX HNDL + AUXZP_ACCESS_OFF + JSR PRNTAX + LDA #$80|'/' + JSR COUT + LDA #$80|'$' + JSR COUT + AUXZP_ACCESS_ON + LDA MPTR+1 + LDX MPTR + AUXZP_ACCESS_OFF + JSR PRNTAX + JSR CROUT +; JMP THROW_INTERNALERR + AUXZP_ACCESS_ON +: +.ENDIF + LDA HFREE ; ADD TO FREE LIST + STA (MPTR),Y + INY + LDA HFREE+1 + STA (MPTR),Y + LDA HNDL + LDX HNDL+1 + STA HFREE + STX HFREE+1 +.IFDEF DEBUG_MEMMGR + STA HFREEBAK ; SAVE BACKUP + STX HFREEBAK+1 +.ENDIF +;.IFDEF DEBUG +.IF 0 + LDA MPTR ; ZERO OUT MEMORY BLOCK WHEN DEBUGGING + ORA #$04 + STA DSTADDR + LDA MPTR+1 + STA DSTADDR+1 + LDY #$01 ; SUBTRACT HEADER SIZE FROM BLOCK SIZE + LDA (MPTR),Y + DEY + TAX + LDA (MPTR),Y + SEC +.IFDEF DEBUG_MEMMGR + SBC #$06 +.ELSE + SBC #$04 +.ENDIF + BCS :+ + DEX +: JSR MEMCLR +.ENDIF +.IFDEF DEBUG_MEMMGR + JSR HFREE_VALIDATE +.ENDIF +.IFDEF DEBUG + LDY #$00 ; UPDATE AVAILABLE RAM + LDA (MPTR),Y + INY + CLC + ADC RAMAVAIL + STA RAMAVAIL + LDA (MPTR),Y + ADC RAMAVAIL+1 + STA RAMAVAIL+1 + JSR PRNTRAM +.ENDIF + AUXZP_ACCESS_OFF + CLC + RTS +;******************************* +;* +;* GARBAGE COLLECTION ROUTINES +;* +;******************************* +;* +;* GARBAGE COLLECT +;* ENTRY: AX = MAX ITERATIONS +;* Y = MIN SWAP SIZE +;* EXIT: CFLAG=1, NOTHING COLLECTED; CFLAG=0, GARBAGE COLLECTED +;* +GCCNT: .WORD $0000 +HMEM_GC: ADC #$01 + INX + STA GCCNT + STX GCCNT+1 +.IFDEF DEBUG_GC + JSR PUTSLN + .ASCIIZ "STARTING GARBAGE COLLECTION:" + JSR HMEM_DUMP + JSR KBWAIT +.ENDIF + LDA GCNEEDED + BNE LOOPGC + INC GCNEEDED +LOOPGC: DEC GCCNT + BNE :+ + DEC GCCNT+1 + BEQ :++ +: +.IFDEF SWAPPING + JSR HMEM_CLRACCESS +.ENDIF + JSR HMEM_GC_INCR + BCC LOOPGC +: +.IFDEF DEBUG_GC + JSR PUTSLN + .ASCIIZ "FINISHED GARBAGE COLLECTION:" + JSR HMEM_DUMP + JSR KBWAIT +.ENDIF +EXITGC: RTS +;* +;* GARBAGE COLLECTION CALLED FROM IDLE LOOP +;* +.IFDEF IDLE_GC +HMEM_GC_IDLE: +.ENDIF +;* +;* GARBAGE COLLECT +;* ENTRY: +;* EXIT: CFLAG=1, NOTHING COLLECTED; CFLAG=0, GARBAGE COLLECTED +;* +HMEM_GC_INCR: CHKAUXLC + SEC + LDA GCNEEDED + BEQ EXITGC + CMP #$02 + BEQ :+ + JSR HMEM_COALESCE ; ATTEMPT EASY FREE SPACE COMBINE + BCC EXITGC + INC GCNEEDED +: JSR HMEM_COMPACT ; ATTEMPT FREE SPACE COMPACTION +.IFDEF SWAPPING +;* +;* SWAP OUT MEMORY BLOCKS WHEN IDLE +;* START FROM BOTTOM AND MOVE TO TOP. THE THEORY BEING IT WILL SWAP OUT OLDER BLOCKS FIRST. +;* + LDA SWPGCHNDL + LDX SWPGCHNDL+1 + CLC + ADC #$02 + BCC :++ + INX + CPX #>HTBL_END + BCC :+ + LDA #HTBL +: STX SWPGCHNDL+1 +: STA SWPGCHNDL + CHKHNDL + AUXZP_ACCESS_ON + STA HNDL + STX HNDL+1 + LDY #$00 + LDA (HNDL),Y + AND #$03 ; SKIP FREE, FIXED OR SWAPPED BLOCKS + CMP #$01 + CLC + BNE EXITSWPGC +.IFDEF DEBUG_MEMMGR + LDA HNDL + JSR HNDL_VALIDATE + LDX HNDL+1 + LDY #$00 +.ENDIF + LDA (HNDL),Y + INY + AND #$F8 + STA MPTR + LDA (HNDL),Y + STA MPTR+1 + LDY #$03 + LDA (MPTR),Y + BMI EXITSWPGC ; LEAVE ACCESSED BLOCKS ALONE + LDA HNDL + AUXZP_ACCESS_OFF + DEC GCNEEDED + JMP HMEM_SWAPOUT ; SWAP OUT UNACCESSED BLOCK +SWPGCHNDL: .ADDR HTBL +EXITSWPGC: AUXZP_ACCESS_OFF + CLC +.ELSE + BCC EXITGC + LDA #$00 ; AND SWAPPING, SO DON'T DO IT WHEN SWAPPING ENABLED + STA GCNEEDED +.ENDIF + RTS +;* +;* COALESCE ADJACENT FREE BLOCKS +;* ENTRY: +;* EXIT: CFLAG=1, NOTHING COALESCED; CFLAG=0, FREE MEM COALESCED +;* +HMEM_COALESCE: +.IFDEF DEBUG_GC + PERR "HMEM_COALESCING..." +.ENDIF + AUXZP_ACCESS_ON + LDA HFREE ; SEARCH FREE LIST FOR BLOCKS TO COMBINE + STA GCHNDL + LDA HFREE+1 + STA GCHNDL+1 + BEQ NOTGCED +SEARCHCOALESCE: LDY #$01 ; DEREF HANDLE + LDA (GCHNDL),Y + DEY + STA GCMPTR+1 + LDA (GCHNDL),Y + STA GCMPTR + CLC + ADC (GCMPTR),Y + INY + STA GCMEND + LDA GCMPTR+1 + ADC (GCMPTR),Y + STA GCMEND+1 + LDA HFREE + STA GCTMP + LDA HFREE+1 + STA GCTMP+1 +LOOPCOALESCE: LDY #$00 ; COMPARE THIS FREE BLOCK ADDRESS + AUXZP_ACCESS_ON + LDA (GCTMP),Y ; WITH END OF FREE BLOCK BEING CHECKED + INY + TAX + LDA (GCTMP),Y + CMP GCMEND+1 + BNE NEXTCOAL + CPX GCMEND + BEQ MATCHCOALESCE ; A MATCH, COMBINE BLOCKS +NEXTCOAL: INY + STA GCTMP+1 ; GET POINTER TO FREE BLOCK + STX GCTMP + LDA (GCTMP),Y ; GET NEXT FREE BLOCK HANDLE + INY + TAX + LDA (GCTMP),Y + STX GCTMP + STA GCTMP+1 + AUXZP_ACCESS_OFF + BNE LOOPCOALESCE ; KEEP CHECKING + AUXZP_ACCESS_ON + LDA (GCMPTR),Y ; NEXT FREE BLOCK TO COMPARE WITH + BEQ NOTGCED + STA GCHNDL+1 + DEY + LDA (GCMPTR),Y + STA GCHNDL + JMP SEARCHCOALESCE +NOTGCED: AUXZP_ACCESS_OFF + SEC + RTS +MATCHCOALESCE: +;.IFDEF DEBUG_GC +.IF 0 + AUXZP_ACCESS_OFF + JSR PUTS + .ASCIIZ "COMBINING " + AUXZP_ACCESS_ON + LDA GCHNDL+1 + LDX GCHNDL + AUXZP_ACCESS_OFF + JSR PRNTAX + JSR PUTS + .ASCIIZ " AND " + AUXZP_ACCESS_ON + LDA GCTMP+1 + LDX GCTMP + AUXZP_ACCESS_OFF + JSR PRNTAX + JSR CROUT + AUXZP_ACCESS_ON +.ENDIF + LDA GCTMP ; UNLINK FREE BLOCK FROM LIST + LDX GCTMP+1 + JSR HFREE_UNLINK + LDY #$00 ; RETURN UNREFERENCED HANDLE BACK TO UNUSED LIST + LDA (GCTMP),Y + PHA ; SAVE MEMORY POINTER FOR LATER + LDA HUNUSED + STA (GCTMP),Y + INY + LDA (GCTMP),Y + PHA + LDA HUNUSED+1 + STA (GCTMP),Y + DEY + LDA GCTMP + STA HUNUSED + LDA GCTMP+1 + STA HUNUSED+1 + PLA ; RECOVER MEMORY POINTER + STA GCTMP+1 + PLA + STA GCTMP + LDA (GCMPTR),Y ; ADD SIZE OF NEXT FREE BLOCK TO CURRENT + CLC + ADC (GCTMP),Y + STA (GCMPTR),Y + INY + STA GCMLEN + LDA (GCMPTR),Y + ADC (GCTMP),Y + STA (GCMPTR),Y + STA GCMLEN+1 +.IFDEF DEBUG_MEMMGR + JSR HFREE_VALIDATE +.ENDIF + AUXZP_ACCESS_OFF + CLC + RTS +;* +;* COMPACT MEMORY BY MOVING ALLOCED BLOCKS TO TOP OF HEAP +;* ENTRY: +;* EXIT: CFLAG=1, NOTHING COMPACTED; CFLAG=0, MEM COMPACTED +;* +COMPGCHNDL: .WORD $0000 +RECOMPACT: LDA HFREE + LDX HFREE+1 ; CHECK FOR ANY FREE BLOCKS + STA COMPGCHNDL + STX COMPGCHNDL+1 + BEQ NOTGCED ; C = 1 +HMEM_COMPACT: +.IFDEF DEBUG_GC + AUXZP_ACCESS_OFF + PERR "HMEM_COMPACTING..." +.ENDIF + LDA COMPGCHNDL + LDX COMPGCHNDL+1 + AUXZP_ACCESS_ON + BEQ RECOMPACT + CHKHNDL + STA GCHNDL + STX GCHNDL+1 + LDY #$00 ; DEREF HANDLE + LDA (GCHNDL),Y + LSR + BCS RECOMPACT + ASL + INY + STA GCMPTR ; GCMPTR = ADDRESS OF FREE BLOCK + LDA (GCHNDL),Y + STA GCMPTR+1 + LDA #HTBL + STA GCTMP + STX GCTMP+1 +LOOPCOMPACT: LDY #$00 + LDA (GCTMP),Y + TAX + AND #$03 + CMP #$01 ; CHECK IF FREE, LOCKED OR SWAPPED + BNE NEXTCOMP ; SKIP IF NOT AVAIL + TXA + AND #$F8 ; MASK OFF FLAGS + TAX + INY + LDA (GCTMP),Y ; COMPARE FOR LOWER ADDRESS THAN FREE BLOCK + CMP GCMPTR+1 + BNE :+ + CPX GCMPTR +: BCS NEXTCOMP + STA GCMEND+1 ; CALC END ADDRESS OF BLOCK + STX GCMEND ; IF IT MATCHES START OF FREE BLOCK + DEY ; THEN IT CAN BE SHIFTED UP + TXA + CLC + ADC (GCMEND),Y + INY + TAX + LDA GCMEND+1 + ADC (GCMEND),Y + CMP GCMPTR+1 + BNE :+ + CPX GCMPTR + BNE :+ + LDA GCTMP ; SAVE NEAREST NEIGHBOR + STA GCNEIGHBOR + LDA GCTMP+1 +; STA GCNEIGHBOR+1 +; BNE NEXTCOMP + BNE SHIFTNEIGHBOR ; MOVE NEXT-DOOR NEIGHBOR UP +: LDA (GCMPTR),Y ; ELSE COMPARE SIZE OF BLOCK TO FREE BLOCK + CMP (GCMEND),Y ; IT MUST BE EQUAL TO SIZE + BNE NEXTCOMP ; OF FREE BLOCK + DEY + LDA (GCMPTR),Y + CMP (GCMEND),Y + BNE NEXTCOMP + LDA GCTMP + STA GCBEST + LDA GCTMP+1 + STA GCBEST+1 + BNE XCHNGBEST +;CHECKBESTCOMP: LDA GCBEST+1 ; ONLY REPLACE BEST MATCH IF AT A HIGER ADDRESS +; BEQ :+ ; ASSUMING HIGHER ADDRESSES ARE OLDER AND +; INY ; WILL BE FREED LAST +; LDA GCMEND+1 +; CMP (GCBEST),Y +; BCC NEXTCOMP ; CURRENT BEST IS HIGHER +; BNE :+ +; DEY +; LDA GCMEND +; CMP (GCBEST),Y +; BCC NEXTCOMP ; CURRENT BEST IS HIGER +;: LDA GCTMP +; STA GCBEST +; LDA GCTMP+1 +; STA GCBEST+1 +NEXTCOMP: LDA GCTMP ; MOVE TO NEXT HANDLE IN TABLE + AUXZP_ACCESS_OFF + CLC + ADC #$02 + AUXZP_ACCESS_ON + STA GCTMP + BCC LOOPCOMPACT + INC GCTMP+1 + LDX GCTMP+1 + CPX #>HTBL_END + BCC LOOPCOMPACT +EXITCOMPACT: AUXZP_ACCESS_OFF + LDY #$02 + LDA (GCMPTR),Y + INY + STA COMPGCHNDL + LDA (GCMPTR),Y + STA COMPGCHNDL+1 + SEC + RTS +SHIFTNEIGHBOR: STA GCBEST+1 + LDA GCNEIGHBOR + STA GCBEST +.IF 0 + AUXZP_ACCESS_OFF + LDA #$80|'<' + JSR COUT + AUXZP_ACCESS_ON +.ENDIF +.IFDEF DEBUG_GC + AUXZP_ACCESS_OFF + JSR PUTS + .ASCIIZ "SHIFT NGHBR " + AUXZP_ACCESS_ON + LDA GCNEIGHBOR+1 + LDX GCNEIGHBOR + AUXZP_ACCESS_OFF + JSR PRNTAX + JSR PUTS + .ASCIIZ " OVR " + AUXZP_ACCESS_ON + LDA GCHNDL+1 + LDX GCHNDL + AUXZP_ACCESS_OFF + JSR PRNTAX + JSR CROUT + AUXZP_ACCESS_ON +.ENDIF +.IFDEF DEBUG_MEMMGR + LDA GCNEIGHBOR + LDX GCNEIGHBOR+1 + JSR HMEM_VALIDATE + LDY #$01 +.ENDIF + LDY #$00 ; SET COPY POINTERS + LDA (GCBEST),Y + AND #$F8 + STA SRCADDR + CLC ; ADD SIZE OF FREE BLOCK + ADC (GCMPTR),Y ; FOR DESTINATION + STA DSTADDR + INY + LDA (GCBEST),Y + STA SRCADDR+1 + ADC (GCMPTR),Y + STA DSTADDR+1 + BNE MOVEBLOCKS +XCHNGBEST: +.IFDEF DEBUG_GC + AUXZP_ACCESS_OFF + JSR PUTS + .ASCIIZ "EXCHANGING BEST " + AUXZP_ACCESS_ON + LDA GCBEST+1 + LDX GCBEST + AUXZP_ACCESS_OFF + JSR PRNTAX + JSR PUTS + .ASCIIZ " WITH " + AUXZP_ACCESS_ON + LDA GCHNDL+1 + LDX GCHNDL + AUXZP_ACCESS_OFF + JSR PRNTAX + JSR CROUT + AUXZP_ACCESS_ON +.ENDIF +.IFDEF DEBUG_MEMMGR + LDA GCBEST + LDX GCBEST+1 + JSR HMEM_VALIDATE +.ENDIF +.IF 0 + AUXZP_ACCESS_OFF + LDA #$80|'^' + JSR COUT + AUXZP_ACCESS_ON +.ENDIF + LDY #$00 ; SET COPY POINTERS + LDA (GCBEST),Y + AND #$F8 + STA SRCADDR + LDA GCMPTR + STA DSTADDR + INY + LDA (GCBEST),Y + STA SRCADDR+1 + LDA GCMPTR+1 + STA DSTADDR+1 +MOVEBLOCKS: LDY #$00 ; SAVE FREE BLOCK INFO +: LDA (GCMPTR),Y + PHA + INY + CPY #$04 + BNE :- + LDY #$00 ; UPDATE ALLOC BLOCK POINTER + LDA (GCBEST),Y + AND #$07 ; COPY ALLOC FLAGS + ORA DSTADDR + STA (GCBEST),Y + LDA SRCADDR + STA (GCHNDL),Y ; UPDATE FREE BLOCK POINTER + STA GCMPTR + INY + LDA DSTADDR+1 + STA (GCBEST),Y + LDA SRCADDR+1 + STA (GCHNDL),Y + STA GCMPTR+1 + LDA (SRCADDR),Y ; SIZE OF ALLOCED BLOCK TO MOVE + DEY + TAX + LDA (SRCADDR),Y + JSR MEMCPY ; MOVE ALLOCED BLOCK UP + LDY #$03 ; RESTORE FREE BLOCK INFO +: PLA + STA (GCMPTR),Y + DEY + BPL :- +.IFDEF DEBUG_MEMMGR + LDA GCBEST + LDX GCBEST+1 + JSR HMEM_VALIDATE + JSR HFREE_VALIDATE +.ENDIF + AUXZP_ACCESS_OFF + CLC + RTS +.IFDEF DEBUG +;* +;* PRINT AVAIL RAM TO SCREEN +;* +PRNTRAM: LDA RAMAVAIL+1 + LSR + LSR + LSR + LSR + CLC + ADC #'0' + CMP #'9'+1 + BCC :+ + ADC #'A'-'9'-2 +: ORA #$80 + STA $0424 + LDA RAMAVAIL+1 + AND #$0F + CLC + ADC #'0' + CMP #'9'+1 + BCC :+ + ADC #'A'-'9'-2 +: ORA #$80 + STA $0425 + LDA RAMAVAIL + LSR + LSR + LSR + LSR + CLC + ADC #'0' + CMP #'9'+1 + BCC :+ + ADC #'A'-'9'-2 +: ORA #$80 + STA $0426 + LDA RAMAVAIL + AND #$0F + CLC + ADC #'0' + CMP #'9'+1 + BCC :+ + ADC #'A'-'9'-2 +: ORA #$80 + STA $0427 + RTS +.ENDIF +;* +;* VALIDATE HANDLE/POINTER +;* +.IFDEF DEBUG_MEMMGR +HNDL_SAVE: .WORD $0000 +HMEM_VALIDATE: PHA + TXA + PHA + TYA + PHA + LDA HNDL + STA HNDL_SAVE + LDA HNDL+1 + STA HNDL_SAVE+1 + LDX #>HTBL + LDA #HTBL_END + BCC HTBLVLP + LDA HNDL_SAVE + STA HNDL + LDA HNDL_SAVE+1 + STA HNDL+1 + PLA + TAY + PLA + TAX + PLA + RTS +HNDL_VALIDATE: + STA $70 + STX $71 + CPX #>HTBL + BCC BADHNDL + CPX #>HTBL_END + BCS BADHNDL + LSR + BCS BADHNDL + LDY #$01 + LDA ($70),Y + DEY + TAX + LDA ($70),Y + TAY + AND #$07 + CMP #$07 + BNE :+ + RTS ; HANDLE SWAPPED OUT +: TYA + AND #$F8 + CPX #>INIT_START + BCC BADHNDL + BNE :+ + CMP #TOPOFHEAP + BCS BADHNDL + TYA + LSR + BCC BADHNDL + TYA + AND #$F8 + STA $72 + STX $73 + LDY #$01 ; CHECK FENCE + LDA ($72),Y + DEY + TAX + LDA ($72),Y + AND #$07 ; MAKE SURE NO BITS IN 3 LSBS + BNE BADSIZE + LDA ($72),Y + SEC + SBC #$02 + BCS :+ + DEX +: CLC + ADC $72 + STA $72 + TXA + ADC $73 + STA $73 + LDA #$CA + CMP ($72),Y + BNE BADFENCE + INY + LDA #$FE + CMP ($72),Y + BNE BADFENCE + RTS +BADHNDL: AUXZP_ACCESS_OFF + PERR "INVALID MEMORY HANDLE/POINTER:" + JMP PRNTBADHNDL +BADFENCE: AUXZP_ACCESS_OFF + PERR "CORRUPTED FENCE:" + JMP PRNTBADHNDL +BADSIZE: AUXZP_ACCESS_OFF + PERR "INVALID SIZE:" +PRNTBADHNDL: LDA $71 + LDX $70 + JSR PRNTAX + LDA #'/' + JSR COUT + AUXZP_ACCESS_ON + LDY #$00 + LDA ($70),Y + INY + TAX + LDA ($70),Y + AUXZP_ACCESS_OFF + JSR PRNTAX + JSR CROUT + JSR CHKDBLALLOC + JSR KBWAIT + JSR HMEM_DUMP + LDA BADHNDLBRK ; STOP RECURSIVE BAD HANDLES + BEQ :+ + DEC BADHNDLBRK + JMP THROW_INTERNALERR +: BRK +CHKDBLALLOC: LDX #>HTBL ; CHECK FOR DOUBLY LINKED BLOCKS + LDA #HTBL_END + BCC CHKDBLALCLP + RTS +DBLALCERR: LDA $71 + LDX $70 + AUXZP_ACCESS_OFF + JSR PRNTAX + PERR " DOUBLEY ALLOCATED WITH " + AUXZP_ACCESS_ON + LDA $75 + LDX $74 + AUXZP_ACCESS_OFF + JSR PRNTAX + JSR CROUT + JMP PRNTBADHNDL +BADHNDLBRK: .BYTE $01 +HFREEBAK: .WORD $0000 +HFREE_VALIDATE: LDA HFREE + CMP HFREEBAK + BNE BADFREE + STA $70 + LDX HFREE+1 + CPX HFREEBAK+1 + BNE BADFREE + STX $71 +VALFREE: CPX #$00 + BEQ VALFREEDONE + CPX #>HTBL ; MAKE SURE HANDLE IS IN THE TABLE RANGE + BCC BADFREE + CPX #>HTBL_END + BCS BADFREE + AND #$01 ; CHECK ALLOCATED BIT (LSB) + BNE BADFREE + LDY #$01 + LDA ($70),Y + DEY + TAX + LDA ($70),Y + AND #$F8 + CPX #>INIT_START ; CHECK MEMORY POINTER IS IN VALID RANGE + BCC BADFREE + BNE :+ + CMP #HTBL + BCC :+ + BEQ :+ + JMP BADFREE + CMP #" + AUXZP_ACCESS_ON + LDY #$00 + LDA (HNDL),Y + INY + STA MPTR + TAX + LDA (HNDL),Y + STA MPTR+1 + AUXZP_ACCESS_OFF + JSR PRNTAX + JSR PUTS + .ASCIIZ ": LEN:" + AUXZP_ACCESS_ON + LDY #$00 + LDA (MPTR),Y + INY + TAX + LDA (MPTR),Y + AUXZP_ACCESS_OFF + JSR PRNTAX + JSR PUTS + .ASCIIZ " NEXT:" + AUXZP_ACCESS_ON + LDY #$02 + LDA (MPTR),Y + INY + TAX + STA HNDL + LDA (MPTR),Y + STA HNDL+1 + AUXZP_ACCESS_OFF + JSR PRNTAX + JSR CROUT + AUXZP_ACCESS_ON + JMP FREE_DUMP +FREE_DONE: LDA #HTBL + STA HNDL+1 + AUXZP_ACCESS_OFF + JSR PUTSLN + .ASCIIZ "ALLOCATED BLOCKS" + JSR PUTSLN + .ASCIIZ "----------------" + AUXZP_ACCESS_ON + LDA #$00 + STA MLEN ; ZERO TOTAL ALLOCATED + STA MLEN+1 +ALLOC_DUMP: LDY #$00 ; MAKE UNUSED HANDLE LIST + LDA (HNDL),Y + AND #$01 + BNE :+ + JMP NEXT_ADUMP ; NOT ALLOCATED +: LDX HNDL + LDA HNDL+1 + AUXZP_ACCESS_OFF + JSR PRNTAX + JSR PUTS + .ASCIIZ "->" + AUXZP_ACCESS_ON + LDY #$00 + LDA (HNDL),Y + AND #$07 + CMP #$07 + BNE :+ + JSR PUTSLN + .ASCIIZ "SWAPPED OUT" + JMP NEXT_ADUMP +: LDA (HNDL),Y + INY + TAX + AND #$F8 + STA MPTR + LDA (HNDL),Y + STA MPTR+1 + AUXZP_ACCESS_OFF + JSR PRNTAX + JSR PUTS + .ASCIIZ ": LEN:" + AUXZP_ACCESS_ON + LDY #$00 + LDA (MPTR),Y + INY + TAX + CLC ; ADD TO TOTAL + ADC MLEN + STA MLEN + LDA (MPTR),Y + ADC MLEN+1 + STA MLEN+1 + LDA (MPTR),Y + AUXZP_ACCESS_OFF + JSR PRNTAX + JSR PUTS + .ASCIIZ " REF:" + AUXZP_ACCESS_ON + LDY #$02 + LDA (MPTR),Y + INY + TAX + LDA (MPTR),Y + AUXZP_ACCESS_OFF + JSR PRNTAX + JSR CROUT +NEXT_ADUMP: AUXZP_ACCESS_ON + LDA HNDL + CLC + ADC #$02 + STA HNDL + BEQ :+ + JMP ALLOC_DUMP +: INC HNDL+1 + LDA HNDL+1 + CMP #>HTBL_END + BEQ :+ + JMP ALLOC_DUMP +: AUXZP_ACCESS_OFF + JSR CROUT + JSR PUTS + .ASCIIZ "TOTAL ALLOCATED:$" + AUXZP_ACCESS_ON + LDA MLEN+1 + LDX MLEN + AUXZP_ACCESS_OFF + JSR PRNTAX + JSR CROUT + RTS +.ENDIF \ No newline at end of file diff --git a/src/mousedrvr.s b/src/mousedrvr.s new file mode 100755 index 0000000..23ace30 --- /dev/null +++ b/src/mousedrvr.s @@ -0,0 +1,165 @@ +;* +;* MOUSE DEVICE DRIVER +;* +MOUSE_INIT: ORA #$C0 + STA XREGMOUSE1+1 + STA XREGMOUSE2+1 + ASL + ASL + ASL + ASL + STA YREGMOUSE1+1 + STA YREGMOUSE2+1 + LDA #$00 + PHA ; DISABLE ALL MOUSE INTS + LDX #$12 ; FW INDEX FOR SETMOUSE + BNE CALLMOUSEFW +MOUSE_DRIVER: +MOUSE_DRVR_SZ: .WORD MOUSE_DRVR_END - MOUSE_DRVR_START +MOUSE_READ_OFS: .WORD MOUSE_READ - MOUSE_DRVR_START +MOUSE_WRITE_OFS: .WORD MOUSE_WRITE - MOUSE_DRVR_START +MOUSE_CTRL_OFS: .WORD MOUSE_CTRL - MOUSE_DRVR_START +MOUSE_IRQ_OFS: .WORD MOUSE_IRQ - MOUSE_DRVR_START +MOUSE_DRVR_START: +MOUSE_READ: +MOUSE_WRITE: SEC + RTS +MOUSE_X: .WORD $0000 +MOUSE_Y: .WORD $0000 +MOUSE_STATUS: .BYTE $00 +MOUSE_CTRL: PHA + TYA + AND #$F8 ; MASK OFF SLOT # + CMP #MOUSECTL_CALLFW + BNE :+ +CALLMOUSEFW: STX OPADDR +XREGMOUSE2: LDX #$C4 + STX OPADDR+1 + LDY #$00 + LDA (OPADDR),Y ; GET ENTRYPOINT OFFSET + STA OPADDR +YREGMOUSE2: LDY #$40 + PLA + SEI + JMP (OPADDR) ; CALL FIXED UP FUNCTION POINTER +: CMP #MOUSECTL_READMOUSE ; COPY MOUSE STATUS/POSITION INTO EASILY ACCESSIBLE MEMORY + BNE :+ + PLA + TYA + AND #$07 + TAX ; SAVE MOUSE PARAMETERS + ASL + TAY + LDA LINK_DEVREAD,Y + STA TMPTR + LDA LINK_DEVREAD+1,Y + STA TMPTR+1 + SEI + LDY #$02 + LDA $0478,X + STA (TMPTR),Y + PHA + INY + LDA $0578,X + STA (TMPTR),Y + INY + LDA $04F8,X + STA (TMPTR),Y + PHA + INY + LDA $05F8,X + STA (TMPTR),Y + INY + LDA $0778,X + STA (TMPTR),Y + STA TMP + PLA + TAY + PLA + TAX + LDA TMP + RTS +: CMP #MOUSECTL_CLAMPX + BEQ :+ + CMP #MOUSECTL_CLAMPY + BNE :++ +: PLA + STA $04F8 + STX $05F8 + LDA #$00 + STA $0478 + STA $0578 + TYA + LSR + LSR + LSR + AND #$01 + PHA + LDX #$17 ; FW INDEX FOR CLAMPMOUSE + BNE CALLMOUSEFW +SETMOUSE: PHA + LDX #$12 ; FW INDEX FOR SETMOUSE + BNE CALLMOUSEFW +: PLA + TYA + AND #$F8 ; MASK OFF SLOT # + CMP #IOCTL_OPEN + BNE :+ + LDA #THREAD_YIELD + STA LINK_YIELD+1 + LDA #$0F ; TURN MOUSE INTS ON + BNE SETMOUSE +: CMP #IOCTL_CLOSE + BNE :+ + LDA #$08 ; TURN MOUSE OFF + BNE SETMOUSE +: CMP #IOCTL_DEACTIVATE + BNE :+ + LDA #MOUSECTL_NOIRQ +: CMP #MOUSECTL_NOIRQ ; UNINSTALL IRQ HANDLER + BNE :+ + SEI + LDA #SW_TIMER + STA LINK_YIELD+1 + BNE SETMOUSE +: CMP #IOCTL_ID + BEQ :+ + SEC + RTS +: LDA #$20 ; MOUSE ID + CLC + RTS +; +; VBLANK TIMER AND MOUSE IRQ +; +MOUSE_IRQ: STA TMP +SERVEMOUSE: JSR $C400 + BCS VBLEXIT ; NOT MOUSE INT + LDY TMP ; CHECK MOUSE INT CAUSE + LDA $0778,Y + PHA + AND #$08 ; WAS IT VLB? + BEQ MOUSEEXIT ; NOPE, MOVE OR BUTTON +VBLTIC: LDX #$00 + LDA #$11 ; 17 MSEC (2/3 OF THE TIME) + DEC TIMERADJUST + BNE :+ + LDA #$02 + STA TIMERADJUST + LDA #$10 ; 16 MSEC (1/3 OF THE TIME) +: JSR SYSTEM_TIC +MOUSEEXIT: PLA + AND #$86 ; MOUSE MOVE OR BUTTON ACTIVE + BEQ VBLEXIT +XREGMOUSE1: LDX #$C4 +YREGMOUSE1: LDY #$40 +READMOUSE: JSR $C400 ; IIGS REQUIRES THIS HAPPEN IN IRQ + CLC + RTS +VBLEXIT: SEC + RTS +MOUSE_DRVR_END EQU * diff --git a/src/object.clasm b/src/object.clasm new file mode 100755 index 0000000..39b9d96 --- /dev/null +++ b/src/object.clasm @@ -0,0 +1,453 @@ +;* +;* CLASS FILE _Object.class +;* + .BYTE $CA,$FE,$BA,$BE ; MAGIC + .BYTE $00,$00 ; MINOR 0 + .BYTE $00,$31 ; MAJOR 49 +;* +;* CONSTANT POOL +;* + .BYTE $00,$1A ; CONST POOL COUNT 26 +;* CONST POOL INDEX 1 + .BYTE $0A ; METHODREF + .BYTE $00,$03 ; CLASS #3 + .BYTE $00,$17 ; NAME AND TYPE #23 +;* CONST POOL INDEX 2 + .BYTE 07 ; CLASS + .BYTE $00,$19 ; #25 +;* CONST POOL INDEX 3 + .BYTE 07 ; CLASS + .BYTE $00,$00 ; #0 +;* CONST POOL INDEX 4 + .BYTE $01 ; UTF8 + .BYTE $00,$06 ; STRLEN + .BYTE "" +;* CONST POOL INDEX 5 + .BYTE $01 ; UTF8 + .BYTE $00,$03 ; STRLEN + .BYTE "()V" +;* CONST POOL INDEX 6 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "Code" +;* CONST POOL INDEX 7 + .BYTE $01 ; UTF8 + .BYTE $00,$05 ; STRLEN + .BYTE "clone" +;* CONST POOL INDEX 8 + .BYTE $01 ; UTF8 + .BYTE $00,$14 ; STRLEN + .BYTE "()Ljava/lang/Object;" +;* CONST POOL INDEX 9 + .BYTE $01 ; UTF8 + .BYTE $00,$06 ; STRLEN + .BYTE "equals" +;* CONST POOL INDEX 10 + .BYTE $01 ; UTF8 + .BYTE $00,$15 ; STRLEN + .BYTE "(Ljava/lang/Object;)Z" +;* CONST POOL INDEX 11 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "finalize" +;* CONST POOL INDEX 12 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "getClass" +;* CONST POOL INDEX 13 + .BYTE $01 ; UTF8 + .BYTE $00,$13 ; STRLEN + .BYTE "()Ljava/lang/Class;" +;* CONST POOL INDEX 14 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "hashCode" +;* CONST POOL INDEX 15 + .BYTE $01 ; UTF8 + .BYTE $00,$03 ; STRLEN + .BYTE "()I" +;* CONST POOL INDEX 16 + .BYTE $01 ; UTF8 + .BYTE $00,$06 ; STRLEN + .BYTE "notify" +;* CONST POOL INDEX 17 + .BYTE $01 ; UTF8 + .BYTE $00,$09 ; STRLEN + .BYTE "notifyAll" +;* CONST POOL INDEX 18 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "toString" +;* CONST POOL INDEX 19 + .BYTE $01 ; UTF8 + .BYTE $00,$14 ; STRLEN + .BYTE "()Ljava/lang/String;" +;* CONST POOL INDEX 20 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "wait" +;* CONST POOL INDEX 21 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "(J)V" +;* CONST POOL INDEX 22 + .BYTE $01 ; UTF8 + .BYTE $00,$05 ; STRLEN + .BYTE "(JI)V" +;* CONST POOL INDEX 23 + .BYTE $0C ; NAME AND TYPE + .BYTE $00,$04 ; NAME #4 + .BYTE $00,$05 ; DESC #5 +;* CONST POOL INDEX 24 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "6502" +;* CONST POOL INDEX 25 + .BYTE $01 ; UTF8 + .BYTE $00,$10 ; STRLEN + .BYTE "java/lang/Object" +;* +;* ACCESS FLAGS +;* + .BYTE $00,$21 ; 0x0021 +;* +;* THIS CLASS +;* + .BYTE $00,$02 ; #2 +;* +;* SUPER CLASS +;* + .BYTE $00,$00 ; #0 +;* +;* INTERFACES +;* + .BYTE $00,$00 ; IFACE COUNT 0 +;* +;* FIELDS +;* + .BYTE $00,$00 ; FIELD COUNT 0 +;* +;* METHODS +;* + .BYTE $00,$0C ; METHOD COUNT 12 +;******* METHOD INDEX 0 ******** + .BYTE $01,$01 ; ACCESS FLAGS 0x0101 + .BYTE $00,$04 ; NAME #4 + .BYTE $00,$05 ; DESC #5 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,24 ; NAME #24 + .BYTE $00,$00,>(M0A0END-M0A0BGN),<(M0A0END-M0A0BGN) +M0A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M0C0END-M0C0BGN),<(M0C0END-M0C0BGN) +M0C0BGN: +.IFDEF DEBUG_FINALIZE +; PSTRLN "HELLO FROM OBJECT." +.ENDIF + TSX + LDA $0103,X + CMP $0107,X + BNE :+ + TAY + LDA $0104,X + CMP $0108,X + BNE :+ + STA TMP + LDA $0106,X + CMP $010A,X + BNE :+ + LDA $0105,X + CMP $0109,X + BNE :+ + BMI :+ ; SKIP IF NOREF INC FLAG ALREADY SET + ORA #$80 ; SET REF COUNT FLAG + STA $0109,X + LDA $0101,X ; POP *THIS* + STA $0105,X + LDA $0102,X + STA $0106,X + INX + INX + INX + INX + TXS + TYA + LDX TMP + JMP HMEM_REF_INC +: PLA + TAX + PLA + TAY + PLA + PLA + PLA + PLA + TYA + PHA + TXA + PHA + RTS +M0C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M0A0END: +;******* METHOD INDEX 1 ******** + .BYTE $00,$04 ; ACCESS FLAGS 0x0004 + .BYTE $00,$07 ; NAME #7 + .BYTE $00,$08 ; DESC #8 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$00,>(M1A0END-M1A0BGN),<(M1A0END-M1A0BGN) +M1A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M1C0END-M1C0BGN),<(M1C0END-M1C0BGN) +M1C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M1C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M1A0END: +;******* METHOD INDEX 2 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$09 ; NAME #9 + .BYTE $00,$0A ; DESC #10 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$00,>(M2A0END-M2A0BGN),<(M2A0END-M2A0BGN) +M2A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M2C0END-M2C0BGN),<(M2C0END-M2C0BGN) +M2C0BGN: + .BYTE $04 ; 00000: iconst_1 + .BYTE $AC ; 00001: ireturn +M2C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M2A0END: +;******* METHOD INDEX 3 - finalize ******** + .BYTE $01,$04 ; ACCESS FLAGS 0x0104 + .BYTE $00,$0B ; NAME #11 + .BYTE $00,$05 ; DESC #5 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,24 ; NAME #24 + .BYTE $00,$00,>(M3A0END-M3A0BGN),<(M3A0END-M3A0BGN) +M3A0BGN: +;* CODE: + .BYTE $00,$00 ; MAX STACK 0 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M3C0END-M3C0BGN),<(M3C0END-M3C0BGN) +M3C0BGN: +.IFDEF DEBUG_FINALIZE + PSTRLN "HELLO FROM OBJECT.FINALIZE()" +.ENDIF + PLA + TAX + PLA + TAY + PLA + PLA + PLA + PLA + TYA + PHA + TXA + PHA + RTS +M3C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M3A0END: +;******* METHOD INDEX 4 ******** + .BYTE $00,$11 ; ACCESS FLAGS 0x0011 + .BYTE $00,$0C ; NAME #12 + .BYTE $00,$0D ; DESC #13 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$00,>(M4A0END-M4A0BGN),<(M4A0END-M4A0BGN) +M4A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M4C0END-M4C0BGN),<(M4C0END-M4C0BGN) +M4C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M4C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M4A0END: +;******* METHOD INDEX 5 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$0E ; NAME #14 + .BYTE $00,$0F ; DESC #15 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$00,>(M5A0END-M5A0BGN),<(M5A0END-M5A0BGN) +M5A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M5C0END-M5C0BGN),<(M5C0END-M5C0BGN) +M5C0BGN: + .BYTE $03 ; 00000: iconst_0 + .BYTE $AC ; 00001: ireturn +M5C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M5A0END: +;******* METHOD INDEX 6 ******** + .BYTE $00,$11 ; ACCESS FLAGS 0x0011 + .BYTE $00,$10 ; NAME #16 + .BYTE $00,$05 ; DESC #5 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$00,>(M6A0END-M6A0BGN),<(M6A0END-M6A0BGN) +M6A0BGN: +;* CODE: + .BYTE $00,$00 ; MAX STACK 0 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M6C0END-M6C0BGN),<(M6C0END-M6C0BGN) +M6C0BGN: + .BYTE $B1 ; 00000: return +M6C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M6A0END: +;******* METHOD INDEX 7 ******** + .BYTE $00,$11 ; ACCESS FLAGS 0x0011 + .BYTE $00,$11 ; NAME #17 + .BYTE $00,$05 ; DESC #5 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$00,>(M7A0END-M7A0BGN),<(M7A0END-M7A0BGN) +M7A0BGN: +;* CODE: + .BYTE $00,$00 ; MAX STACK 0 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M7C0END-M7C0BGN),<(M7C0END-M7C0BGN) +M7C0BGN: + .BYTE $B1 ; 00000: return +M7C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M7A0END: +;******* METHOD INDEX 8 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$12 ; NAME #18 + .BYTE $00,$13 ; DESC #19 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$00,>(M8A0END-M8A0BGN),<(M8A0END-M8A0BGN) +M8A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M8C0END-M8C0BGN),<(M8C0END-M8C0BGN) +M8C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M8C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M8A0END: +;******* METHOD INDEX 9 ******** + .BYTE $00,$11 ; ACCESS FLAGS 0x0011 + .BYTE $00,$14 ; NAME #20 + .BYTE $00,$05 ; DESC #5 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$00,>(M9A0END-M9A0BGN),<(M9A0END-M9A0BGN) +M9A0BGN: +;* CODE: + .BYTE $00,$00 ; MAX STACK 0 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M9C0END-M9C0BGN),<(M9C0END-M9C0BGN) +M9C0BGN: + .BYTE $B1 ; 00000: return +M9C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M9A0END: +;******* METHOD INDEX 10 ******** + .BYTE $00,$11 ; ACCESS FLAGS 0x0011 + .BYTE $00,$14 ; NAME #20 + .BYTE $00,$15 ; DESC #21 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$00,>(M10A0END-M10A0BGN),<(M10A0END-M10A0BGN) +M10A0BGN: +;* CODE: + .BYTE $00,$00 ; MAX STACK 0 + .BYTE $00,$03 ; MAX LOCALS 3 + .BYTE $00,$00,>(M10C0END-M10C0BGN),<(M10C0END-M10C0BGN) +M10C0BGN: + .BYTE $B1 ; 00000: return +M10C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M10A0END: +;******* METHOD INDEX 11 ******** + .BYTE $00,$11 ; ACCESS FLAGS 0x0011 + .BYTE $00,$14 ; NAME #20 + .BYTE $00,$16 ; DESC #22 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$00,>(M11A0END-M11A0BGN),<(M11A0END-M11A0BGN) +M11A0BGN: +;* CODE: + .BYTE $00,$00 ; MAX STACK 0 + .BYTE $00,$04 ; MAX LOCALS 4 + .BYTE $00,$00,>(M11C0END-M11C0BGN),<(M11C0END-M11C0BGN) +M11C0BGN: + .BYTE $B1 ; 00000: return +M11C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M11A0END: +;* +;* GLOBAL ATTRIBUTES +;* + .BYTE $00,$00 ; ATTRIB COUNT 0 diff --git a/src/ops.s b/src/ops.s new file mode 100755 index 0000000..d646d87 --- /dev/null +++ b/src/ops.s @@ -0,0 +1,3528 @@ +;* +;* JAVA OPCODE INTERPRETER FOR 6502 +;* + .INCLUDE "global.inc" + .INCLUDE "class.inc" + .INCLUDE "frame.inc" + .IMPORT COUT,CROUT,PRBYTE,MEMSRC,MEMDST,MEMCPY,MEMCLR + .IMPORT THREAD_LOCK,THREAD_UNLOCK + .IMPORT HMEM_ALLOC,HMEM_ALLOC_FIXED,HMEM_FREE,HMEM_LOCK,HMEM_UNLOCK,HMEM_UNLOCK_CODE + .IMPORT HMEM_PTR,HMEM_REF_INC,HMEM_REF_DEC,HMEM_CLR + .IMPORT HSTR_HASH,STR_HASH,HSTRPL_ADD,HSTRPL_DEL + .IMPORT HCLASS_NAME,HCLASS_HNDL,HCLASS_ADD,HCLASS_INDEX,RESOLVE_CLASS,CLASS_OF + .IMPORT CLASS_MATCH_NAME,CLASS_MATCH_DESC,RESOLVE_METHOD,CLASS_METHODPTR,RESOLVE_FIELD,CLASS_FIELDPTR + .IMPORT UNREF_OBJECT,WARM_INIT + .IMPORT INVOKE_VIRTUAL,INVOKE_STATIC,INVOKE_SPECIAL,EXIT_METHOD,CATCH_EXCEPTN + .IMPORT THROW_SYSEXCEPTN,THROW_INTERNALERR,CURRENTEXCEPTN + .EXPORT SCANDESCPARMS,EXECBYTECODES,LOOKUPCLASSIDX,SYSTHROW,INTERP_INIT,INTERP_END + +.IFDEF BIGMEM +.MACRO LDB_BYTECODE + JSR READBYTECODEB +.ENDMACRO +.MACRO LDW_BYTECODE + JSR READBYTECODEW +.ENDMACRO + +.ELSE ; BIGMEM +.MACRO LDB_BYTECODE + LDA (EXECPC),Y +.ENDMACRO +.MACRO LDW_BYTECODE + LDA (EXECPC),Y + INY + TAX + LDA (EXECPC),Y +.ENDMACRO +.ENDIF + + .CODE +;* +;* CLASS HELPER ROUTINES +;* +SETCONSTPTR: CALC_CONSTPLRECSZ + CLC + ADC EXECCONSTPL + STA CONSTPTR + TXA + ADC EXECCONSTPL+1 + STA CONSTPTR+1 + RTS +GETCONSTB: JSR SETCONSTPTR + LDA (CONSTPTR),Y + RTS +GETCONSTW: JSR SETCONSTPTR + LDA (CONSTPTR),Y + INY + TAX + LDA (CONSTPTR),Y + RTS +; +; LOOKUP CLASS REFERENCE IN CONSTPOOL - CONSPTR PROBALY TRASHED +; +LOOKUPCLASSREF: LDY #$01 ; GET CLASS INDEX + LDA (CONSTPTR),Y + INY + TAX + LDA (CONSTPTR),Y +; +; LOOKUP CLASS INDEX IN CONST POOL +; +LOOKUPCLASSIDX: STA CCLASSINDEX ; SAVE CLASS INDEX + STX CCLASSINDEX+1 + LDY #$01 + JSR GETCONSTB + BPL :+ + INY + LDA (CONSTPTR),Y ; CLASS ALREADY LINKED + INY + STA TARGETCLASS + LDA (CONSTPTR),Y + INY + TAX + LDA (CONSTPTR),Y + LDY TARGETCLASS + RTS +: LDA CCLASSINDEX + PHA + LDA CCLASSINDEX+1 + PHA + LDY #$03 ; GET CLASS NAME INDEX + LDA (CONSTPTR),Y + INY + TAX + LDA (CONSTPTR),Y + DEY ; LDY #$03 ; GET CLASS NAME + JSR GETCONSTW + JSR RESOLVE_CLASS + BCS :+ + STY TARGETCLASS + STA CCINST ; STEAL CLASS CLASS VAR FOR A SEC + STX CCINST+1 + PLA ; RESTORE CLASS INDEX + TAX + PLA + JSR SETCONSTPTR + LDA CCINST + LDY #$04 ; SAVE LINKED CLASS + STA (CONSTPTR),Y ; HANDLE TO CLASS + DEY + LDA CCINST+1 + TAX + STA (CONSTPTR),Y + DEY + LDA TARGETCLASS ; INDEX TO CLASS + STA (CONSTPTR),Y + DEY + LDA #$80 + STA (CONSTPTR),Y + LDA CCINST + LDY TARGETCLASS + RTS +: +.IFDEF DEBUG + .IMPORT PRSTR + STA TMPTR + STX TMPTR+1 + LDY #$03 ; GET CLASS NAME + LDA (TMPTR),Y + INY + TAX + LDA (TMPTR),Y + JSR PRSTR + LDA #':' + JSR COUT + PERR "UNABLE TO RESOLVE CLASS" +.ENDIF + JMP RETHROW +; +; LOOKUP REFERENCE NAME/TYPE +; +LOOKUPREF: LDY #$04 + JSR GETCONSTB ; GET NAME/TYPE + DEY + PHA ; SAVE TYPE INDEX ON STACK + LDA (CONSTPTR),Y + PHA + LDY #$01 ; GET NAME INDEX + LDA (CONSTPTR),Y + INY + TAX + LDA (CONSTPTR),Y + LDY #$03 + JSR GETCONSTW ; GET NAME + JSR CLASS_MATCH_NAME ; SAVE MATCH NAME + PLA ; RETRIEVE TYPE INDEX FROM STACK + TAX + PLA + LDY #$03 + JSR GETCONSTW ; GET TYPE + JSR CLASS_MATCH_DESC ; SAVE MATCH TYPE + LDY TARGETCLASS + RTS +; +; GET POINTER TO FIELDS +; +GETFIELDPTR: STA CCLASSINDEX ; SAVE REF INDEX + STX CCLASSINDEX+1 + LDY #$01 + JSR GETCONSTB ; MSB MEANS ALREADY LINKED + BMI FLDLNK + LDA CCLASSINDEX + PHA + LDA CCLASSINDEX+1 + PHA + LDY #$04 ; GET FIELD NAME/TYPE INDEX + LDA (CONSTPTR),Y + DEY + PHA + LDA (CONSTPTR),Y + PHA + JSR LOOKUPCLASSREF + PLA + TAX + PLA + JSR LOOKUPREF ; LOOKUP FIELD IN CONSTPTR + JSR RESOLVE_FIELD + BCC :+ + LDA #10 ; NO SUCH FIELD + JMP SYSTHROW +: STY TARGETCLASS + STA CCINST ; STEAL CLASS CLASS VAR FOR A SEC + STX CCINST+1 + PLA ; RESTORE CLASS INDEX + TAX + PLA + JSR SETCONSTPTR + LDA CCINST + LDY #$04 ; SAVE LINKED CLASS/FIELD OFFSET + STA (CONSTPTR),Y + DEY + LDA CCINST+1 + STA (CONSTPTR),Y + DEY + LDA TARGETCLASS + STA (CONSTPTR),Y + DEY + LDA #$80 + STA (CONSTPTR),Y +FLDLNK: INY + LDA (CONSTPTR),Y + INY + STA TARGETCLASS + LDA (CONSTPTR),Y + INY + TAX + LDA (CONSTPTR),Y + LDY TARGETCLASS + JSR CLASS_FIELDPTR + STA FIELDPTR + STX FIELDPTR+1 + RTS +; +; GET POINTER TO METHOD +; +GETMETHODPTR: STA CCLASSINDEX ; SAVE REF INDEX + STX CCLASSINDEX+1 + LDY #$01 + JSR GETCONSTB ; MSB MEANS ALREADY LINKED + BMI MTHDLNK + LDA CCLASSINDEX + PHA + LDA CCLASSINDEX+1 + PHA + LDY #$04 ; GET METHOD NAME/TYPE INDEX + LDA (CONSTPTR),Y + DEY + PHA + LDA (CONSTPTR),Y + PHA + JSR LOOKUPCLASSREF + PLA + TAX + PLA + JSR LOOKUPMETHODREF + STY TARGETCLASS ; MAY BE SUPERCLASS OF CLASS REF + STA CCINST ; STEAL CLASS CLASS VAR FOR A SEC + STX CCINST+1 + PLA ; RESTORE CLASS INDEX + TAX + PLA + JSR SETCONSTPTR + LDA CCINST + LDY #$04 ; SAVE LINKED CLASS/METHOD OFFSET + STA (CONSTPTR),Y + DEY + LDA CCINST+1 + STA (CONSTPTR),Y + DEY + LDA TARGETCLASS + STA (CONSTPTR),Y + DEY + LDA #$80 + STA (CONSTPTR),Y +MTHDLNK: INY + LDA (CONSTPTR),Y + INY + STA TARGETCLASS + LDA (CONSTPTR),Y + INY + TAX + LDA (CONSTPTR),Y + LDY TARGETCLASS + RTS +; +; SCAN DESCRIPTOR STRING FOR PARAM COUNT +; +SCANDESCPARMS: JSR HMEM_PTR ; GET POINTER TO DESC STRING + STA TMPTR + STX TMPTR+1 + LDX #$00 + LDY #$02 ; BETTER START WITH '(' +SCANDP_LP: LDA (TMPTR),Y + INY + CMP #')' + BEQ SCANDP_DONE + INX ; INC PARAM COUNT + CMP #'L' + BEQ SCANDP_REF + CMP #'[' + BNE SCANDP_LP +SCANDP_ARRAY: LDA (TMPTR),Y + INY + CMP #'[' + BEQ SCANDP_ARRAY ; EAT ARRAY + CMP #'L' + BNE SCANDP_LP ; FALL THROUGH FOR ARRAY OBJECTS +SCANDP_REF: LDA (TMPTR),Y + INY + CMP #';' + BNE SCANDP_REF + BEQ SCANDP_LP +SCANDP_DONE: TXA + ASL ; CONVERT PARAM COUNT TO BYTE COUNT + ASL + RTS +;* +;* ARRAY ROUTINES +;* +; +; CHECK ARRAY INDEX AND FILL IN OFFSET AND ARRAYPTR +; +CHKSTOREINDEX: INX + INX + INX + INX +CHKINDEX: LDA $0103,X + ORA $0104,X + BNE ARRAYINDEXERR + LDA $0102,X + STA TARGETOFFSET+1 + LDA $0101,X + STA TARGETOFFSET +.IFDEF DEBUG + LDA $0107,X + AND #$7F + CMP #CL_ARRAY + BEQ :+ + LDA #8 ; INCOMPATIBLE CLASS + JMP SYSTHROW +: +.ENDIF + LDA $0105,X ; GET POINTER TO ARRAY DATA + TAY + LDA $0106,X + BEQ NULLARRAYERR + TAX + TYA + JSR HMEM_PTR + STA TMPTR + STX TMPTR+1 + CLC ; SKIP ARRAY LENGTH VALUE + ADC #$02 + BCC :+ + INX +: STA ARRAYPTR + STX ARRAYPTR+1 + LDY #$00 + LDA TARGETOFFSET + CMP (TMPTR),Y + INY + LDA TARGETOFFSET+1 + SBC (TMPTR),Y + BCS ARRAYINDEXERR + RTS +ARRAYINDEXERR: LDA #18 ; INDEX OUT OF BOUNDS + JMP SYSTHROW +NULLARRAYERR: LDA #17 ; NULL POINTER + JMP SYSTHROW +; +; SCAN CLASS STRING FOR ARRAY TYPE INFORMATION +; +SCANARRAYTYPE: LDY #$01 ; LINKED CLASS MUST BE ANEWARRAY + LDA (CONSTPTR),Y + BPL :+ +REFARRAYTYPE: LDA #T_REF ; ANEWARRAY REF TYPE + RTS +: LDY #$03 ; GET TYPE NAME INDEX + LDA (CONSTPTR),Y + INY + TAX + LDA (CONSTPTR),Y + DEY ; GET TYPE NAME + JSR GETCONSTW + JSR HMEM_PTR + STA SCANPTR + STX SCANPTR+1 + LDY #$00 +SCANARRAY: INY + LDA (SCANPTR),Y + CMP #'[' + BEQ SCANARRAY + CPY #$01 + BEQ REFARRAYTYPE + CMP #'B' + BNE :+ + LDA #T_BYTE + RTS +: CMP #'S' + BNE :+ + LDA #T_SHORT + RTS +: CMP #'I' + BNE :+ + LDA #T_INT + RTS +: CMP #'Z' + BNE :+ + LDA #T_BOOLEAN + RTS +: CMP #'C' + BNE :+ + LDA #T_CHAR + RTS +.IFDEF DEBUG +: CMP #'L' + BNE :+ + CMP #'D' + BNE :+ + LDA #22 ; ARRAY STORE + JMP SYSTHROW +.ENDIF +: CMP #'F' + BNE REFARRAYTYPE + LDA #T_FLOAT + RTS +; +; ALLOCATE MULTIDIMENSIONAL ARRAY +; ENTRY: A = DEPTH OF ARRAY TO ALLOC +; X = PC INCREMENT +; Y = ANEWARRAY ADJUST +; +MULTIARRAY_ALLOC: STA TARGETDEPTH + JSR SCANARRAYTYPE + STA TARGETTYPE + TYA ; CALC LAST DIM TO ALLOC + CLC + ADC #$01 + SEC + SBC TARGETDEPTH + ASL + ASL + ASL + ASL + STA ADEPTH + DEY ; GET ARRAY DIMENSION (SCANPOS - 1) + TYA + ASL + ASL + ASL + ASL + ORA TARGETTYPE + STA TARGETTYPE + LDA TARGETDEPTH ; CALC STACK OFFSET TO ARRAY DIM + SEC + SBC #$01 + ASL + ASL + TSX + STX TMP + CLC + ADC TMP + TAX + LDY TARGETTYPE + JSR ALLOC_SUBARRAYS ; RECURSIVELY ALLOCATE ARRAYS + STA TMP + STX TMP+1 + LDA TARGETDEPTH ; POP DIMENSION SIZES OFF STACK + ASL + ASL + TSX + STX TARGETDEPTH + CLC + ADC TARGETDEPTH + TAX + TXS + LDA TARGETTYPE + PHA + LDA #CL_ARRAY|$80 ; SET NO INC REF FLAG + PHA + LDA TMP+1 + PHA + LDA TMP + PHA + LDA #$04 + JMP INCANEXTOP +; +; ALLOCATE SINGLE DIMENSION OF REFERENCE ARRAY +; +REFARRAY_ALLOC: JSR SETCONSTPTR + JSR SCANARRAYTYPE + STA TARGETTYPE + TYA + ASL + ASL + ASL + ASL + ORA TARGETTYPE + TAX + PLA + STA TARGETSIZE + STA TMP + PLA + STA TARGETSIZE+1 + STA TMP+1 + PLA + BNE NEWARRAYERR + PLA + BNE NEWARRAYERR + TXA ; RETRIEVE TYPE + PHA ; PUSH TYPE AS PART OF ARRAY REF + LDA #CL_ARRAY|$80 ; PUSH CLASS AS PART OF ARRAY REF + PHA + CPX #$20 + BCS :+ + JSR ALLOCBASEARRAY ; ALLOC ARRAY OF OBJECTS + TAY + TXA + PHA ; PUSH HANDLE AS PART OF ARRAY REF + TYA + PHA + JMP INC3NEXTOP +: LDA TARGETSIZE ; ALLOC AND CLEAR ARRAY OF ARRAYS + ASL ; MUL BY 2 FOR SIZE + TAY + LDA TARGETSIZE+1 + ROL + BCS NEWARRAYERR + TAX + TYA + CLC + ADC #$02 ; ADD 2 FOR ARRAY LENGTH VALUE + BCC :+ + INX +: LDY #$01 + JSR HMEM_ALLOC + JSR HMEM_CLR + TAY + TXA + PHA ; PUSH ARRAY HANDLE ON STACK + TYA + PHA + JSR HMEM_PTR + STA ARRAYPTR + STX ARRAYPTR+1 + LDY #$01 ; SET ARRAY SIZE + LDA TARGETSIZE+1 + STA (ARRAYPTR),Y + DEY + LDA TARGETSIZE + STA (ARRAYPTR),Y + JMP INC3NEXTOP +; +; ALLOC SIMPLE ARRAY TYPE +; +ARRAY_ALLOC: TAX + PLA + STA TARGETSIZE + STA TMP + PLA + STA TARGETSIZE+1 + STA TMP+1 + PLA + BNE NEWARRAYERR + PLA + BNE NEWARRAYERR + TXA ; RETRIEVE TYPE + ORA #$10 ; SET DIMENSION TO ONE + PHA ; PUSH TYPE AS PART OF ARRAY REF + TAX + LDA #CL_ARRAY|$80 ; PUSH CLASS AS PART OF ARRAY REF + PHA + JSR ALLOCBASEARRAY + TAY + TXA + PHA ; PUSH HANDLE AS PART OF ARRAY REF + TYA + PHA + LDA #$02 + JMP INCANEXTOP +; +; NEW ARRAY ERROR +; +NEWARRAYERR: LDA #21 ; ARRAY SIZE NEG OR TOO BIG + JMP SYSTHROW +; ALLOC SUB ARRAYS +; ENTRY: Y = ARRAY TYPE +; X = STACK OFFSET OF SIZE PARAM +; EXIT: AX = HANDLE TO SUB ARRAY +; +ALLOC_SUBARRAYS: TYA + SEC + SBC #$10 + PHA ; SAVE NEXT ARRAY TYPE = $0104,X + TXA + SEC + SBC #$04 + PHA ; SAVE NEXT DIM SIZE OFFSET = $0103,X + LDA $0102,X ; COPY ARRAY SIZE = $0101,X $0102,X + STA TARGETSIZE+1 + LDA $0101,X + STA TARGETSIZE + TYA ; RETRIEVE ARRAY TYPE + CMP ADEPTH ; CHECK FOR LAST DIM TO ALLOC + BCS ALLOCARRAY2 + CMP #$20 + TAX + PLA + PLA + BCC :+ + LDA #$00 ; NOT FINAL ARRAY TYPE + TAX ; RETURN NULL + RTS +: LDA TARGETSIZE + STA TMP + LDA TARGETSIZE+1 + STA TMP+1 +; +; ALLOC BASE ARRAY +; ENTRY: X = TYPE +; +ALLOCBASEARRAY: TXA + AND #$03 ; CONVERT TYPE TO SIZE SHIFT COUNT + BEQ :+ + TAX +BASEARRAYSHIFT: ASL TMP + ROL TMP+1 + BCS NEWARRAYERR + DEX + BNE BASEARRAYSHIFT +: LDA TMP + LDX TMP+1 + CLC ; ADD ROOM FOR LENGTH WORD + ADC #$02 + BCC :+ + INX +: LDY #$01 ; SET REF COUNT TO 1 + JSR HMEM_ALLOC + JSR HMEM_CLR ; CLEAR INSTANCE MEMORY + STA ARRAYHNDL + STX ARRAYHNDL+1 + JSR HMEM_PTR ; SET SIZE IN ARRAY + STA TMPTR + STX TMPTR+1 + LDY #$00 + LDA TARGETSIZE + STA (TMPTR),Y + INY + LDA TARGETSIZE+1 + STA (TMPTR),Y + LDA ARRAYHNDL + LDX ARRAYHNDL+1 + RTS +ALLOCARRAY2: LDA TARGETSIZE ; ALLOC AND FILL ARRAY OF ARRAYS + ASL ; MUL BY 2 FOR SIZE + TAY + LDA TARGETSIZE+1 + ROL + BCS NEWARRAYERR + TAX + TYA + CLC + ADC #$02 ; ADD 2 FOR ARRAY LENGTH VALUE + BCC :+ + INX +: LDY #$01 + JSR HMEM_ALLOC + PHA ; PUSH ARRAY HANDLE ON STACK + TAY + TXA + PHA + TYA + JSR HMEM_PTR + STA ARRAYPTR + STX ARRAYPTR+1 + LDY #$01 ; SET ARRAY SIZE + LDA TARGETSIZE+1 + PHA ; SET CURRENT ARRAY FILL INDEX TO 0 + STA (ARRAYPTR),Y + DEY + LDA TARGETSIZE + PHA ; SET CURRENT ARRAY FILL INDEX TO 0 + STA (ARRAYPTR),Y + ; + ; LOCALS ON STACK: + ; NEXT ARRAY TYPE = $0106,X + ; NEXT ARRAY SIZE OFFSET = $0105,X + ; ARRAY HANDLE = $0103,X $0104,X + ; CURRENT FILL INDEX = $0101,X $0102,X + ; +FILLARRAY: TSX + LDA $0106,X ; GET NEXT DIM TYPE + TAY + LDA $0105,X ; GET OFFSET TO NEXT DIM SIZE + TAX + JSR ALLOC_SUBARRAYS + STA TARGETOBJ + STX TARGETOBJ+1 + TSX + LDA $0104,X ; RETRIEVE ARRAY HANDLE + TAY + LDA $0103,X + TAX + TYA + JSR HMEM_PTR + STA ARRAYPTR + STX ARRAYPTR+1 + TSX + LDA $0102,X ; RETRIEVE FILL INDEX + STA TMP+1 + LDA $0101,X + TAY + ORA TMP+1 + BNE :+ ; CHECK FOR LAST INDEX + LDA $0104,X ; RETRIEVE ARRAY HANDLE + TAY + LDA $0103,X + STA TMP + TXA + CLC + ADC #$06 + TAX + TXS + TYA + LDX TMP + RTS +: TYA + ASL ; MUL INDEX BY 2 FOR OFFSET + ROL TMP+1 + CLC + ADC ARRAYPTR + STA ARRAYPTR + LDA TMP+1 + ADC ARRAYPTR+1 + STA ARRAYPTR+1 + LDY #$01 + LDA TARGETOBJ+1 + STA (ARRAYPTR),Y + DEY + LDA TARGETOBJ + STA (ARRAYPTR),Y + LDA $0101,X + SEC + SBC #$01 + STA $0101,X + BCS FILLARRAY + LDA $0102,X + SBC #$00 + STA $0102,X + BCS FILLARRAY +.IFDEF DEBUG + PERR "FILL ARRAY END ERR" + JMP THROW_INTERNALERR +.ENDIF +; +; PUSH ARRAY SIZE +; +ARRAYLENGTH: PLA + TAY + PLA + TAX + PLA +.IFDEF DEBUG + AND #$7F + CMP #CL_ARRAY + BEQ :+ + LDA #8 ; INCOMPATIBLE CLASS CHANGE + JMP SYSTHROW +: +.ENDIF + PLA + LDA #$00 + PHA + PHA + TYA + BEQ :+ ; LENGTH OF NULL IS ZERO + JSR HMEM_PTR + STA TMPTR + STX TMPTR+1 + LDY #$01 + LDA (TMPTR),Y + DEY + PHA + LDA (TMPTR),Y + PHA + JMP INCNEXTOP +: PHA + PHA + JMP INCNEXTOP +;* +;* DEBUG VERSION OF OPCODE DISPATCH +;* +.IFDEF DEBUG_INTERP +DEBUGEXEC: PHA + ASL + BCS :+ + TAX + LDA OPLTBL,X + STA OPADDR + LDA OPLTBL+1,X + STA OPADDR+1 + JMP :++ +: TAX + LDA OPHTBL,X + STA OPADDR + LDA OPHTBL+1,X + STA OPADDR+1 + .IMPORT KBWAIT +: PSTR "OPCODE:" + PLA + PHA + JSR PRBYTE + JSR CROUT + JSR KBWAIT + PLA + LDY #$01 + CMP #$80 + JMP (OPADDR) +.ENDIF +;* +;* MOVE FLOATING POINT ROUTINES +;* +.IFDEF FLOATING_POINT +FNEG: TSX + LDA $0104,X + EOR #$80 + STA $0104,X + JMP INCNEXTOP +FSUB: LDA #$80 ; TOGGLE SIGN + BNE :+ +FADD: LDA #$00 +: STA FP2SGN + PLA + STA FP2MAN0 + PLA + STA FP2MAN1 + PLA + CMP #$80 ; SET CARRY FROM MSB + ORA #$80 ; SET HIDDEN BIT + STA FP2MAN2 + PLA + EOR FP2SGN ; TOGGLE SIGN FOR FSUB + ROL + STA FP2EXP + LDA #$00 + STA FPSGN + BCC :+ + SBC FP2MAN0 + STA FP2MAN0 + LDA #$00 + SBC FP2MAN1 + STA FP2MAN1 + LDA #$00 + SBC FP2MAN2 + STA FP2MAN2 + LDA #$FF +: STA FP2MAN3 + PLA + STA FP1MAN0 + PLA + STA FP1MAN1 + PLA + CMP #$80 ; SET CARRY FROM MSB + ORA #$80 ; SET HIDDEN BIT + STA FP1MAN2 + PLA + ROL + STA FP1EXP + LDA #$00 + BCC :+ + SBC FP1MAN0 + STA FP1MAN0 + LDA #$00 + SBC FP1MAN1 + STA FP1MAN1 + LDA #$00 + SBC FP1MAN2 + STA FP1MAN2 + LDA #$FF +: STA FP1MAN3 + LDA FP1EXP ; CALCULATE WHICH MANTISSA TO SHIFT + STA FPEXP + SEC + SBC FP2EXP + BEQ FADDMAN + BCS :+ + EOR #$FF + TAY + INY + LDA FP2EXP + STA FPEXP + LDA FP1MAN3 + CPY #24 ; KEEP SHIFT RANGE VALID + BCC FP1SHFT + LDA #$00 + STA FP1MAN3 + STA FP1MAN2 + STA FP1MAN1 + STA FP1MAN0 + BEQ FADDMAN +FP1SHFT: CMP #$80 ; SHIFT FP1 DOWN + ROR + ROR FP1MAN2 + ROR FP1MAN1 + ROR FP1MAN0 + DEY + BNE FP1SHFT + STA FP1MAN3 + JMP FADDMAN +: TAY + LDA FP2MAN3 + CPY #24 ; KEEP SHIFT RANGE VALID + BCC FP2SHFT + LDA #$00 + STA FP2MAN3 + STA FP2MAN2 + STA FP2MAN1 + STA FP2MAN0 + BEQ FADDMAN +FP2SHFT: CMP #$80 ; SHIFT FP2 DOWN + ROR + ROR FP2MAN2 + ROR FP2MAN1 + ROR FP2MAN0 + DEY + BNE FP2SHFT + STA FP2MAN3 +FADDMAN: LDA FP1MAN0 + CLC + ADC FP2MAN0 + STA FPMAN0 + LDA FP1MAN1 + ADC FP2MAN1 + STA FPMAN1 + LDA FP1MAN2 + ADC FP2MAN2 + STA FPMAN2 + LDA FP1MAN3 + ADC FP2MAN3 + STA FPMAN3 + BPL FPNORM + LDA #$80 + STA FPSGN + LDA #$00 + SBC FPMAN0 + STA FPMAN0 + LDA #$00 + SBC FPMAN1 + STA FPMAN1 + LDA #$00 + SBC FPMAN2 + STA FPMAN2 + LDA #$00 + SBC FPMAN3 + STA FPMAN3 +FPNORM: BEQ FPNORMLEFT ; NORMALIZE FP, A = FPMANT3 +FPNORMRIGHT: INC FPEXP + LSR + STA FPMAN3 + ROR FPMAN2 + ROR FPMAN1 + LDA FPMAN0 + ROR + ADC #$00 + STA FPMAN0 + LDA FPMAN1 + ADC #$00 + STA FPMAN1 + LDA FPMAN2 + ADC #$00 + STA FPMAN2 + LDA FPMAN3 + ADC #$00 + BNE FPNORMRIGHT + LDA FPEXP + ASL FPMAN2 + LSR + ORA FPSGN + PHA + LDA FPMAN2 + ROR + PHA + LDA FPMAN1 + PHA + LDA FPMAN0 + PHA + JMP INCNEXTOP +FPNORMLEFT: LDA FPMAN2 + BNE FPNORMLEFT1 + LDA FPMAN1 + BNE FPNORMLEFT8 + LDA FPMAN0 + BNE FPNORMLEFT16 + PHA ; RESULT IS ZERO + PHA + PHA + PHA + JMP INCNEXTOP +FPNORMLEFT16: TAX + LDA FPEXP + SEC + SBC #$10 + STA FPEXP + LDA #$00 + STA FPMAN1 + STA FPMAN0 + TXA + BNE FPNORMLEFT1 +FPNORMLEFT8: TAX + LDA FPMAN0 + STA FPMAN1 + LDA FPEXP + SEC + SBC #$08 + STA FPEXP + LDA #$00 + STA FPMAN0 + TXA +FPNORMLEFT1: BMI FPNORMDONE +: DEC FPEXP + ASL FPMAN0 + ROL FPMAN1 + ROL + BPL :- +FPNORMDONE: ASL + TAX + LDA FPEXP + LSR + ORA FPSGN + PHA + TXA + ROR + PHA + LDA FPMAN1 + PHA + LDA FPMAN0 + PHA + JMP INCNEXTOP +FMUL: PLA + STA FP2MAN0 + PLA + STA FP2MAN1 + PLA + CMP #$80 ; SET CARRY FROM MSB + ORA #$80 ; SET HIDDEN BIT + STA FP2MAN2 + PLA + ROL + STA FP2EXP + BNE :+ + TSX ; MUL BY ZERO, RESULT ZERO +; LDA #$00 + STA $0101,X + STA $0102,X + STA $0103,X + STA $0104,X + JMP INCNEXTOP +: LDA #$00 + ROR + STA FPSGN + PLA + STA FP1MAN0 + PLA + STA FP1MAN1 + PLA + CMP #$80 ; SET CARRY FROM MSB + ORA #$80 ; SET HIDDEN BIT + STA FP1MAN2 + PLA + ROL + STA FP1EXP + BNE :+ +; LDA #$00 + PHA ; MUL BY ZERO, RESULT ZERO + PHA + PHA + PHA + JMP INCNEXTOP +: LDA #$00 + ROR + EOR FPSGN + STA FPSGN + LDA FP1EXP + CLC ; ADD EXPONENTS + ADC FP2EXP + SEC ; SUBTRACT BIAS + SBC #$7F + STA FPEXP + LDX #$00 + STX FPMAN0 + STX FPMAN1 + STX FPMAN2 + STX FPMAN3 + STX TMP +FMULNEXTBYTE: LDA FP1MAN0,X + BNE :+ + LDX FPMAN1 ; SHORT CIRCUIT BYTE OF ZERO BITS + STX FPMAN0 + LDX FPMAN2 + STX FPMAN1 + LDX FPMAN3 + STX FPMAN2 + STA FPMAN3 + INC TMP + LDX TMP + CPX #$03 + BNE FMULNEXTBYTE + LDA FPMAN3 + JMP FPNORM +: EOR #$FF + LDX #$08 +FMULTSTBITS: LSR FPMAN3 + ROR FPMAN2 + ROR FPMAN1 + ROR FPMAN0 + LSR + BCS FMULNEXTTST + TAY + LDA FP2MAN0 + ADC FPMAN0 + STA FPMAN0 + LDA FP2MAN1 + ADC FPMAN1 + STA FPMAN1 + LDA FP2MAN2 + ADC FPMAN2 + STA FPMAN2 + LDA #$00 + ADC FPMAN3 + STA FPMAN3 + TYA +FMULNEXTTST: DEX + BNE FMULTSTBITS + INC TMP + LDX TMP + CPX #$03 + BNE FMULNEXTBYTE + LDA FPMAN3 + JMP FPNORM +FDIV: PLA + STA FP2MAN0 + PLA + STA FP2MAN1 + PLA + CMP #$80 ; SET CARRY FROM MSB + ORA #$80 ; SET HIDDEN BIT + STA FP2MAN2 + PLA + ROL + STA FP2EXP + BNE :+ + LDA #23 ; DIVIDE BY ZERO, ERROR + JMP SYSTHROW +: LDA #$00 + ROR + STA FPSGN + PLA + STA FP1MAN0 + PLA + STA FP1MAN1 + PLA + CMP #$80 ; SET CARRY FROM MSB + ORA #$80 ; SET HIDDEN BIT + STA FP1MAN2 + PLA + ROL + STA FP1EXP + BNE :+ +; LDA #$00 + PHA ; DIVIDE ZERO, RESULT ZERO + PHA + PHA + PHA + JMP INCNEXTOP +: LDA #$00 + STA FP1MAN3 + ROR + EOR FPSGN + STA FPSGN + LDA FP1EXP + SEC ; SUBTRACT EXPONENTS + SBC FP2EXP + CLC + ADC #$7F ; ADD BACK BIAS + STA FPEXP + LDX #24 ; #BITS +FDIVLOOP: LDA FP1MAN0 + SEC + SBC FP2MAN0 + STA TMP + LDA FP1MAN1 + SBC FP2MAN1 + STA TMP+1 + LDA FP1MAN2 + SBC FP2MAN2 + TAY + LDA FP1MAN3 + SBC #$00 + BCC FDIVNEXTBIT + STA FP1MAN3 + STY FP1MAN2 + LDA TMP+1 + STA FP1MAN1 + LDA TMP + STA FP1MAN0 +FDIVNEXTBIT: ROL FPMAN0 + ROL FPMAN1 + ROL FPMAN2 + ASL FP1MAN0 + ROL FP1MAN1 + ROL FP1MAN2 + ROL FP1MAN3 + DEX + BNE FDIVLOOP + LDA #$00 + JMP FPNORM +FCMPL: +FCMPG: TSX + TXA + TAY + CLC + ADC #$08 + TAX + TXS + LDA $0104,Y ; COMPARE SIGNS + AND #$80 + STA FP2SGN + LDA $0108,Y + AND #$80 + CMP FP2SGN + BCC FCMPGTSGN + BEQ :+ + BCS FCMPLTSGN +: LDA $0108,Y ; COMPARE AS MAGNITUDE + CMP $0104,Y + BCC FCMPLT + BEQ :+ + BCS FCMPGT +: LDA $0107,Y + CMP $0103,Y + BCC FCMPLT + BEQ :+ + BCS FCMPGT +: LDA $0106,Y + CMP $0102,Y + BCC FCMPLT + BEQ :+ + BCS FCMPGT +: LDA $0105,Y + CMP $0101,Y + BCC FCMPLT + BEQ FCMPEQ + BCS FCMPGT +FCMPEQ: PHA ; EQUAL + PHA + PHA + PHA + JMP INCNEXTOP +FCMPGT: LDA FP2SGN ; FLIP RESULT IF NEGATIVE #S + BMI FCMPLTSGN +FCMPGTSGN: LDA #$00 ; GREATER THAN + PHA + PHA + PHA + LDA #$01 + PHA + JMP INCNEXTOP +FCMPLT: LDA FP2SGN ; FLIP RESULT IF NEGATIVE #S + BMI FCMPGTSGN +FCMPLTSGN: LDA #$FF ; LESS THAN + PHA + PHA + PHA + PHA + JMP INCNEXTOP +F2I: PLA + STA FPMAN0 + PLA + STA FPMAN1 + PLA + CMP #$80 ; SET CARRY FROM MSB + ORA #$80 ; SET HIDDEN BIT + STA FPMAN2 + PLA + ROL + STA FPEXP + LDA #$00 + ROR + STA FPSGN + LDA FPEXP ; CHECK FOR LESS THAN ONE + SEC + SBC #$7F + BCS :+ + LDA #$00 ; RETURN ZERO + PHA + PHA + PHA + PHA + JMP INCNEXTOP +: CMP #23 + BCS F2ISHL + STA FPEXP + LDA #23 + SEC + SBC FPEXP + TAX ; SHIFT MANTISSA RIGHT + LDA FPMAN2 +F2ISHR: LSR + ROR FPMAN1 + ROR FPMAN0 + DEX + BNE F2ISHR + STA FPMAN2 + STX FPMAN3 +F2ICHKNEG: LDA FPSGN + BPL :+ ; CHECK FOR NEGATIVE + ASL ; LDA #$00; SEC + SBC FPMAN0 + STA FPMAN0 + LDA #$00 + SBC FPMAN1 + STA FPMAN1 + LDA #$00 + SBC FPMAN2 + STA FPMAN2 + LDA #$00 + SBC FPMAN3 + STA FPMAN3 +: LDA FPMAN3 + PHA + LDA FPMAN2 + PHA + LDA FPMAN1 + PHA + LDA FPMAN0 + PHA + JMP INCNEXTOP +F2ISHL: CMP #32 + BCC :+ + LDA #$FF ; OVERFLOW, STORE MAXINT + STA FPMAN0 + STA FPMAN1 + STA FPMAN2 + LSR + STA FPMAN3 + BNE F2ICHKNEG +: SEC + SBC #23 + BNE :+ + STA FPMAN3 + BEQ F2ICHKNEG +: TAX ; SHIFT MANTISSA LEFT + LDA #$00 +: ASL FPMAN0 + ROL FPMAN1 + ROL FPMAN2 + ROL + DEX + BNE :- + STA FPMAN3 + BEQ F2ICHKNEG +I2F: PLA + STA FPMAN0 + PLA + STA FPMAN1 + PLA + STA FPMAN2 + PLA + STA FPMAN3 + AND #$80 + STA FPSGN + BPL :+ + LDX #FPMAN0 + JSR NEGINT +: LDA #$7F+23 + STA FPEXP + LDA FPMAN3 + JMP FPNORM +;* +;* UNIMPLEMENTED INSTRUCTIONS +;* +.ELSE +FNEG: +FADD: +FSUB: +FMUL: +FDIV: +FREM: +FCMPL: +FCMPG: +F2I: +I2F: + PSTRLN "FLOATING POINT UNIMPLEMENTED" + JMP THROW_INTERNALERR +.ENDIF +DCONST_0: +DCONST_1: +DLOAD: +DLOAD0: +DLOAD1: +DLOAD2: +DLOAD3: +DALOAD: +DSTORE: +DSTORE0: +DSTORE1: +DSTORE2: +DSTORE3: +DASTORE: +DADD: +DSUB: +DMUL: +DDIV: +DREM: +DNEG: +I2D: +D2I: +D2L: +D2F: +DCMPL: +DCMPG: + PSTRLN "DOUBLE PRECISION UNIMPLEMENTED" +; BRK + JMP THROW_INTERNALERR +LCONST_0: +LCONST_1: +LALOAD: +LSTORE: +LSTORE0: +LSTORE1: +LSTORE2: +LSTORE3: +LASTORE: +LADD: +LSUB: +LMUL: +LDIV: +LREM: +LNEG: +LSHL: +LSHR: +LUSHR: +LAND: +LOR: +LXOR: +L2F: +L2D: +F2L: +F2D: +LCMP: + PSTRLN "LONG INTS UNIMPLEMENTED" + JMP THROW_INTERNALERR +WIDE: +GOTO_W: +JSR_W: +BREAKPOINT: +XXX: + PSTRLN "UNIMPLEMENTED INSTRUCTION" + JMP THROW_INTERNALERR + + .SEGMENT "INIT" +INTERP_SIZE EQU INTERP_END-INTERP_BEGIN +INTERP_INIT: LDA LCBNK2 ; SET LANGUAGE CARD BANK2 WRITE ENABLE + LDA LCBNK2 + LDA WARM_INIT + BNE :+ + LDA #INTERP_RELOC + JSR MEMSRC + LDA #INTERP_BEGIN + JSR MEMDST + LDA #<(INTERP_SIZE) + LDX #>(INTERP_SIZE) + JSR MEMCPY ; RELOCATE INTERPRETER TO LANGUAGE CARD + LDA #$00 + TAX + STA HEXECFRAME ; ZERO OUT CURRENT FRAME + STX HEXECFRAME+1 +: RTS +INTERP_RELOC: + .ORG $D000 +INTERP_BEGIN: +OPLTBL: .ADDR NOOP, ACONST_NULL, ICONST_M1, ICONST_0 + .ADDR ICONST_1, ICONST_2, ICONST_3, ICONST_4 + .ADDR ICONST_5, LCONST_0, LCONST_1, FCONST_0 + .ADDR FCONST_1, FCONST_2, DCONST_0, DCONST_1 + .ADDR BIPUSH, SIPUSH, LDC, LDC_W, LDC2_W + .ADDR ILOAD, LLOAD, FLOAD, DLOAD, ALOAD + .ADDR ILOAD0, ILOAD1, ILOAD2, ILOAD3 + .ADDR LLOAD0, LLOAD1, LLOAD2, LLOAD3 + .ADDR FLOAD0, FLOAD1, FLOAD2, FLOAD3 + .ADDR DLOAD0, DLOAD1, DLOAD2, DLOAD3 + .ADDR ALOAD0, ALOAD1, ALOAD2, ALOAD3 + .ADDR IALOAD, LALOAD, FALOAD, DALOAD, AALOAD + .ADDR BALOAD, CALOAD, SALOAD + .ADDR ISTORE, LSTORE, FSTORE, DSTORE, ASTORE + .ADDR ISTORE0, ISTORE1, ISTORE2, ISTORE3 + .ADDR LSTORE0, LSTORE1, LSTORE2, LSTORE3 + .ADDR FSTORE0, FSTORE1, FSTORE2, FSTORE3 + .ADDR DSTORE0, DSTORE1, DSTORE2, DSTORE3 + .ADDR ASTORE0, ASTORE1, ASTORE2, ASTORE3 + .ADDR IASTORE, LASTORE, FASTORE, DASTORE, AASTORE + .ADDR BASTORE, CASTORE, SASTORE + .ADDR POP, POP2, DUP, DUP_X1, DUP_X2 + .ADDR DUP2, DUP2_X1, DUP2_X2, SWAP + .ADDR IADD, LADD, FADD, DADD + .ADDR ISUB, LSUB, FSUB, DSUB + .ADDR IMUL, LMUL, FMUL, DMUL + .ADDR IDIV, LDIV, FDIV, DDIV + .ADDR IREM, LREM, FREM, DREM + .ADDR INEG, LNEG, FNEG, DNEG + .ADDR ISHL, LSHL, ISHR, LSHR + .ADDR IUSHR, LUSHR, IAND, LAND +OPHTBL: .ADDR IOR, LOR, IXOR, LXOR, IINC + .ADDR NOOP, I2F, I2D ; I2L = NOOP + .ADDR NOOP, L2F, L2D ; L2I = NOOP + .ADDR F2I, F2L, F2D + .ADDR D2I, D2L, D2F + .ADDR I2B, I2C, I2S + .ADDR LCMP, FCMPL, FCMPG, DCMPL, DCMPG + .ADDR IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE + .ADDR IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE + .ADDR IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE + .ADDR GOTO, JSUB, RET, TABLESWITCH, LOOKUPSWITCH + .ADDR IRETURN, LRETURN, FRETURN, DRETURN, ARETURN, RETURN + .ADDR GETSTATIC, PUTSTATIC, GETFIELD, PUTFIELD + .ADDR INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC, INVOKEINTERFACE + .ADDR UCODERET, NEW, NEWARRAY, ANEWARRAY, ARRAYLENGTH + .ADDR ATHROW, CHECKCAST, INSTANCEOF + .ADDR MONITORENTER, MONITOREXIT + .ADDR WIDE, MULTINEWARRAY, IFNULL, IFNONNULL + .ADDR GOTO_W, JSR_W, BREAKPOINT +; .ADDR NEW2, DECREFOBJ ; MY SPECIAL OPCODES +;* +;* FETCH BYTECODE AND INTERPRET. +;* +GOTO: +BRANCHNEXTOP: LDY #$01 + LDW_BYTECODE + CLC + ADC EXECPC + STA EXECPC + TXA + ADC EXECPC+1 + STA EXECPC+1 + INC OPCNT + BNE EXECBYTECODES +YIELDOP: LDA #>(EXECBYTECODES-1) ; RETURN TO EXECBYTECODES + PHA + LDA #<(EXECBYTECODES-1) + PHA + JMP (LINK_YIELD) ; CALL THREAD_YIELD +INC3NEXTOP: LDY #$02 +INCYNEXTOP: INY + TYA +INCANEXTOP: CLC + ADC EXECPC + STA EXECPC + BCC NEXTOP + BCS :+ +NOOP: +I2B: +I2C: +I2S: +INCNEXTOP: INC EXECPC + BNE NEXTOP +: INC EXECPC+1 +NEXTOP: INC OPCNT + BEQ YIELDOP +EXECBYTECODES: + LDY #$00 + AUXMEM_RDACCESS_ON + LDA (EXECPC),Y + AUXMEM_RDACCESS_OFF + INY +.IFDEF DEBUG_INTERP + JMP DEBUGEXEC +.ELSE + ASL + BCS :+ + STA OPL+1 +OPL: JMP (OPLTBL) +: STA OPH+1 +OPH: JMP (OPHTBL) +.ENDIF +;* +;* BIGMEM BYTECODE ACCESS ROUTINES +;* +.IFDEF BIGMEM +READBYTECODEB: AUXMEM_RDACCESS_ON + LDA (EXECPC),Y + AUXMEM_RDACCESS_OFF + RTS +READBYTECODEW: AUXMEM_RDACCESS_ON + LDA (EXECPC),Y + INY + TAX + LDA (EXECPC),Y + AUXMEM_RDACCESS_OFF + RTS +.ENDIF +;* +;* BYTECODE OPS IN ORDER (SORT OF) +;* +ACONST_NULL: +FCONST_0: +ICONST_0: +CONST_0: LDA #$00 +CONST_N: PHA + PHA + PHA + PHA + JMP INCNEXTOP +ICONST_M1: LDA #$FF + BNE CONST_N +ICONST_5: INY ; LDY #$05 +ICONST_4: INY ; LDY #$04 +ICONST_3: INY ; LDY #$03 +ICONST_2: INY ; LDY #$02 +ICONST_1: LDA #$00 ; LDY #$01 + PHA + PHA + PHA + TYA + PHA + JMP INCNEXTOP +FCONST_1: LDY #$80 + LDA #$3F +FCONST_N: PHA + TYA + PHA + LDA #$00 + PHA + PHA + JMP INCNEXTOP +FCONST_2: LDY #$00 + LDA #$40 + BNE FCONST_N +BIPUSH: AUXMEM_RDACCESS_ON + LDA (EXECPC),Y + AUXMEM_RDACCESS_OFF + TAX + AND #$80 + BPL :+ + LDA #$FF +: PHA + PHA + PHA + TXA + PHA + JMP INCYNEXTOP +SIPUSH: AUXMEM_RDACCESS_ON + LDA (EXECPC),Y + INY + TAX + AND #$80 + BPL :+ + LDA #$FF +: PHA + PHA + TXA + PHA + LDA (EXECPC),Y + AUXMEM_RDACCESS_OFF + PHA + JMP INCYNEXTOP +LDC: LDB_BYTECODE ; READ INDEX + LDX #$00 + LDY #$00 + JSR GETCONSTB ; CONVERT TO CONSTANT + CMP #CONST_STRING ; CHECK FOR STRING OBJECT + BNE :+ + LDY #$03 ; FOLLOW INDEX + LDA (CONSTPTR),Y + INY + TAX + LDA (CONSTPTR),Y + JSR SETCONSTPTR ; STRING REFERENCE +: LDY #$01 + LDA (CONSTPTR),Y + INY + PHA + LDA (CONSTPTR),Y + INY + PHA + LDA (CONSTPTR),Y + INY + PHA + LDA (CONSTPTR),Y + PHA + LDA #02 + JMP INCANEXTOP +LDC2_W: LDW_BYTECODE + CLC + ADC #$01 ; FAKE 64 BIT LOADS AS 32 BITS + BCC :+ + INX + BNE :+ +LDC_W: LDW_BYTECODE +: LDY #$00 + JSR GETCONSTB ; CONVERT TO POINTER + CMP #CONST_STRING ; CHECK FOR STRING OBJECT + BNE :+ + LDY #$03 ; FOLLOW INDEX + LDA (CONSTPTR),Y + INY + TAX + LDA (CONSTPTR),Y + JSR SETCONSTPTR ; STRING REFERENCE +: LDY #$01 + LDA (CONSTPTR),Y + INY + PHA + LDA (CONSTPTR),Y + INY + PHA + LDA (CONSTPTR),Y + INY + PHA + LDA (CONSTPTR),Y + PHA + JMP INC3NEXTOP +ILOAD: +FLOAD: +LLOAD: +ALOAD: LDB_BYTECODE + TAY + LDA (BP3),Y + PHA + LDA (BP2),Y + PHA + LDA (BP1),Y + PHA + LDA (BP0),Y + PHA + LDA #$02 + JMP INCANEXTOP +ILOAD3: +FLOAD3: +LLOAD3: +ALOAD3: INY +ILOAD2: +FLOAD2: +LLOAD2: +ALOAD2: INY +ILOAD1: +FLOAD1: +LLOAD1: +ALOAD1: INY +ILOAD0: +FLOAD0: +LLOAD0: +ALOAD0: DEY + LDA (BP3),Y + PHA + LDA (BP2),Y + PHA + LDA (BP1),Y + PHA + LDA (BP0),Y + PHA + JMP INCNEXTOP +BALOAD: TSX + JSR CHKINDEX + LDA TARGETOFFSET + CLC + ADC ARRAYPTR + STA ARRAYPTR + LDA TARGETOFFSET+1 + ADC ARRAYPTR+1 + STA ARRAYPTR+1 + TSX ; SKIP ARRAY REF AND INDEX + TXA + CLC + ADC #$08 + TAX + TXS + LDY #$00 + LDA (ARRAYPTR),Y + TAX + AND #$80 + BPL :+ + LDA #$FF +: PHA + PHA + PHA + TXA + PHA + JMP INCNEXTOP +SALOAD: TSX + JSR CHKINDEX + LDA TARGETOFFSET + ASL + ROL TARGETOFFSET+1 + CLC + ADC ARRAYPTR + STA ARRAYPTR + LDA TARGETOFFSET+1 + ADC ARRAYPTR+1 + STA ARRAYPTR+1 + TSX + TXA + CLC + ADC #$08 + TAX + TXS + LDY #$01 + LDA (ARRAYPTR),Y + DEY + TAX + AND #$80 + BPL :+ + LDA #$FF +: PHA + PHA + TXA + PHA + LDA (ARRAYPTR),Y + PHA + JMP INCNEXTOP +CALOAD: LDA #$00 + STA TARGETCLASS + STA TARGETCLASS+1 + TSX +U16ALOAD: JSR CHKINDEX + LDA TARGETOFFSET + ASL + ROL TARGETOFFSET+1 + CLC + ADC ARRAYPTR + STA ARRAYPTR + LDA TARGETOFFSET+1 + ADC ARRAYPTR+1 + STA ARRAYPTR+1 + TSX + TXA + CLC + ADC #$08 + TAX + TXS + LDA TARGETCLASS+1 ; ALLOW CALOAD AND AALOAD(ARRAY) TO USE SAME CODE + PHA + LDA TARGETCLASS + PHA + LDY #$01 + LDA (ARRAYPTR),Y + DEY + PHA + LDA (ARRAYPTR),Y + PHA + JMP INCNEXTOP +AALOAD: TSX + LDA $0108,X ; CHECK ATYPE + CMP #$20 + BCC IALOAD+1 ; USE 32 BIT LOAD FOR REF ARRAY +; SEC + SBC #$10 ; DEC DIMENSION COUNT + STA TARGETCLASS+1 + LDA #CL_ARRAY + STA TARGETCLASS + BNE U16ALOAD ; USE 16 BIT LOAD FOR ARRAY REF +IALOAD: +FALOAD: TSX + JSR CHKINDEX + LDA TARGETOFFSET + ASL + ROL TARGETOFFSET+1 + ASL + ROL TARGETOFFSET+1 + CLC + ADC ARRAYPTR + STA ARRAYPTR + LDA TARGETOFFSET+1 + ADC ARRAYPTR+1 + STA ARRAYPTR+1 + TSX + TXA + CLC + ADC #$08 + TAX + TXS + LDY #$03 + LDA (ARRAYPTR),Y + DEY + PHA + LDA (ARRAYPTR),Y + DEY + PHA + LDA (ARRAYPTR),Y + DEY + PHA + LDA (ARRAYPTR),Y + PHA + JMP INCNEXTOP +ISTORE: +FSTORE: LDB_BYTECODE + TAY + PLA + STA (BP0),Y + PLA + STA (BP1),Y + PLA + STA (BP2),Y + PLA + STA (BP3),Y + LDA #$02 + JMP INCANEXTOP +ASTORE: LDB_BYTECODE + TAY + LDA #$02 + BCC :+ +ASTORE3: INY +ASTORE2: INY +ASTORE1: INY +ASTORE0: DEY + LDA #$01 +: TSX + PHA + LDA $0103,X + BMI :++ + TYA + PHA + LDA $0101,X + TAY + LDA $0102,X + BEQ :+ + TAX + TYA + JSR HMEM_REF_INC ; INC REF COUNT OF NEW STORED VALUE +: PLA + TAY +: LDA (BPT),Y + BPL :+ + TYA + PHA + LDA (BP3),Y + PHA + LDA (BP2),Y + PHA + LDA (BP1),Y + PHA + LDA (BP0),Y + PHA + JSR UNREF_OBJECT + PLA + TAY +: PLA + TAX + LDA #T_REF|$80 + STA (BPT),Y + PLA + STA (BP0),Y + PLA + STA (BP1),Y + PLA + AND #$7F ; CLEAR REF COUNT FLAG + STA (BP2),Y + PLA + STA (BP3),Y + TXA + JMP INCANEXTOP +ISTORE3: +FSTORE3: INY +ISTORE2: +FSTORE2: INY +ISTORE1: +FSTORE1: INY +ISTORE0: +FSTORE0: DEY + PLA + STA (BP0),Y + PLA + STA (BP1),Y + PLA + STA (BP2),Y + PLA + STA (BP3),Y + JMP INCNEXTOP +BASTORE: TSX + JSR CHKSTOREINDEX + LDA TARGETOFFSET + CLC + ADC ARRAYPTR + STA ARRAYPTR + LDA TARGETOFFSET+1 + ADC ARRAYPTR+1 + STA ARRAYPTR+1 + TSX + LDY #$00 + PLA + STA (ARRAYPTR),Y + TXA + CLC + ADC #$0C + TAX + TXS + JMP INCNEXTOP +CASTORE: +SASTORE: TSX + JSR CHKSTOREINDEX + LDA TARGETOFFSET + ASL + ROL TARGETOFFSET+1 + CLC + ADC ARRAYPTR + STA ARRAYPTR + LDA TARGETOFFSET+1 + ADC ARRAYPTR+1 + STA ARRAYPTR+1 + TSX + LDY #$00 + PLA + STA (ARRAYPTR),Y + INY + PLA + STA (ARRAYPTR),Y + TXA + CLC + ADC #$0C + TAX + TXS + JMP INCNEXTOP +IASTORE: +FASTORE: TSX + JSR CHKSTOREINDEX + LDA TARGETOFFSET + ASL + ROL TARGETOFFSET+1 + ASL + ROL TARGETOFFSET+1 + CLC + ADC ARRAYPTR + STA ARRAYPTR + LDA TARGETOFFSET+1 + ADC ARRAYPTR+1 + STA ARRAYPTR+1 + TSX + LDY #$00 + PLA + STA (ARRAYPTR),Y + INY + PLA + STA (ARRAYPTR),Y + INY + PLA + STA (ARRAYPTR),Y + INY + PLA + STA (ARRAYPTR),Y + TXA + CLC + ADC #$0C + TAX + TXS + JMP INCNEXTOP +AASTORE: TSX + LDA $0103,X + BMI :+ + LDY $0101,X + LDA $0102,X + BEQ :+ + TAX + TYA + JSR HMEM_REF_INC ; INC REF COUNT OF NEW STORED VALUE + TSX +: JSR CHKSTOREINDEX + TSX + LDA $010C,X ; CHECK ARRAY DIMENSIONS + CMP #$20 + BCC REFASTORE ; STORE INTO REF ARRAY + SBC #$10 + STA TARGETTYPE + LDA TARGETOFFSET + ASL + ROL TARGETOFFSET+1 + CLC + ADC ARRAYPTR + STA ARRAYPTR + LDA TARGETOFFSET+1 + ADC ARRAYPTR+1 + STA ARRAYPTR+1 + LDA $0104,X ; FILL IN HIWORD OF ARRAY REFERENCE + BNE :+ + LDA TARGETTYPE +: CMP TARGETTYPE + BNE REFSTOREERR + PHA + LDA #CL_ARRAY + PHA + LDY #$01 + LDA (ARRAYPTR),Y + PHA + LDA $0102,X + STA (ARRAYPTR),Y + DEY + LDA (ARRAYPTR),Y + PHA + LDA $0101,X ; COPY NEW VALUE OVER BEFORE UNREF OLD OBJECT + STA (ARRAYPTR),Y + JSR UNREF_OBJECT + TSX + TXA + CLC + ADC #$0C + TAX + TXS + JMP INCNEXTOP +REFSTOREERR: LDA #8 ; INCOMPATIBLE CLASS CHANGE + JMP SYSTHROW +REFASTORE: LDA TARGETOFFSET + ASL + ROL TARGETOFFSET+1 + ASL + ROL TARGETOFFSET+1 + CLC + ADC ARRAYPTR + STA ARRAYPTR + LDA TARGETOFFSET+1 + ADC ARRAYPTR+1 + STA ARRAYPTR+1 + LDY #$03 + LDA (ARRAYPTR),Y + PHA + LDA $0104,X + STA (ARRAYPTR),Y + DEY + LDA (ARRAYPTR),Y + PHA + LDA $0103,X + AND #$7F ; CLEAR REF COUNT FLAG + STA (ARRAYPTR),Y + DEY + LDA (ARRAYPTR),Y + PHA + LDA $0102,X + STA (ARRAYPTR),Y + DEY + LDA (ARRAYPTR),Y + PHA + LDA $0101,X ; COPY NEW VALUE OVER BEFORE UNREF OLD OBJECT + STA (ARRAYPTR),Y + JSR UNREF_OBJECT + TSX + TXA + CLC + ADC #$0C + TAX + TXS + JMP INCNEXTOP +POP: PLA + PLA + PLA + PLA + JMP INCNEXTOP +POP2: TSX + TXA + ADC #$08 + TAX + TXS + JMP INCNEXTOP +DUP: TSX + LDA $0104,X + PHA + LDA $0103,X + PHA + LDA $0102,X + PHA + LDA $0101,X + PHA + JMP INCNEXTOP +DUP2: TSX + LDA $0108,X + PHA + LDA $0107,X + PHA + LDA $0106,X + PHA + LDA $0105,X + PHA + LDA $0104,X + PHA + LDA $0103,X + PHA + LDA $0102,X + PHA + LDA $0101,X + PHA + JMP INCNEXTOP +DUP_X1: TSX + DEX + DEX + DEX + DEX + TXS + LDY #$08 ; MOVE TOP 2 STACK VALS UP +: LDA $0105,X + STA $0101,X + INX + DEY + BNE :- + TSX + LDA $0101,X ; COPY TOP STACK VAL TO EMPTY SPOT + STA $0109,X + LDA $0102,X + STA $010A,X + LDA $0103,X + STA $010B,X + LDA $0104,X + STA $010C,X + JMP INCNEXTOP +DUP_X2: TSX + DEX + DEX + DEX + DEX + TXS + LDY #$0C ; MOVE TOP 3 STACK VALS UP +: LDA $0105,X + STA $0101,X + INX + DEY + BNE :- + TSX + LDA $0101,X ; COPY TOP STACK VAL TO EMPTY SPOT + STA $010D,X + LDA $0102,X + STA $010E,X + LDA $0103,X + STA $010F,X + LDA $0104,X + STA $0110,X + JMP INCNEXTOP +DUP2_X1: TSX + TXA + SBC #$07 ; CARRY = 0, SUB 8 + TAX + TXS + LDY #$0C ; MOVE TOP 3 STACK VALS UP +: LDA $0109,X + STA $0101,X + INX + DEY + BNE :- + TSX + LDY #$08 +: LDA $0101,X + STA $010D,X + INX + DEY + BNE :- + JMP INCNEXTOP +DUP2_X2: TSX + TXA + SBC #$07 ; CARRY = 0, SUB 8 + TAX + TXS + LDY #$10 ; MOVE TOP 4 STACK VALS UP +: LDA $0109,X + STA $0101,X + INX + DEY + BNE :- + TSX + LDY #$08 +: LDA $0101,X + STA $0111,X + INX + DEY + BNE :- + JMP INCNEXTOP +SWAP: TSX + LDA $0104,X + TAY + LDA $0108,X + STA $0104,X + TYA + STA $0108,X + LDA $0103,X + TAY + LDA $0107,X + STA $0103,X + TYA + STA $0107,X + LDA $0102,X + TAY + LDA $0106,X + STA $0102,X + TYA + STA $0106,X + LDA $0101,X + TAY + LDA $0105,X + STA $0101,X + TYA + STA $0105,X + JMP INCNEXTOP +IADD: TSX + PLA + ADC $0105,X + STA $0105,X + PLA + ADC $0106,X + STA $0106,X + PLA + ADC $0107,X + STA $0107,X + PLA + ADC $0108,X + STA $0108,X + JMP INCNEXTOP +ISUB: TSX + LDA $0105,X + SEC + SBC $0101,X + STA $0105,X + INX + LDA $0105,X + SBC $0101,X + STA $0105,X + INX + LDA $0105,X + SBC $0101,X + STA $0105,X + INX + LDA $0105,X + SBC $0101,X + STA $0105,X + INX + TXS + JMP INCNEXTOP +IMUL: PLA + STA MULTPLR + PLA + STA MULTPLR+1 + PLA + STA MULTPLR+2 + PLA + STA MULTPLR+3 + AND #$80 ; KEEP # OF 1 BITS DOWN + STA MULSIGN + BPL :+ + LDX #MULTPLR + JSR NEGINT +: PLA + STA MULTPLND + PLA + STA MULTPLND+1 + PLA + STA MULTPLND+2 + PLA + STA MULTPLND+3 + LDX #$00 + STX PROD + STX PROD+1 + STX PROD+2 + STX PROD+3 + STX MULIDX +IMULNEXTBYTE: LDA MULTPLR,X + BNE :+ + LDX MULTPLND+2 ; SHORT CIRCUIT BYTE OF ZERO BITS + STX MULTPLND+3 + LDX MULTPLND+1 + STX MULTPLND+2 + LDX MULTPLND + STX MULTPLND+1 + STA MULTPLND + INC MULIDX + LDX MULIDX + CPX #$04 + BNE IMULNEXTBYTE + BEQ IMULDONE +: EOR #$FF + LDX #$08 +IMULTSTBITS: LSR + BCS IMULNEXTTST + TAY + LDA MULTPLND + ADC PROD + STA PROD + LDA MULTPLND+1 + ADC PROD+1 + STA PROD+1 + LDA MULTPLND+2 + ADC PROD+2 + STA PROD+2 + LDA MULTPLND+3 + ADC PROD+3 + STA PROD+3 + TYA +IMULNEXTTST: ASL MULTPLND + ROL MULTPLND+1 + ROL MULTPLND+2 + ROL MULTPLND+3 + DEX + BNE IMULTSTBITS + INC MULIDX + LDX MULIDX + CPX #$04 + BNE IMULNEXTBYTE +IMULDONE: LDA MULSIGN + BPL :+ + LDX #PROD + JSR NEGINT +: LDA PROD+3 + PHA + LDA PROD+2 + PHA + LDA PROD+1 + PHA + LDA PROD + PHA + JMP INCNEXTOP +IDIV: LDA #IDIVDONE + STA OPADDR+1 + BNE IDIVIDE +IDIVDONE: LSR DVSIGN ; SIGN(RESULT) = (SIGN(DIVIDEND) + SIGN(DIVISOR)) & 1 + BCC :+ + LDX #DVDND + JSR NEGINT +: LDA DVDND+3 + PHA + LDA DVDND+2 + PHA + LDA DVDND+1 + PHA + LDA DVDND + PHA + JMP INCNEXTOP +IREM: LDA #IREMDONE + STA OPADDR+1 + BNE IDIVIDE ; REMAINDER IS SIGN OF DIVIDEND +IREMDONE: LDA DVSIGN + BPL :+ + LDX #REMNDR + JSR NEGINT +: LDA REMNDR+3 + PHA + LDA REMNDR+2 + ROR + PHA + LDA REMNDR+1 + ROR + PHA + LDA REMNDR + ROR + PHA + JMP INCNEXTOP +IDIVIDE: PLA + STA DVSR + PLA + STA DVSR+1 + PLA + STA DVSR+2 + PLA + STA DVSR+3 + AND #$80 + STA DVSIGN + BPL :+ + LDX #DVSR + JSR NEGINT + INC DVSIGN +: PLA + STA DVDND + PLA + STA DVDND+1 + PLA + STA DVDND+2 + PLA + STA DVDND+3 + BPL :+ + LDX #DVDND + JSR NEGINT + INC DVSIGN +: LDX #33 ; #BITS+1 + LDA DVSR + ORA DVSR+1 + ORA DVSR+2 + ORA DVSR+3 + BNE :+ + LDA #23 ; DIVIDE BY ZERO, ERROR + JMP SYSTHROW +: LDA DVDND + ORA DVDND+1 + ORA DVDND+2 + ORA DVDND+3 + BNE IDIVFIND1 + LDA #$00 ; DIVIDE ZERO + STA REMNDR + STA REMNDR+1 + STA REMNDR+2 + STA REMNDR+3 + JMP (OPADDR) +IDIVFIND1: ASL DVDND + ROL DVDND+1 + ROL DVDND+2 + ROL DVDND+3 + DEX + BCC IDIVFIND1 + LDA #$00 + STA REMNDR+3 + STA REMNDR+2 + STA REMNDR+1 + ROL ; CARRY = 1, A = 1 AFTER ROL + STA REMNDR +IDIVLOOP: LDA REMNDR + SEC + SBC DVSR + STA TMP + LDA REMNDR+1 + SBC DVSR+1 + STA TMP+1 + LDA REMNDR+2 + SBC DVSR+2 + TAY + LDA REMNDR+3 + SBC DVSR+3 + BCC IDIVNEXTBIT + STA REMNDR+3 + STY REMNDR+2 + LDA TMP+1 + STA REMNDR+1 + LDA TMP + STA REMNDR +IDIVNEXTBIT: ROL DVDND + ROL DVDND+1 + ROL DVDND+2 + ROL DVDND+3 + ROL REMNDR + ROL REMNDR+1 + ROL REMNDR+2 + ROL REMNDR+3 + DEX + BNE IDIVLOOP + JMP (OPADDR) ; RETURN TO IDIV OR IREM +NEGINT: LDA #$00 + SEC + SBC $00,X + STA $00,X + LDA #$00 + SBC $01,X + STA $01,X + LDA #$00 + SBC $02,X + STA $02,X + LDA #$00 + SBC $03,X + STA $03,X + RTS +INEG: TSX + DEY + TYA + SEC + SBC $0101,X + STA $0101,X + TYA + SBC $0102,X + STA $0102,X + TYA + SBC $0103,X + STA $0103,X + TYA + SBC $0104,X + STA $0104,X + JMP INCNEXTOP +.IFDEF FLOATING_POINT ; MUST BE IN LC +FREM: LDA #FREMCODE + JMP EXECUCODE +FREMCODE: .BYTE $5C ; DUP2 ; INJECT BYTECODE TO EXECUTE OPERATION + .BYTE $6E ; FDIV ; FP1 - (INT(FP1/FP2) * FP2) + .BYTE $8B ; F2I + .BYTE $86 ; I2F + .BYTE $6A ; FMUL + .BYTE $66 ; FSUB + .BYTE $BA ; UCODERET ; HIJACK UNUSED OPCODE +.ENDIF +ISHL: PLA + TAY + PLA + PLA + PLA + TSX + CPY #$08 + BCC :+ +ISHL8: LDA $0103,X + STA $0104,X + LDA $0102,X + STA $0103,X + LDA $0101,X + STA $0102,X + LDA #$00 + STA $0101,X + TYA + SEC + SBC #$08 + BEQ ISHLEXIT + TAY + CPY #$08 + BCS ISHL8 +: ASL $0101,X + ROL $0102,X + ROL $0103,X + ROL $0104,X + DEY + BNE :- +ISHLEXIT: JMP INCNEXTOP +ISHR: PLA + TAY + PLA + PLA + PLA + TSX + CPY #$08 + BCC :++ +ISHR8: LDA $0102,X + STA $0101,X + LDA $0103,X + STA $0102,X + LDA $0104,X + STA $0103,X + AND #$80 + BPL :+ + LDA #$FF +: STA $0104,X + TYA + SEC + SBC #$08 + BEQ ISHREXIT + TAY + CPY #$08 + BCS ISHR8 +: LDA $0104,X +: CMP #$80 + ROR + ROR $0103,X + ROR $0102,X + ROR $0101,X + DEY + BNE :- + STA $0104,X +ISHREXIT: JMP INCNEXTOP +IUSHR: PLA + TAY + PLA + PLA + PLA + TYA + TSX + CPY #$08 + BCC :+ +IUSHR8: LDA $0102,X + STA $0101,X + LDA $0103,X + STA $0102,X + LDA $0104,X + STA $0103,X + LDA #$00 + STA $0104,X + TYA + SEC + SBC #$08 + BEQ IUSHREXIT + TAY + CPY #$08 + BCS IUSHR8 +: LSR $0104,X + ROR $0103,X + ROR $0102,X + ROR $0101,X + DEY + BNE :- +IUSHREXIT: JMP INCNEXTOP +IAND: TSX + PLA + AND $0105,X + STA $0105,X + PLA + AND $0106,X + STA $0106,X + PLA + AND $0107,X + STA $0107,X + PLA + AND $0108,X + STA $0108,X + JMP INCNEXTOP +IOR: TSX + PLA + ORA $0105,X + STA $0105,X + PLA + ORA $0106,X + STA $0106,X + PLA + ORA $0107,X + STA $0107,X + PLA + ORA $0108,X + STA $0108,X + JMP INCNEXTOP +IXOR: TSX + PLA + EOR $0105,X + STA $0105,X + PLA + EOR $0106,X + STA $0106,X + PLA + EOR $0107,X + STA $0107,X + PLA + EOR $0108,X + STA $0108,X + JMP INCNEXTOP +IINC: LDX #$00 + AUXMEM_RDACCESS_ON + LDA (EXECPC),Y + INY + STA TMP + LDA (EXECPC),Y + AUXMEM_RDACCESS_OFF + BPL :+ + DEX +: LDY TMP + CLC + ADC (BP0),Y + STA (BP0),Y + TXA + ADC (BP1),Y + STA (BP1),Y + TXA + ADC (BP2),Y + STA (BP2),Y + TXA + ADC (BP3),Y + STA (BP3),Y + JMP INC3NEXTOP +IFNULL: PLA + STA TMP + PLA + ORA TMP + STA TMP + PLA + PLA + LDA TMP + BEQ ISTRUE + BNE ISFALSE +IFNONNULL: PLA + STA TMP + PLA + ORA TMP + STA TMP + PLA + PLA + LDA TMP + BNE ISTRUE + BEQ ISFALSE +IFEQ: PLA + STA TMP + PLA + ORA TMP + STA TMP + PLA + ORA TMP + STA TMP + PLA + ORA TMP + BEQ ISTRUE +ISFALSE: JMP INC3NEXTOP +ISTRUE: JMP BRANCHNEXTOP +IFNE: PLA + STA TMP + PLA + ORA TMP + STA TMP + PLA + ORA TMP + STA TMP + PLA + ORA TMP + BNE ISTRUE + BEQ ISFALSE +IFLT: PLA + PLA + PLA + PLA + BMI ISTRUE + BPL ISFALSE +IFGE: PLA + PLA + PLA + PLA + BPL ISTRUE + BMI ISFALSE +IFLE: PLA + STA TMP + PLA + ORA TMP + STA TMP + PLA + ORA TMP + STA TMP + PLA + BMI ISTRUE + ORA TMP + BEQ ISTRUE + BNE ISFALSE +IFGT: PLA + STA TMP + PLA + ORA TMP + STA TMP + PLA + ORA TMP + STA TMP + PLA + BMI ISFALSE + ORA TMP + BEQ ISFALSE + BNE ISTRUE +IF_ICMPEQ: +IF_ACMPEQ: TSX + TXA + TAY + CLC + ADC #$08 + TAX + LDA $0105,Y + CMP $0101,Y + BNE :+ + LDA $0106,Y + CMP $0102,Y + BNE :+ + LDA $0107,Y + CMP $0103,Y + BNE :+ + LDA $0108,Y + CMP $0104,Y + BNE :+ + TXS + JMP BRANCHNEXTOP +: TXS + JMP INC3NEXTOP +IF_ICMPNE: +IF_ACMPNE: TSX + TXA + TAY + CLC + ADC #$08 + TAX + LDA $0105,Y + CMP $0101,Y + BNE :+ + LDA $0106,Y + CMP $0102,Y + BNE :+ + LDA $0107,Y + CMP $0103,Y + BNE :+ + LDA $0108,Y + CMP $0104,Y + BNE :+ + TXS + JMP INC3NEXTOP +: TXS + JMP BRANCHNEXTOP +; TOS-1 < TOS +IF_ICMPLT: TSX + TXA + TAY + CLC + ADC #$08 + TAX + LDA $0105,Y + CMP $0101,Y + LDA $0106,Y + SBC $0102,Y + LDA $0107,Y + SBC $0103,Y + LDA $0108,Y + SBC $0104,Y + TXS + BVC :+ + EOR #$80 +: BMI :+ + JMP INC3NEXTOP +: JMP BRANCHNEXTOP +; TOS-1 >= TOS +IF_ICMPGE: TSX + TXA + TAY + CLC + ADC #$08 + TAX + LDA $0105,Y + CMP $0101,Y + LDA $0106,Y + SBC $0102,Y + LDA $0107,Y + SBC $0103,Y + LDA $0108,Y + SBC $0104,Y + TXS + BVC :+ + EOR #$80 +: BPL :+ + JMP INC3NEXTOP +: JMP BRANCHNEXTOP +; TOS-1 > TOS -> TOS < TOS-1 +IF_ICMPGT: TSX + TXA + TAY + CLC + ADC #$08 + TAX + LDA $0101,Y + CMP $0105,Y + LDA $0102,Y + SBC $0106,Y + LDA $0103,Y + SBC $0107,Y + LDA $0104,Y + SBC $0108,Y + TXS + BVC :+ + EOR #$80 +: BMI :+ + JMP INC3NEXTOP +: JMP BRANCHNEXTOP +; TOS-1 <= TOS -> TOS >= TOS-1 +IF_ICMPLE: TSX + TXA + TAY + CLC + ADC #$08 + TAX + LDA $0101,Y + CMP $0105,Y + LDA $0102,Y + SBC $0106,Y + LDA $0103,Y + SBC $0107,Y + LDA $0104,Y + SBC $0108,Y + TXS + BVC :+ + EOR #$80 +: BPL :+ + JMP INC3NEXTOP +: JMP BRANCHNEXTOP +JSUB: LDA EXECPC ; GET INSTRUCTION PTR + LDX EXECPC+1 + CLC ; CALC RETURN ADDRESS + ADC #$03 + BCC :+ + INX +: SEC ; CALC OFFSET FROM CODEPTR + SBC EXECCODEBASE + TAY + TXA + SBC EXECCODEBASE+1 + PHA ; HIWORD DON'T CARE + PHA + PHA + TYA + PHA + JMP BRANCHNEXTOP +RET: LDB_BYTECODE + TAY + LDA (BP0),Y + CLC + ADC EXECCODEBASE + STA EXECPC + LDA (BP1),Y + ADC EXECCODEBASE+1 + STA EXECPC+1 + JMP NEXTOP +TABLESWITCH: LDA EXECPC + LDX EXECPC+1 + CLC ; SKIP PADDING + ADC #$04 + AND #$FC + BCC :+ + INX +: STA TABLEPTR + STX TABLEPTR+1 + AUXMEM_RDACCESS_ON + TSX + LDY #$0B ; CHECK HIGH VALUE + LDA (TABLEPTR),Y + CMP $0101,X + DEY + LDA (TABLEPTR),Y + SBC $0102,X + DEY + LDA (TABLEPTR),Y + SBC $0103,X + DEY + LDA (TABLEPTR),Y + SBC $0104,X + BVC :+ + EOR #$80 +: BMI TABLEDEF ; HIGH VALUE LESS THAN INDEX, USE DEFAULT + DEY ; LDY #$08 SUBTRACT LOW VALUE + LDA $0101,X + SEC + SBC (TABLEPTR),Y + STA TABLEIDX + DEY + LDA $0102,X + SBC (TABLEPTR),Y + STA TABLEIDX+1 + DEY + LDA $0103,X + SBC (TABLEPTR),Y + STA TABLEIDX+2 + DEY + LDA $0104,X + SBC (TABLEPTR),Y + STA TABLEIDX+3 + BMI TABLEDEF ; BELOW LOW VALUE, USE DEFAULT + LDA TABLEIDX + CLC ; ADD OFFSET FOR DEF/HI/LO + ADC #$03 + BCC :+ + INC TABLEIDX+1 +: ASL ; SHIFT FROM INDEX TO OFFSET + ROL TABLEIDX+1 + ASL + ROL TABLEIDX+1 + CLC + ADC TABLEPTR + STA TABLEPTR + LDA TABLEIDX+1 + ADC TABLEPTR+1 + STA TABLEPTR+1 + LDY #$03 +TABLEJMP: INX + INX + INX + INX + TXS + LDA (TABLEPTR),Y + DEY + CLC + ADC EXECPC + STA EXECPC + LDA (TABLEPTR),Y + ADC EXECPC+1 + STA EXECPC+1 + AUXMEM_RDACCESS_OFF + JMP NEXTOP +TABLEDEF: LDY #$03 ; OUT OF RANGE, USE DEFAULT OFFSET + BNE TABLEJMP +LOOKUPSWITCH: LDA EXECPC + LDX EXECPC+1 + CLC ; SKIP PADDING + ADC #$04 + AND #$FC + BCC :+ + INX +: STA TABLEPTR + STX TABLEPTR+1 + CLC ; CALC POINTER TO FIRST TEST + ADC #$08 + BCC :+ + INX +: STA MATCHPTR + STX MATCHPTR+1 + AUXMEM_RDACCESS_ON + LDY #$07 + LDA (TABLEPTR),Y ; COPY NUM LOOKUPS + DEY + STA MATCHCNT + LDA (TABLEPTR),Y + TAX + INX + STX MATCHCNT+1 + TSX +LOOKUPMATCH: LDY #$03 ; CHECK FOR MATCH + LDA $0101,X + CMP (MATCHPTR),Y + BNE LOOKUPNEXT + DEY + LDA $0102,X + CMP (MATCHPTR),Y + BNE LOOKUPNEXT + DEY + LDA $0103,X + CMP (MATCHPTR),Y + BNE LOOKUPNEXT + DEY + LDA $0104,X + CMP (MATCHPTR),Y + BNE LOOKUPNEXT + LDY #$07 +LOOKUPJMP: INX ; FOUND MATCH + INX + INX + INX + TXS + LDA (MATCHPTR),Y + DEY + CLC + ADC EXECPC + STA EXECPC + LDA (MATCHPTR),Y + ADC EXECPC+1 + STA EXECPC+1 + AUXMEM_RDACCESS_OFF + JMP NEXTOP +LOOKUPNEXT: LDA MATCHPTR + CLC ; NEXT MATCH + ADC #$08 + STA MATCHPTR + BCC :+ + INC MATCHPTR+1 +: DEC MATCHCNT + BNE LOOKUPMATCH + DEC MATCHCNT+1 + BNE LOOKUPMATCH +LOOKUPDEF: LDA TABLEPTR ; NO MATCH, USE DEFAULT OFFSET + STA MATCHPTR + LDA TABLEPTR+1 + STA MATCHPTR+1 + LDY #$03 + BNE LOOKUPJMP +IRETURN: +LRETURN: +FRETURN: +DRETURN: +RETURN: LDA #$00 ; NULL MATCH REF + TAX + JMP EXIT_METHOD +ARETURN: TSX ; MATCH REF ON STACK + LDA $0101,X + TAY + LDA $0102,X + TAX + TYA + JMP EXIT_METHOD +GETSTATIC: LDW_BYTECODE + JSR GETFIELDPTR + LDY #FIELDSTATICVAL+3 + LDA (FIELDPTR),Y + DEY + PHA + LDA (FIELDPTR),Y + DEY + PHA + LDA (FIELDPTR),Y + DEY + PHA + LDA (FIELDPTR),Y + PHA + JMP INC3NEXTOP +GETFIELD: LDW_BYTECODE + JSR GETFIELDPTR ; GET INSTANCE FIELD OFFSET + LDY #FIELDINSTOFFSET+1 + LDA (FIELDPTR),Y + DEY + STA TARGETOFFSET+1 + LDA (FIELDPTR),Y + DEY + STA TARGETOFFSET + LDA (FIELDPTR),Y + STA TARGETTYPE + PLA ; GET OBJECT INSTANCE OFF STACK + TAY + PLA + TAX + PLA + PLA + TYA + JSR HMEM_PTR + CLC + ADC TARGETOFFSET + STA FIELDPTR + TXA + ADC TARGETOFFSET+1 + STA FIELDPTR+1 + LDA TARGETTYPE + CMP #T_BYTE + BEQ GETS8FLD + CMP #T_BOOLEAN + BEQ GETS8FLD + CMP #T_SHORT + BEQ GETS16FLD + CMP #T_CHAR + BEQ GETU16FLD + LDY #$03 + LDA (FIELDPTR),Y + DEY + PHA + LDA (FIELDPTR),Y + DEY + PHA + LDA (FIELDPTR),Y + DEY + PHA + LDA (FIELDPTR),Y + PHA + JMP INC3NEXTOP +GETS8FLD: LDY #$00 + LDA (FIELDPTR),Y + TAX + AND #$80 + BPL :+ + LDA #$FF +: PHA + PHA + PHA + TXA + PHA + JMP INC3NEXTOP +GETU16FLD: LDY #$01 + LDA (FIELDPTR),Y + DEY + TAX + LDA #$00 + BEQ :+ +GETS16FLD: LDY #$01 + LDA (FIELDPTR),Y + DEY + TAX + AND #$80 + BPL :+ + LDA #$FF +: PHA + PHA + TXA + PHA + LDA (ARRAYPTR),Y + PHA + JMP INC3NEXTOP +PUTSTATIC: LDW_BYTECODE + JSR GETFIELDPTR + LDY #FIELDTYPE + LDA (FIELDPTR),Y + INY + CMP #T_REF|$80 + BEQ PUTASTAT + PLA + STA (FIELDPTR),Y + INY + PLA + STA (FIELDPTR),Y + INY + PLA + STA (FIELDPTR),Y + INY + PLA + STA (FIELDPTR),Y + JMP INC3NEXTOP +PUTASTAT: TSX + LDY #FIELDSTATICVAL+3 + JSR PUTREF + PLA + PLA + PLA + PLA + JMP INC3NEXTOP +; +; COMMON PUT FIELD/STATIC REF +; +PUTREF: LDA (FIELDPTR),Y + PHA + LDA $0104,X + STA (FIELDPTR),Y + DEY + LDA (FIELDPTR),Y + PHA + LDA $0103,X + AND #$7F ; CLEAR NO_INC FLAG + STA (FIELDPTR),Y + DEY + LDA (FIELDPTR),Y + PHA + LDA $0102,X + STA (FIELDPTR),Y + DEY + LDA (FIELDPTR),Y + PHA + LDA $0101,X + STA (FIELDPTR),Y + LDA $0103,X + BMI NOREFINC + LDA $0102,X + BEQ NOREFINC + LDY $0101,X + TAX + TYA + JSR HMEM_REF_INC ; INC REF COUNT OF NEW OBJECT +NOREFINC: JSR UNREF_OBJECT ; UNREF PREV OBJECT + RTS +PUTAFLD: LDY #$03 + JSR PUTREF + TSX + JMP PUTFLDEXIT +PUTFIELD: LDW_BYTECODE + JSR GETFIELDPTR ; GET INSTANCE FIELD OFFSET + LDY #FIELDINSTOFFSET+1 + LDA (FIELDPTR),Y + DEY + STA TARGETOFFSET+1 + LDA (FIELDPTR),Y + DEY + STA TARGETOFFSET + LDA (FIELDPTR),Y + AND #$0F + STA TARGETTYPE + TSX ; EXTRACT OBJECT INSTANCE FROM STACK + LDA $0105,X + TAY + LDA $0106,X + TAX + TYA + JSR HMEM_PTR + CLC + ADC TARGETOFFSET + STA FIELDPTR + TXA + ADC TARGETOFFSET+1 + STA FIELDPTR+1 + LDY #$00 + TSX + LDA TARGETTYPE + CMP #T_REF + BEQ PUTAFLD + AND #$03 + BEQ PUT8FLD + CMP #$01 + BEQ PUT16FLD +PUT32FLD: PLA + STA (FIELDPTR),Y + INY + PLA + STA (FIELDPTR),Y + INY +PUT16FLD: PLA + STA (FIELDPTR),Y + INY +PUT8FLD: PLA + STA (FIELDPTR),Y +PUTFLDEXIT: TXA ; POP DATA AND OBJECT INSTANCE OFF STACK + CLC + ADC #$08 + TAX + TXS + JMP INC3NEXTOP +; +; LOOKUP METHOD IN CONSTPTR +; +LOOKUPMETHODREF: JSR LOOKUPREF +LOOKUPMETHOD: JSR RESOLVE_METHOD ; LOOK IT UP + BCS :+ + RTS +: LDA #9 ; NO SUCH METHOD + JMP SYSTHROW +INVOKESPECIAL: LDW_BYTECODE + JSR GETMETHODPTR + JMP INVOKE_SPECIAL +INVOKESTATIC: LDW_BYTECODE + JSR GETMETHODPTR + JMP INVOKE_STATIC +INVOKEVIRTUAL: LDW_BYTECODE + JSR GETMETHODPTR + JMP INVOKE_VIRTUAL +INVOKEINTERFACE: LDW_BYTECODE + INC EXECPC ; INCREMENT PAST TWO DUMMY PARAMETERS + BNE :+ + INC EXECPC+1 +: INC EXECPC + BNE :+ + INC EXECPC+1 +: JSR LOOKUPREF ; GET NAME/TYPE - CLASS NOT DEFINED YET + JSR SCANDESCPARMS + TSX + STX TARGETCLASS + CLC + ADC TARGETCLASS + TAX + LDA $0103,X ; GET CLASS FROM *THIS* PARAMTER +; AND #$7F + TAY + JSR LOOKUPMETHOD ; MUST LOOKUP METHOD EVERY TIME + JMP INVOKE_VIRTUAL +NEW: LDW_BYTECODE + JSR LOOKUPCLASSIDX + JSR HMEM_PTR + STA TMPTR + STX TMPTR+1 + LDY #CLASSINSTSIZE+1 ; GET INSTANCE SIZE FOR THIS CLASS + LDA (TMPTR),Y + DEY + TAX + LDA (TMPTR),Y + LDY #$00 ; SET ZERO REF COUNT - INC DURING STORE + JSR HMEM_ALLOC + JSR HMEM_CLR ; CLEAR INSTANCE MEMORY + TAY + LDA TARGETCLASS + PHA ; PUSH OBJECT ICLASS IN HIWORD + PHA + TXA ; PUSH OBJECT INSTANCE IN LOWORD + PHA + TYA + PHA + JMP INC3NEXTOP +NEWARRAY: LDB_BYTECODE ; ARRAY TYPE + JMP ARRAY_ALLOC +ANEWARRAY: LDW_BYTECODE ; ARRAY CLASS + JMP REFARRAY_ALLOC +MULTINEWARRAY: LDW_BYTECODE + JSR SETCONSTPTR ; ARRAY CLASS + LDY #$03 + LDB_BYTECODE ; ARRAY DEPTH TO ALLOCATE + JMP MULTIARRAY_ALLOC +CHECKCAST: TSX + LDA $0101,X + ORA $0102,X + BNE :+ + STA $0103,X + STA $0104,X + BEQ :++ +: LDW_BYTECODE + JSR LOOKUPCLASSIDX + TSX + LDA $0103,X + AND #$7F ; MASK OFF NOINC FLAG + JSR CLASS_OF + BCC :+ + LDA #24 ; CLASS CAST + JMP SYSTHROW +: JMP INC3NEXTOP +INSTANCEOF: LDW_BYTECODE + JSR LOOKUPCLASSIDX + CLC ;SEC ; SET CARRY = FALSE + TSX + LDA $0101,X ; CHECK FOR NULL REF + ORA $0102,X + BEQ :+ + LDA $0103,X + AND #$7F ; MASK OFF NOINC FLAG + JSR CLASS_OF + TSX + LDA #$00 +: STA $0104,X + STA $0103,X + STA $0102,X + ROL ; PUT CARRY INTO LSB + EOR #$01 ; INVERT TO MATCH TRUTH + STA $0101,X + JMP INC3NEXTOP +;* +;* MISC ROTUINES THAT DIDN'T FIT IN LC +;* +MONITORENTER: PLA + TAY + PLA + TAX + PLA + PLA + TYA + JSR THREAD_LOCK + JMP INCNEXTOP +MONITOREXIT: PLA + TAY + PLA + TAX + PLA + PLA + TYA + JSR THREAD_UNLOCK + JMP INCNEXTOP +SYSTHROW: JSR THROW_SYSEXCEPTN ; THROW SYSTEM EXCEPTION +RETHROW: LDA CURRENTEXCEPTN+3 ; RE-THROW AN EXCEPTION + PHA + LDA CURRENTEXCEPTN+2 + PHA + LDA CURRENTEXCEPTN+1 + PHA + LDA CURRENTEXCEPTN + PHA +ATHROW: TSX ; MATCH REF ON STACK + LDA $0101,X + STA RETURN_REF + LDA $0102,X + STA RETURN_REF+1 + LDA #$80 ; SET EXCEPTION FLAG + STA EXECFLAGS +.IFDEF DEBUG_EXCEPT +; PERR "EXCEPTION THROWN IN METHOD" +; JSR KBWAIT +.ENDIF + LDA HEXECFRAME ; SET FRAME POINTER + LDX HEXECFRAME+1 + JSR HMEM_PTR + STA FRAMEPTR + STX FRAMEPTR+1 + LDY #FRAMEPC + LDA EXECPC ; SAVE INSTRUCTION PTR IN CURRENT FRAME + SEC ; SAVE AS OFFSET FROM CODEPTR + SBC EXECCODEBASE + STA (FRAMEPTR),Y + INY + LDA EXECPC+1 + SBC EXECCODEBASE+1 + STA (FRAMEPTR),Y + JMP CATCH_EXCEPTN +;* +;* THIS ALLOWS A BYTECODE SEQUENCE TO BE SUBSTITUTED FOR A SINGLE BYTECODE OPERATION +;* SEE FREM +;* +EXECUCODE: LDY EXECPC ; INJECT BYTECODE INTO OPERATION + STY UCODEPC + LDY EXECPC+1 + STY UCODEPC+1 + STA EXECPC + STX EXECPC+1 + LDA OPCNT ; MAKE SURE NO RESCHED HAPPENS + AND #$F0 + STA OPCNT + JMP EXECBYTECODES ; EXEC BYTECODE +UCODERET: LDA UCODEPC ; HIJACK UNUSED BYTECODE $BA + STA EXECPC + LDA UCODEPC+1 + STA EXECPC+1 + STY UCODEPC + STY UCODEPC+1 + JMP INCNEXTOP +UCODEPC: .BYTE $00,$00 ; SAVED PC + +INTERP_END EQU * diff --git a/src/org/vm02/cui/Launcher.java b/src/org/vm02/cui/Launcher.java new file mode 100755 index 0000000..f6cadba --- /dev/null +++ b/src/org/vm02/cui/Launcher.java @@ -0,0 +1,340 @@ +package org.vm02.cui; +import apple2.*; + +public class Launcher extends cuiApp +{ + public static String Months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + private static byte infoBuilder[] = {(byte)'T', (byte)'Y', (byte)'P', + (byte)' ', (byte)' ', (byte)' ', + (byte)'0', (byte)'0', (byte)'-', (byte)'J', (byte)'a', (byte)'n', (byte)'-', (byte)'0', (byte)'0', + (byte)' ', (byte)' ', (byte)' ', + (byte)'0', (byte)'0', (byte)':', (byte)'0', (byte)'0', (byte)' ', (byte)'A', (byte)'M'}; + private int ioBuffer; + private String dirPrefix, launchCmd; + private String dirFileName[]; + private byte dirFileType[]; + private String dirFileInfo[]; + private short dirFileLength[]; + private short dirAuxType[]; + private short dirModDate[]; + private cuiListBox fileList; + private cuiTextEntry params; + + public void start(String path) + { + super.start(); + ioBuffer = ProDOS.allocIOBuffer(); + dirPrefix = ProDOS.getPrefix(); + if (path != null) + { + if (path.charAt(path.length() - 1) != '/') + path += '/'; + if (path.charAt(0) == '/') + dirPrefix = path; + else + dirPrefix += path; + } + cui.fillRect(2, 20, 14, 3, 0x80 | ' ', 0x80 | ' '); + cui.drawString(4, 21, "Parameters:"); + params = new cuiTextEntry(17, 21, 60, true, 1, (cuiControl)this); + cuiButton volBttn = new cuiButton(61, 2, 16, 1, "Volumes:TAB", true, (char)cui.KEY_TAB, 1, (cuiControl)this); + cuiButton upBttn = new cuiButton(61, 6, 16, 1, "Up Level:ESC", true, (char)cui.KEY_ESC, 2, (cuiControl)this); + cuiButton runBttn = new cuiButton(61, 10, 16, 1, "Launch:OA-L", true, (char)(cui.MODKEY_OPENAPPLE|'l'), 3, (cuiControl)this); + cuiButton exitBttn = new cuiButton(61, 17, 16, 1, "Exit:OA-X", true, (char)(cui.MODKEY_OPENAPPLE|'x'), 4, (cuiControl)this); + dirLoadList(); + } + public void stop() + { + ProDOS.freeIOBuffer(ioBuffer); + super.stop(); + super.chain(launchCmd); + } + public boolean event(int msg, int msgData) + { + switch (msg) + { + case EVENT_KEYPRESS: + switch (cui.codeKey) + { + case cui.KEY_ARROWLEFT: + dirExit(); + return true; + case cui.KEY_ARROWRIGHT: + dirEnter(fileList.getHilite()); + return true; + case cui.MODKEY_OPENAPPLE | cui.KEY_TAB: + if (focus != null) + focus.nextFocus(this.next); + else + this.nextFocus(this.next); + return true; + } + break; + case cuiListBox.EVENT_LISTITEMSELECT: + if (!dirEnter(msgData)) + launch(msgData); + return true; + case cuiListBox.EVENT_LISTITEMDRAW: + case cuiListBox.EVENT_LISTITEMDRAWHILITE: + int itemX = (msgData >> 24) + 1; + int itemY = (msgData >> 16) & 0xFF; + int itemWidth = (msgData >> 8) & 0xFF; + int itemIndex = msgData & 0xFF; + if (dirFileType[itemIndex] == 0x0F) // Is it a directory? + cui.drawMouseString(itemX, itemY, "XY"); + else + cui.drawString(itemX, itemY, dirFileType[itemIndex] == (byte)0xED ? " *" : " "); + if (msg == cuiListBox.EVENT_LISTITEMDRAWHILITE) + { + cui.drawInverseString(itemX + 3, itemY, 0, 16, dirFileName[itemIndex], ' '); + cui.drawInverseString(itemX + 19, itemY, dirFileInfo[itemIndex]); + } + else + { + cui.drawString(itemX + 3, itemY, 0, 16, dirFileName[itemIndex], 0x80 | ' '); + cui.drawString(itemX + 19, itemY, dirFileInfo[itemIndex]); + } + return true; + case cuiButton.EVENT_BUTTONPRESS: + switch (msgData) + { + case 1: + dirPrefix = "/"; + dirLoadList(); + return true; + case 2: + dirExit(); + return true; + case 3: + launch(fileList.getHilite()); + return true; + case 4: + quit = true; + return true; + } + case cuiTextEntry.EVENT_TEXTENTRY: + launch(fileList.getHilite()); + return true; + + } + return false; + } + public boolean launch(int index) + { + if (dirFileType[index] == (byte)0xED) + { + launchCmd = dirPrefix + dirFileName[index] + " " + params.getText(); + quit = true; + return true; + } + return false; + } + public boolean dirEnter(int index) + { + if (dirFileType[index] == (byte)0x0F) // Is it a directory? + { + dirPrefix = dirPrefix + dirFileName[index] + "/"; + dirLoadList(); + return true; + } + return false; + } + public void dirExit() + { + if (dirPrefix != "/") + { + byte prefixChars[] = new byte[dirPrefix.length()]; + int lastDir = 0; + for (int i = dirPrefix.length() - 2; i >= 0; i--) + { + prefixChars[i] = (byte)dirPrefix.charAt(i); + if (prefixChars[i] == '/' && lastDir == 0) + lastDir = i + 1; + } + if (lastDir > 1) + dirPrefix = new String(prefixChars, 0, lastDir); + else + dirPrefix = "/"; + dirLoadList(); + } + } + public void dirLoadList() + { + byte prevCursor = cui.setMouseCursor('C'); // hour glass + if (fileList != null) fileList.delete(); + dirFileName = null; + dirFileType = null; + dirFileInfo = null; + if (dirPrefix == null || dirPrefix == "/") + { + dirFileName = ProDOS.online(); + dirFileType = new byte[dirFileName.length]; + dirFileInfo = new String[dirFileName.length]; + for (int i = 0; i < dirFileType.length; i++) + { + dirFileType[i] = 0x0F; // set to directory + dirFileInfo[i] = "VOL "; // no mod time + } + } + else + { + int entryOffset, entriesBlock = 0, entryLength = 0; + int refNum = ProDOS.open(dirPrefix, ioBuffer); + if (refNum < 0) + { + cui.setMouseCursor(prevCursor); + cuiMessageBox errBox = new cuiMessageBox("ProDOS Error", "Unable to read directory:", dirPrefix, cuiMessageBox.MSGBOX_OK); + errBox.reply(); + quit = true; + return; + } + byte dataBuffer[] = new byte[512]; + int fileCount = 0; + int entry = 0; + int firstBlock = 1; + do + { + if (ProDOS.read(refNum, dataBuffer) == 512) + { + if (firstBlock == 1) + { + entryLength = dataBuffer[0x23] & 0xFF; + entriesBlock = dataBuffer[0x24] & 0xFF; + fileCount = (dataBuffer[0x25] & 0xFF) + | ((dataBuffer[0x26] & 0xFF) << 8); + //cui.drawString(10, 0, "Dir file count: " + fileCount + " "); + if (fileCount > 64) fileCount = 64; + if (fileCount > 0) + { + dirFileName = new String[fileCount]; + dirFileType = new byte[fileCount]; + dirFileInfo = new String[fileCount]; + } + entryOffset = entryLength + 4; + } + else + entryOffset = 4; + for (int i = firstBlock; i < entriesBlock; i++) + { + int typeLen = dataBuffer[entryOffset]; + if (typeLen != 0) + { + dirFileName[entry] = new String(dataBuffer, entryOffset + 1, typeLen & 0x0F); + dirFileType[entry] = dataBuffer[entryOffset + 0x10]; + int modDate = (dataBuffer[entryOffset + 0x21] & 0xFF) + | ((dataBuffer[entryOffset + 0x22] & 0xFF) << 8); + int modTime = (dataBuffer[entryOffset + 0x23] & 0xFF) + | ((dataBuffer[entryOffset + 0x24] & 0xFF) << 8); + dirFileInfo[entry] = infoString(dirFileType[entry], modDate, modTime); + entry++; + if (--fileCount == 0) break; + } + entryOffset += entryLength; + } + firstBlock = 0; + } + else + fileCount = 0; + } while (fileCount > 0); + ProDOS.close(refNum); + } + fileList = new cuiListBox(3, 2, 50, 16, dirFileName.length, (cuiControl)this); + cui.drawInverseString(3, 1, dirPrefix); + fileList.setFocus(); + cui.setMouseCursor(prevCursor); + } + public String infoString(byte type, int date, int time) + { + byte infoChars[] = infoBuilder; + switch (type) + { + case (byte)0x04: + infoChars[0] = (byte)'T'; + infoChars[1] = (byte)'X'; + infoChars[2] = (byte)'T'; + break; + case (byte)0x06: + infoChars[0] = (byte)'B'; + infoChars[1] = (byte)'I'; + infoChars[2] = (byte)'N'; + break; + case (byte)0x0F: + infoChars[0] = (byte)'D'; + infoChars[1] = (byte)'I'; + infoChars[2] = (byte)'R'; + break; + case (byte)0xED: + infoChars[0] = (byte)'J'; + infoChars[1] = (byte)'V'; + infoChars[2] = (byte)'M'; + break; + case (byte)0xFC: + infoChars[0] = (byte)'B'; + infoChars[1] = (byte)'A'; + infoChars[2] = (byte)'S'; + break; + case (byte)0xFD: + infoChars[0] = (byte)'V'; + infoChars[1] = (byte)'A'; + infoChars[2] = (byte)'R'; + break; + case (byte)0xFE: + infoChars[0] = (byte)'R'; + infoChars[1] = (byte)'E'; + infoChars[2] = (byte)'L'; + break; + case (byte)0xFF: + infoChars[0] = (byte)'S'; + infoChars[1] = (byte)'Y'; + infoChars[2] = (byte)'S'; + break; + default: + infoChars[0] = (byte)'$'; + infoChars[1] = (byte)(((type >> 4) & 0x0F) + '0'); + if (infoChars[1] > '9') + infoChars[1] += (byte)('A' - '9' - 1); + infoChars[2] = (byte)((type & 0x0F) + '0'); + if (infoChars[2] > '9') + infoChars[2] += (byte)('A' - '9' - 1); + } + int year = (date >> 9) & 0x7F; + int month = ((date >> 5) & 0x0F) - 1; + int day = date & 0x1F; + if (month < 0 || month > 11) // bogus month + { + year = 0; + month = 0; + day = 0; + } + infoChars[6] = (byte)((day / 10) + '0'); + infoChars[7] = (byte)((day % 10) + '0'); + infoChars[9] = (byte)Months[month].charAt(0); + infoChars[10] = (byte)Months[month].charAt(1); + infoChars[11] = (byte)Months[month].charAt(2); + infoChars[13] = (byte)((year / 10) + '0'); + infoChars[14] = (byte)((year % 10) + '0'); + int hour = (time >> 8) & 0x1F; + int minute = time & 0x3F; + if (hour > 12) + { + hour -= 12; + infoChars[24] = (byte)'P'; + } + else + { + infoChars[24] = (byte)'A'; + } + infoChars[18] = (byte)((hour / 10) + '0'); + infoChars[19] = (byte)((hour % 10) + '0'); + infoChars[21] = (byte)((minute / 10) + '0'); + infoChars[22] = (byte)((minute % 10) + '0'); + return new String(infoChars, 0, 26); + } + public static void main(String args[]) + { + Launcher launchApp = new Launcher(); + launchApp.start((args.length > 0) ? args[0] : (String)null); + launchApp.run(8); + launchApp.stop(); + } +} \ No newline at end of file diff --git a/src/org/vm02/cui/cui.java b/src/org/vm02/cui/cui.java new file mode 100755 index 0000000..ef925e2 --- /dev/null +++ b/src/org/vm02/cui/cui.java @@ -0,0 +1,472 @@ +// +// java - character user interface +// +package org.vm02.cui; +import apple2.*; + +public class cui +{ + // + // PARAM INDECES + // + private final static byte OP = 0; + private final static byte X = 1; + private final static byte Y = 2; + private final static byte WIDTH = 3; + private final static byte HEIGHT = 4; + private final static byte OFFSET = 3; + private final static byte COUNT = 4; + private final static byte FREQUENCY = 1; + private final static byte DURATION = 2; + private final static byte TIMBRE = 3; + private final static byte XDST = 5; + private final static byte YDST = 6; + private final static byte CHAR_EVEN = 5; + private final static byte CHAR_ODD = 6; + private final static byte CURSOR = 7; + private final static byte FLAGS = 7; + private final static byte PARAMS = 8; + // + // OPS + // + private final static byte INIT = 0; + private final static byte EXIT = 1; + private final static byte FILLRECT = 2; + private final static byte SCROLLRECT = 3; + private final static byte PUTCHARS = 4; + private final static byte PUTSTR = 5; + private final static byte PUTINVSTR = 6; + private final static byte PUTMOUSESTR = 7; + private final static byte GETCHARS = 8; + private final static byte UPDATEMOUSE = 10; + private final static byte SHOWMOUSE = 11; + private final static byte HIDEMOUSE = 12; + private final static byte TONE = 16; + // + // EVENTS + // + public final static int INPUT_UNKNOWN = 0x00; + public final static int INPUT_KEYBOARD = 0x01; + public final static int INPUT_MOUSE = 0x0E; + public final static int INPUT_MOUSEBTTN = 0x06; + public final static int INPUT_MOUSEBTTNDOWN = 0x02; + public final static int INPUT_MOUSEBTTNUP = 0x04; + public final static int INPUT_MOUSEMOVE = 0x08; + public final static int INPUT_TIMEOUT = 0x80; + // + // KEY CODES + // + public final static char KEY_TAB = 0x09; + public final static char KEY_ARROWLEFT = 0x08; + public final static char KEY_ARROWRIGHT = 0x15; + public final static char KEY_ARROWUP = 0x0B; + public final static char KEY_ARROWDOWN = 0x0A; + public final static char KEY_RETURN = 0x0D; + public final static char KEY_ESC = 0x1B; + public final static char KEY_SPACEBAR = 0x20; + public final static char KEY_DELETE = 0x7F; + // + // KEY CODE MODS + // + public final static char MODKEY_OPENAPPLE = 0x0080; + public final static char MODKEY_CLOSEAPPLE = 0x0100; + + + private static byte selectMask = 0x08; // CONSOLE by default + private static byte selectMouse = 0x00; // CONSOLE by default + private static byte cursorMouse; + private static int mouseSlot, mouseCtrl, ctrlRead, addrXPos, addrYPos, addrStatus; + protected static byte staticParams[] = new byte[PARAMS]; + public static int timeMouseEvent; + public static byte xMouse, yMouse, bttnMouse; + public static char codeKey; + public static byte leftBorder = (byte)'Z'; + public static byte rightBorder = (byte)'_'; + public static byte topBorder = (byte)(0x80|'_'); + public static byte bottomBorder = (byte)'L'; + public static byte titleBar = (byte)(0x80|'_'); + + public static int select() throws InterruptedException + { + return (vm02.call(selectMask, 0x80) & 0xFF); + } + public static int updateMouse() + { + int update = 0; + int sxy = vm02.call(ctrlRead, mouseCtrl); // CALL_FW ReadMouse + if ((sxy & 0x80) != (bttnMouse & 0x80)) + { + bttnMouse = (byte)(sxy & 0x80); + update = (bttnMouse == 0) ? INPUT_MOUSEBTTNUP : INPUT_MOUSEBTTNDOWN; + timeMouseEvent = (vm02.call(0, 0x3C) << 16) | (vm02.call(0, 0x3A) & 0xFFFF); + } + if ((sxy & 0x20) != 0) + { + int x = (sxy & 0x0000FF00) >> 9; + int y = (sxy & 0x00FF0000) >> 18; + if (x >= 80) x = 79; + if (y >= 24) y = 23; + if (x != xMouse || y != yMouse) + { + byte params[] = staticParams; + xMouse = (byte)x; + yMouse = (byte)y; + params[OP] = UPDATEMOUSE; + params[X] = (byte)x; + params[Y] = (byte)y; + params[CURSOR] = cursorMouse; + cuiDriver.dispatch(params, null); + update |= INPUT_MOUSEMOVE; + } + } + return update; + } + public static int getInputEvent(int eventMask, int timeOut) + { + int inputSlot, inputEvent; + int curTID = vm02.call(0, 0x1C) & 0x00FF0000; // THREAD_GET_CURRENT + if (timeOut < 0) + { + vm02.call(curTID, 0x22); // LINK_THREADNOTIMEOUT + } + else + { + vm02.call(curTID | (timeOut & 0xFFFF), 0x1E); // THREAD_SETTIMEOUTL + vm02.call(curTID | (timeOut >> 16 ), 0x20); // THREAD_SETTIMEOUTH + } + do + { + inputEvent = 0; + try + { + inputSlot = select(); + } + catch (InterruptedException e) + { + return INPUT_TIMEOUT; + } + if ((inputSlot & selectMouse) != 0) // MOUSE event + inputEvent = updateMouse(); + if ((inputSlot & 0x08) != 0) // KEYBOARD event + { + codeKey = (char)(vm02.call(0, 0x76) & 0xFF); // KEYBD_READ + // moved following into console driver + // | (vm02.peekByte(0xC061) & 0x80)); // PB0 (OPEN-APPLE) + // | ((vm02.peekByte(0xC062) & 0x80) << 1));// PB1 (CLOSED-APPLE OR OPTION) + inputEvent |= INPUT_KEYBOARD; + } + } while ((inputEvent & eventMask) == 0); + return (inputEvent & eventMask); + } + public static byte[][] saveRect(int x, int y, int width, int height) + { + byte params[] = staticParams; + byte saveUnder[][] = new byte[height][width]; + params[OP] = GETCHARS; + params[X] = (byte)x; + params[OFFSET] = 0; + params[COUNT] = (byte)width; + while (--height >= 0) + { + params[Y] = (byte)y++; + cuiDriver.dispatch(params, saveUnder[height]); + } + return saveUnder; + } + public static void restoreRect(int x, int y, byte saveUnder[][]) + { + byte params[] = staticParams; + int height = saveUnder.length; + params[OP] = PUTCHARS; + params[X] = (byte)x; + params[OFFSET] = 0; + params[COUNT] = (byte)saveUnder[0].length; + while (--height >= 0) + { + params[Y] = (byte)y++; + cuiDriver.dispatch(params, saveUnder[height]); + } + } + public static void scrollRect(int x, int y, int width, int height, int yDst) + { + byte params[] = staticParams; + params[OP] = SCROLLRECT; + params[X] = (byte)x; + params[Y] = (byte)y; + params[WIDTH] = (byte)width; + params[HEIGHT] = (byte)height; + params[YDST] = (byte)yDst; + cuiDriver.dispatch(params, null); + } + public static void fillRect(int x, int y, int width, int height, int charEven, int charOdd) + { + byte params[] = staticParams; + params[OP] = FILLRECT; + params[X] = (byte)x; + params[Y] = (byte)y; + params[WIDTH] = (byte)width; + params[HEIGHT] = (byte)height; + params[CHAR_EVEN] = (byte)charEven; + params[CHAR_ODD] = (byte)charOdd; + cuiDriver.dispatch(params, null); + } + public static void frameRect(int x, int y, int width, int height, int charFill, boolean borderTop, String title) + { + byte params[] = staticParams; + params[OP] = FILLRECT; + if (charFill >= 0) + { + params[X] = (byte)(x + 1); + params[Y] = (byte)(y + 1); + params[WIDTH] = (byte)(width - 2); + params[HEIGHT] = (byte)(height - 2); + params[CHAR_EVEN] = (byte)charFill; + params[CHAR_ODD] = (byte)charFill; + cuiDriver.dispatch(params, null); + } + // LEFT + params[X] = (byte)x; + params[Y] = (byte)(y + 1); + params[WIDTH] = 1; + params[HEIGHT] = (byte)(height - 2); + params[CHAR_EVEN] = leftBorder; + params[CHAR_ODD] = leftBorder; + cuiDriver.dispatch(params, null); + // RIGHT + params[X] = (byte)(x + width - 1); + params[CHAR_EVEN] = rightBorder; + params[CHAR_ODD] = rightBorder; + cuiDriver.dispatch(params, null); + // BOTTOM + params[X] = (byte)x; + params[Y] = (byte)(y + height - 1); + params[WIDTH] = (byte)width; + params[HEIGHT] = 1; + params[CHAR_EVEN] = (byte)(0x80 | ' '); + params[CHAR_ODD] = (byte)(0x80 | ' '); + cuiDriver.dispatch(params, null); + params[X] = (byte)(x + 1); + params[WIDTH] = (byte)(width - 2); + params[CHAR_EVEN] = bottomBorder; + params[CHAR_ODD] = bottomBorder; + cuiDriver.dispatch(params, null); + if (borderTop) + { + // TOP + params[X] = (byte)x; + params[Y] = (byte)y; + params[WIDTH] = (byte)width; + params[CHAR_EVEN] = (byte)(0x80 | ' '); + params[CHAR_ODD] = (byte)(0x80 | ' '); + cuiDriver.dispatch(params, null); + params[X] = (byte)(x + 1); + params[WIDTH] = (byte)(width - 2); + params[CHAR_EVEN] = topBorder; + params[CHAR_ODD] = topBorder; + cuiDriver.dispatch(params, null); + if (title != null) + { + params[X] = (byte)(x + 1); + params[Y] = (byte)(y + 1); + params[WIDTH] = (byte)(width - 2); + params[CHAR_EVEN] = titleBar; + params[CHAR_ODD] = titleBar; + cuiDriver.dispatch(params, null); + // TITLE + params[OP] = PUTINVSTR; + params[X] = (byte)(x + ((width - title.length()) >> 1)); + params[OFFSET] = 0; + params[COUNT] = (byte)(title.length()); + cuiDriver.dispatch(params, title); + } + } + } + public static void drawString(int x, int y, String str) + { + byte params[] = staticParams; + params[OP] = PUTSTR; + params[X] = (byte)x; + params[Y] = (byte)y; + params[OFFSET] = 0; + params[COUNT] = (byte)str.length(); + cuiDriver.dispatch(params, str); + } + public static void drawString(int x, int y, int offset, int count, String str, int charFill) + { + byte params[] = staticParams; + params[OP] = PUTSTR; + params[X] = (byte)x; + params[Y] = (byte)y; + params[OFFSET] = (byte)offset; + params[COUNT] = (byte)count; + params[CHAR_EVEN] = (byte)charFill; + params[CHAR_ODD] = (byte)charFill; + cuiDriver.dispatch(params, str); + } + public static void drawInverseString(int x, int y, String str) + { + byte params[] = staticParams; + params[OP] = PUTINVSTR; + params[X] = (byte)x; + params[Y] = (byte)y; + params[OFFSET] = 0; + params[COUNT] = (byte)str.length(); + cuiDriver.dispatch(params, str); + } + public static void drawInverseString(int x, int y, int offset, int count, String str, int charFill) + { + byte params[] = staticParams; + params[OP] = PUTINVSTR; + params[X] = (byte)x; + params[Y] = (byte)y; + params[OFFSET] = (byte)offset; + params[COUNT] = (byte)count; + params[CHAR_EVEN] = (byte)charFill; + params[CHAR_ODD] = (byte)charFill; + cuiDriver.dispatch(params, str); + } + public static void drawMouseString(int x, int y, String str) + { + byte params[] = staticParams; + params[OP] = PUTMOUSESTR; + params[X] = (byte)x; + params[Y] = (byte)y; + params[OFFSET] = 0; + params[COUNT] = (byte)str.length(); + cuiDriver.dispatch(params, str); + } + public static void drawMouseString(int x, int y, int offset, int count, String str, int charFill) + { + byte params[] = staticParams; + params[OP] = PUTMOUSESTR; + params[X] = (byte)x; + params[Y] = (byte)y; + params[OFFSET] = (byte)offset; + params[COUNT] = (byte)count; + params[CHAR_EVEN] = (byte)charFill; + params[CHAR_ODD] = (byte)charFill; + cuiDriver.dispatch(params, str); + } + public static void putChars(int x, int y, byte chars[]) + { + byte params[] = staticParams; + params[OP] = PUTCHARS; + params[X] = (byte)x; + params[Y] = (byte)y; + params[OFFSET] = 0; + params[COUNT] = (byte)chars.length; + cuiDriver.dispatch(params, chars); + } + public static void putChars(int x, int y, int offset, int count, byte chars[]) + { + byte params[] = staticParams; + params[OP] = PUTCHARS; + params[X] = (byte)x; + params[Y] = (byte)y; + params[OFFSET] = (byte)offset; + params[COUNT] = (byte)count; + cuiDriver.dispatch(params, chars); + } + public static void getChars(int x, int y, byte chars[]) + { + byte params[] = staticParams; + params[OP] = GETCHARS; + params[X] = (byte)x; + params[Y] = (byte)y; + params[OFFSET] = 0; + params[COUNT] = (byte)chars.length; + cuiDriver.dispatch(params, chars); + } + public static void getChars(int x, int y, int offset, int count, byte chars[]) + { + byte params[] = staticParams; + params[OP] = GETCHARS; + params[X] = (byte)x; + params[Y] = (byte)y; + params[OFFSET] = (byte)offset; + params[COUNT] = (byte)count; + cuiDriver.dispatch(params, chars); + } + public static void showMouse() + { + staticParams[OP] = SHOWMOUSE; + staticParams[X] = (byte)xMouse; + staticParams[Y] = (byte)yMouse; + staticParams[CURSOR] = cursorMouse; + cuiDriver.dispatch(staticParams, null); + } + public static void hideMouse() + { + staticParams[OP] = HIDEMOUSE; + cuiDriver.dispatch(staticParams, null); + } + public static byte setMouseCursor(int newCursor) + { + byte oldCursor = cursorMouse; + cursorMouse = (byte)newCursor; + staticParams[OP] = UPDATEMOUSE; + staticParams[X] = (byte)xMouse; + staticParams[Y] = (byte)yMouse; + staticParams[CURSOR] = (byte)newCursor; + cuiDriver.dispatch(staticParams, null); + return oldCursor; + } + public static void tone(int frequency, int timbre, int duration) + { + staticParams[OP] = TONE; + staticParams[FREQUENCY] = (byte)frequency; + staticParams[TIMBRE] = (byte)timbre; + staticParams[DURATION] = (byte)duration; + cuiDriver.dispatch(staticParams, null); + } + public static void gc(int iterations) + { + vm02.call(iterations & 0xFFFF, 0x64); + } + public static boolean startUp() + { + staticParams[OP] = INIT; + if (cuiDriver.dispatch(staticParams, null) != 0) + return false; + // + // Search for mouse card + // + for (int slot = 1; slot < 8; slot++) + { + int mouse = vm02.call((1 << 19), 0x90 + (slot << 1)); // ID device + if ((mouse & 0x010000FF) == 0x20) // CARRY clear == valid device IOCTL, 0x20 == mouse card ID + { + mouseCtrl = 0x90 + (slot << 1); + mouseSlot = slot << 16; + ctrlRead = mouseSlot | (20 << 19); + addrXPos = vm02.peekWord(0x0370 + (slot << 1)) + 2; + addrYPos = addrXPos + 2; + addrStatus = addrYPos + 2; + if ((vm02.call(mouseSlot | (3 << 19), mouseCtrl) & 0x01000000) == 0) // open port + { + vm02.call(mouseSlot | (18 << 19) | 160, mouseCtrl); // clamp X + vm02.call(mouseSlot | (19 << 19) | 96, mouseCtrl); // clamp Y + selectMouse = (byte)(1 << slot); + selectMask |= selectMouse; + xMouse = 40; + yMouse = 12; + cursorMouse = (byte)'B'; + showMouse(); + } + } + } + return true; + } + public static void shutDown() + { + if (selectMouse != 0) + { + staticParams[OP] = HIDEMOUSE; + cuiDriver.dispatch(staticParams, null); + vm02.call(mouseSlot | (4<<19), mouseCtrl); // close port + } + staticParams[OP] = EXIT; + cuiDriver.dispatch(staticParams, null); + } + +} diff --git a/src/org/vm02/cui/cuiApp.java b/src/org/vm02/cui/cuiApp.java new file mode 100755 index 0000000..ffa0409 --- /dev/null +++ b/src/org/vm02/cui/cuiApp.java @@ -0,0 +1,67 @@ +// +// java - character user interface +// +package org.vm02.cui; +import apple2.*; + +public class cuiApp extends cuiControl +{ + protected boolean quit = false; // Not dead yet! + protected int inputMask = cui.INPUT_KEYBOARD | cui.INPUT_MOUSEBTTNDOWN; // Default input mask + protected int eventTimeOut = -1; // Default time-out + + public cuiApp() + { + super(0, 0, 80, 24, 0, (char)-1, 0, (cuiControl)null); + if (!cui.startUp()) + { + System.out.println("Reqiures 128K IIe or IIc"); + System.exit(-1); + } + cuiControl.list = this; + cuiControl.listTop = this; + } + protected void start() + { + cui.fillRect(0, 0, 80, 24, (byte)'V', (byte)'W'); + } + protected void stop() + { + cui.shutDown(); + } + protected void chain(String chainCmd) + { + if (chainCmd != null) + { + int stringptr = vm02.call(vm02.refAsBits((Object)chainCmd), 0x0E) & 0xFFFF; // HMEM_LOCK + vm02.call(stringptr + 1, 0x3E); // MEMSRC + vm02.call(0x0200, 0x40); // MEMDST + vm02.call(chainCmd.length(), 0x42); // MEMCPY + vm02.call(vm02.refAsBits((Object)chainCmd), 0x10); // HMEM_UNLOCK + vm02.pokeByte(0x03EC, (byte)chainCmd.length()); // CHAIN_CMD + } + } + protected void run(int gc) + { + if (gc > 0) + { + byte prevCursor = cui.setMouseCursor('C'); // hour glass + cuiMessageBox waitBox = new cuiMessageBox("Please Wait", "System is coming up", "(forcing garbage collection)", 0); + cui.frameRect(29, 13, 22, 3, -1, true, null); + cui.fillRect(30, 14, 20, 1, (byte)'V', (byte)'W'); + for (int i = 0; i < 20; i++) + { + cui.fillRect(30, 14, i + 1, 1, ' ', ' '); + cui.gc(gc); // get a leg up on GC + } + waitBox.delete(); + waitBox = null; + cui.setMouseCursor(prevCursor); + } + run(); + } + protected void run() + { + while (!quit) eventDispatch(inputMask, eventTimeOut); + } +} diff --git a/src/org/vm02/cui/cuiButton.java b/src/org/vm02/cui/cuiButton.java new file mode 100755 index 0000000..e863fef --- /dev/null +++ b/src/org/vm02/cui/cuiButton.java @@ -0,0 +1,105 @@ +// +// java - character user interface +// +package org.vm02.cui; + +public class cuiButton extends cuiControl +{ + public final static int EVENT_BUTTONPRESS = 100; + private String label; + private byte xLabel, yLabel; + + public cuiButton(int bttnX, int bttnY, int bttnWidth, int bttnHeight, String bttnLabel, boolean frame, char bttnAccelChar, int bttnID, cuiControl bttnOwner) + { + super(bttnX, bttnY, bttnWidth, bttnHeight, bttnID, bttnAccelChar, FLAGS_NOMOUSEFOCUS, bttnOwner); + label = bttnLabel; + xLabel = (byte)(x + ((width - label.length()) >> 1)); + yLabel = (byte)(y + (height >> 1)); + if (frame) + { + cui.frameRect(bttnX - 1, bttnY - 1, bttnWidth + 2, bttnHeight + 2, 0x80 | ' ', true, null); + cui.drawString(xLabel, yLabel, label); + } + else + drawNormalButton(); + } + + private void drawNormalButton() + { + cui.fillRect(x, y, width, height, 0x80|' ', 0x80|' '); + if (focus == this) + cui.drawInverseString(xLabel, yLabel, label); + else + cui.drawString(xLabel, yLabel, label); + } + private void drawInvertedButton() + { + //cui.tone(254, 80, 4); + cui.fillRect(x, y, width, height, ' ', ' '); + cui.drawInverseString(xLabel, yLabel, label); + } + public cuiControl setFocus() + { + cuiControl prevFocus = super.setFocus(); + drawNormalButton(); + return prevFocus; + } + public void unFocus() + { + super.unFocus(); + drawNormalButton(); + } + public boolean event(int msg, int msgData) + { + switch (msg) + { + case EVENT_KEYPRESS: + if ((cui.codeKey == accel) + || (isFocus && (cui.codeKey == cui.KEY_RETURN || cui.codeKey == cui.KEY_SPACEBAR))) + { + drawInvertedButton(); + drawNormalButton(); + owner.event(EVENT_BUTTONPRESS, ID); + return true; + } + break; + case EVENT_MOUSEBTTNDOWN: + boolean inv = true; + drawInvertedButton(); + while (cui.bttnMouse != 0) + if ((cui.updateMouse() & cui.INPUT_MOUSEMOVE) != 0) + { + if ((cui.xMouse >= x) + && (cui.xMouse < right) + && (cui.yMouse >= y) + && (cui.yMouse < bottom)) + { + if (!inv) + { + drawInvertedButton(); + inv = true; + } + } + else + { + if (inv) + { + drawNormalButton(); + inv = false; + } + } + } + if (inv) drawNormalButton(); + if ((cui.xMouse >= x) + && (cui.xMouse < right) + && (cui.yMouse >= y) + && (cui.yMouse < bottom)) + { + owner.event(EVENT_BUTTONPRESS, ID); + return true; + } + break; + } + return false; + } +} diff --git a/src/org/vm02/cui/cuiConsole.java b/src/org/vm02/cui/cuiConsole.java new file mode 100755 index 0000000..a284dfd --- /dev/null +++ b/src/org/vm02/cui/cuiConsole.java @@ -0,0 +1,20 @@ +// +// java - character user interface +// +package org.vm02.cui; +import apple2.*; + +public class cuiConsole extends cuiWindow +{ + public cuiConsole(int conX, int conY, int conWidth, int conHeight, int conID, String conTitle, cuiControl conOwner) + { + super(conX, conY, conWidth, conHeight, conID, conTitle, conOwner); + vm02.pokeByte(0x20, x); + vm02.pokeByte(0x21, width); + vm02.pokeByte(0x22, y); + vm02.pokeByte(0x23, bottom); + vm02.pokeByte(0x24, x); + vm02.pokeByte(0x25, y); + vm02.call(y, 0xFBC1); + } +} diff --git a/src/org/vm02/cui/cuiControl.java b/src/org/vm02/cui/cuiControl.java new file mode 100755 index 0000000..6327abe --- /dev/null +++ b/src/org/vm02/cui/cuiControl.java @@ -0,0 +1,198 @@ +// +// java - character user interface +// +package org.vm02.cui; + +public class cuiControl +{ + public final static int EVENT_KEYPRESS = 1; + public final static int EVENT_MOUSEBTTNDOWN = 2; + public final static int EVENT_MOUSEDBLDOWN = 4; + public final static int EVENT_MOUSEMOVE = 8; + public final static int EVENT_MOUSEMASK = 0xFFFFFFF1; + public final static int EVENT_TIMEOUT = 16; + public final static int EVENT_CANCEL = 20; + public final static int EVENT_OK = 21; + public final static int EVENT_REDRAW = 30; + public final static int EVENT_SHUTDOWN = 99; + + protected final static byte FLAGS_NOMOUSEFOCUS = 1; + protected final static byte FLAGS_NOKEYBOARDFOCUS = 2; + protected final static byte FLAGS_OWNERFOCUS = 4; + + protected static cuiControl list, listTop, focus; + private static byte prevMouseX, prevMouseY; + private static int prevMouseTime; + public boolean isFocus; + protected byte x, y, width, height, right, bottom; + public byte flags; + protected int ID; + protected char accel; + protected cuiControl prev, next, owner; + + public cuiControl(int ctrlX, int ctrlY, int ctrlWidth, int ctrlHeight, int ctrlID, char ctrlAccel, int ctrlFlags, cuiControl ctrlOwner) + { + x = (byte)ctrlX; + y = (byte)ctrlY; + width = (byte)ctrlWidth; + height = (byte)ctrlHeight; + right = (byte)(ctrlX + ctrlWidth); + bottom = (byte)(ctrlY + ctrlHeight); + ID = ctrlID; + accel = ctrlAccel; + flags = (byte)ctrlFlags; + owner = (ctrlOwner != null) ? ctrlOwner : this; + prev = listTop; + listTop = this; + if (prev != null) + prev.next = this; + isFocus = false; + } + public void delete() + { + if (isFocus) + focus.unFocus(); + if (next != null) + next.delete(); + if (this == listTop) + listTop = prev; + if (prev != null) + { + prev.next = null; + prev = null; + } + owner = null; + } + protected void unFocus() + { + if (isFocus) + { + focus = null; + isFocus = false; + } + } + public static cuiControl clearFocus() + { + cuiControl prevFocus = focus; + if (focus != null) + focus.unFocus(); + return prevFocus; + } + public cuiControl setFocus() + { + cuiControl prevFocus = focus; + + if (!isFocus) + { + if ((flags & FLAGS_OWNERFOCUS) != 0) + { + if (!owner.isFocus) + owner.setFocus(); + } + else + { + if (prevFocus != null) + prevFocus.unFocus(); + focus = this; + isFocus = true; + } + } + return prevFocus; + } + public void nextFocus(cuiControl wrapFocus) + { + cuiControl ctrlFocus = next; + unFocus(); + if (ctrlFocus == null) + ctrlFocus = wrapFocus; + while ((ctrlFocus.flags & FLAGS_NOKEYBOARDFOCUS) != 0) + { + ctrlFocus = ctrlFocus.next; + if (ctrlFocus == null) + ctrlFocus = wrapFocus; + } + ctrlFocus.setFocus(); + } + public boolean event(int msg, int msgData) + { + return false; + } + public static void eventDispatch(int mask, int timeOut) + { + int msg = 0; + int input = cui.getInputEvent(mask, timeOut); + while (input != 0) + { + if ((input & cui.INPUT_KEYBOARD) != 0) + { + input &= ~cui.INPUT_KEYBOARD; + if (focus != null && focus.event(EVENT_KEYPRESS, 0)) // give focus first crack at keyboard input + msg = 0; + else + msg = EVENT_KEYPRESS; + } + else if ((input & cui.INPUT_MOUSEBTTNDOWN) != 0) + { + input &= ~cui.INPUT_MOUSEBTTNDOWN; + if ((cui.timeMouseEvent - prevMouseTime < 500) + && (cui.xMouse == prevMouseX) + && (cui.yMouse == prevMouseY)) + msg = EVENT_MOUSEDBLDOWN; + else + msg = EVENT_MOUSEBTTNDOWN; + prevMouseTime = cui.timeMouseEvent; + prevMouseX = cui.xMouse; + prevMouseY = cui.yMouse; + if ((focus != null) + && (cui.xMouse >= focus.x) + && (cui.xMouse < focus.right) + && (cui.yMouse >= focus.y) + && (cui.yMouse < focus.bottom) + && focus.event(msg, 0)) + msg = 0; + } + else if ((input & cui.INPUT_MOUSEMOVE) != 0) + { + input &= ~cui.INPUT_MOUSEMOVE; + msg = EVENT_MOUSEMOVE; + } + else if ((input & cui.INPUT_TIMEOUT) != 0) + { + input &= ~cui.INPUT_TIMEOUT; + msg = EVENT_TIMEOUT; + } + if (msg != 0) + { + for (cuiControl ctrlHandler = listTop; ctrlHandler != null; ctrlHandler = ctrlHandler.prev) + { + if ((msg & EVENT_MOUSEMASK) == 0) + { + if ((cui.xMouse >= ctrlHandler.x) + && (cui.xMouse < ctrlHandler.right) + && (cui.yMouse >= ctrlHandler.y) + && (cui.yMouse < ctrlHandler.bottom)) + { + if ((ctrlHandler.flags & FLAGS_OWNERFOCUS) == 0) + { + if (!ctrlHandler.isFocus + && ((ctrlHandler.flags & FLAGS_NOMOUSEFOCUS) == 0)) + ctrlHandler.setFocus(); + } + else + { + if (!ctrlHandler.owner.isFocus + && ((ctrlHandler.owner.flags & FLAGS_NOMOUSEFOCUS) == 0)) + ctrlHandler.owner.setFocus(); + } + ctrlHandler.event(msg, 0); + break; + } + } + else if ((focus != ctrlHandler) && ctrlHandler.event(msg, 0)) + break; + + } + } + } + } +} diff --git a/src/org/vm02/cui/cuiDriver.clasm b/src/org/vm02/cui/cuiDriver.clasm new file mode 100755 index 0000000..4669f1a --- /dev/null +++ b/src/org/vm02/cui/cuiDriver.clasm @@ -0,0 +1,776 @@ +;* +;* CLASS FILE cuiDriver.class +;* + .INCLUDE "global.inc" + .INCLUDE "dvm.inc" + +CHARPTR EQU $A6 +PARMS EQU $A8 +PARMS_OP EQU PARMS+0 +PARMS_STATUS EQU PARMS+0 +PARMS_X EQU PARMS+1 +PARMS_Y EQU PARMS+2 +PARMS_WIDTH EQU PARMS+3 +PARMS_HEIGHT EQU PARMS+4 +PARMS_OFFSET EQU PARMS+3 +PARMS_COUNT EQU PARMS+4 +PARMS_FREQUENCY EQU PARMS+1 +PARMS_DURATION EQU PARMS+2 +PARMS_TIMBRE EQU PARMS+3 +PARMS_XDST EQU PARMS+5 +PARMS_YDST EQU PARMS+6 +PARMS_CHAR_EVEN EQU PARMS+5 +PARMS_CHAR_ODD EQU PARMS+6 +PARMS_CURSOR EQU PARMS+7 +PARMS_LEN EQU PARMS+7 + +.MACRO CALCBASE ROW, ADDR + LDA ROW + AND #$18 + ASL + STA ADDR + ASL + ASL + ORA ADDR + STA ADDR + LDA ROW + AND #$07 + ORA #$08 + LSR + STA ADDR+1 + ROR ADDR +.ENDMACRO +.MACRO CHECKMOUSE ROW, ADDR + LDY #(MOUSEY - DISPATCH) + LDA (NATIVECODEPTR),Y + CMP ROW + BNE :+ + DVM_ENTER + LDZPW ADDR + CALL HIDECURSOR + DVM_EXIT +: +.ENDMACRO + .ORG $1000 ; DUMMY ADDRESS + .BYTE $CA,$FE,$BA,$BE ; MAGIC + .BYTE $00,$00 ; MINOR 0 + .BYTE $00,$32 ; MAJOR 50 +;* +;* CONSTANT POOL +;* + .BYTE $00,$0E ; CONST POOL COUNT 14 +;* CONST POOL INDEX 1 + .BYTE $0A ; METHODREF + .BYTE $00,$04 ; CLASS #4 + .BYTE $00,$0A ; NAME AND TYPE #10 +;* CONST POOL INDEX 2 + .BYTE $08 ; STRING + .BYTE $00,$0B ; #11 +;* CONST POOL INDEX 3 + .BYTE 07 ; CLASS + .BYTE $00,$0C ; #12 +;* CONST POOL INDEX 4 + .BYTE 07 ; CLASS + .BYTE $00,$0D ; #13 +;* CONST POOL INDEX 5 + .BYTE $01 ; UTF8 + .BYTE $00,$06 ; STRLEN + .BYTE "" +;* CONST POOL INDEX 6 + .BYTE $01 ; UTF8 + .BYTE $00,$03 ; STRLEN + .BYTE "()V" +;* CONST POOL INDEX 7 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "Code" +;* CONST POOL INDEX 8 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "dispatch" +;* CONST POOL INDEX 9 + .BYTE $01 ; UTF8 + .BYTE $00,$17 ; STRLEN + .BYTE "([BLjava/lang/Object;)I" +;* CONST POOL INDEX 10 + .BYTE $0C ; NAME AND TYPE + .BYTE $00,$05 ; NAME #5 + .BYTE $00,$06 ; DESC #6 +;* CONST POOL INDEX 11 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "6502" +;* CONST POOL INDEX 12 + .BYTE $01 ; UTF8 + .BYTE $00,$16 ; STRLEN + .BYTE "org/vm02/cui/cuiDriver" +;* CONST POOL INDEX 13 + .BYTE $01 ; UTF8 + .BYTE $00,$10 ; STRLEN + .BYTE "java/lang/Object" +;* +;* ACCESS FLAGS +;* + .BYTE $00,$21 ; 0x0021 +;* +;* THIS CLASS +;* + .BYTE $00,$03 ; #3 +;* +;* SUPER CLASS +;* + .BYTE $00,$04 ; #4 +;* +;* INTERFACES +;* + .BYTE $00,$00 ; IFACE COUNT 0 +;* +;* FIELDS +;* + .BYTE $00,$00 ; FIELD COUNT 0 +;* +;* METHODS +;* + .BYTE $00,$02 ; METHOD COUNT 2 +;******* METHOD INDEX 0 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$05 ; NAME #5 + .BYTE $00,$06 ; DESC #6 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$07 ; NAME #7 + .BYTE $00,$00,>(M0A0END-M0A0BGN),<(M0A0END-M0A0BGN) +M0A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M0C0END-M0C0BGN),<(M0C0END-M0C0BGN) +M0C0BGN: + .BYTE $2A ; 00000: aload_0 + .BYTE $B7,$00,$01 ; 00001: invokespecial #1 + .BYTE $B1 ; 00004: return +M0C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M0A0END: +;******* METHOD INDEX 1 ******** + .BYTE $01,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$09 ; DESC #9 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$0B ; NAME #11 + .BYTE $00,$00,>(M1A0END-M1A0BGN),<(M1A0END-M1A0BGN) +M1A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$03 ; MAX LOCALS 3 + .BYTE $00,$00,>(M1C0END-M1C0BGN),<(M1C0END-M1C0BGN) +M1C0BGN: +DISPATCH: + BCC :+ ; SKIP LOCAL VARS +;* +;* LOCAL VARS +;* +MOUSESTATE: .BYTE $00 +MOUSECURSOR: .BYTE 'B' ; MOUSETEXT ARROW +MOUSESAVEUNDER: .BYTE $00 +MOUSEX: .BYTE $00 +MOUSEY: .BYTE $FF ; MOUSE OFFSCREEN +;* +;* CODE +;* +: LDA HMETHODCODE + LDX HMETHODCODE+1 + LDY LINK_HMEMLOCK + STY OPADDR + LDY LINK_HMEMLOCK+1 + STY OPADDR+1 + JSR OPJMP + PLA ; SAVE RETURN ADDRESS + STA $A4 + PLA + STA $A5 + PLA ; PULL TEXT OBJECT + STA $A6 + PLA + TAX + PLA + PLA + LDA $A6 + LDY LINK_HMEMPTR + STY OPADDR + LDY LINK_HMEMPTR+1 + STY OPADDR+1 + CPX #$00 ; NULL CHECK + BEQ :+ + JSR OPJMP +: STA CHARPTR ; SAVE POINTER TO TEXT OBJECT + STX CHARPTR+1 + PLA ; PULL PARAMS ARRAY + STA TMP + PLA + TAX + PLA + PLA + LDA TMP + JSR OPJMP + CLC + ADC #$02 + BCC :+ + INX +: STA TMPTR + STX TMPTR+1 + LDY #$07 ; COPY PARAMETER ARRAY OVER +CPYPARMS: LDA (TMPTR),Y + STA PARMS,Y + DEY + BPL CPYPARMS + DVM_ENTER + LDZPB PARMS_OP ; SWITCH ON FUNCTION + SWTCHB 13 + CASEB 10, UPDATEMOUSE ; MOVE MOUSE CURSOR + CASEB 5, PUTSTR ; PUT STRING + CASEB 6, PUTINVSTR ; PUT STRING + CASEB 7, PUTMOUSESTR ; PUT STRING + CASEB 4, PUTCHARS ; PUT RAW CHARS FROM BYTE ARRAY + CASEB 8, GETCHARS ; GET RAW CHARS FROM SCREEN INTO BYTE ARRAY + CASEB 2, FILLRECT ; FILL RECT WITH CHAR + CASEB 3, SCROLLRECT ; SCROLL RECT + CASEB 11, SHOWMOUSE ; ENABLE MOUSE CURSOR + CASEB 12, HIDEMOUSE ; DISABLE MOUSE CURSOR + CASEB 16, TONE ; SIMPLE TONES + CASEB 0, INIT ; INIT TEXT UI MODE + CASEB 1, CLEANUP ; EXIT TEXT UI MODE + LDCB $FF ; DEFAULT: SET ERROR AND RETURN + STZPB PARMS_STATUS + JUMP DRETURN +; +; FILL RECT WITH CHAR +; +FILLRECT: DVM_EXIT +FILL_LP: CALCBASE PARMS_Y, TMPTR + CHECKMOUSE PARMS_Y, TMPTR +FILL_ROW: LDX PARMS_WIDTH + LDA PARMS_X + LSR + TAY + SEI + BCS FILL_ODD +FILL_EVN: BIT $C055 ; PAGE2 + LDA PARMS_CHAR_EVEN + STA (TMPTR),Y + DEX + BEQ :+ +FILL_ODD: BIT $C054 ; PAGE1 + LDA PARMS_CHAR_ODD + STA (TMPTR),Y + INY + DEX + BNE FILL_EVN +: BIT $C054 ; PAGE1 + CLI + INC PARMS_Y + DEC PARMS_HEIGHT + BNE FILL_LP +FILL_EXIT: DVM_ENTER + JUMP DRETURN +; +; PUT STRING +; +PUTINVSTR: DVM_EXIT + LDA #$7F + LDX #$40 + BNE :+ +; +; PUT MOUSE STRING +; +PUTMOUSESTR: DVM_EXIT + LDA #$7F + LDX #$00 + BEQ :+ +; +; FILL REMAINDER OF WIDTH +; +PUTS_FILL: LDA PARMS_COUNT + BEQ FILL_EXIT + STA PARMS_WIDTH + LDA #$01 + STA PARMS_HEIGHT + BNE FILL_ROW +; +; PUT STRING +; +PUTSTR: DVM_EXIT + LDA #$FF + LDX #$00 +: STA $32 + STX $24 + CALCBASE PARMS_Y, TMPTR + CHECKMOUSE PARMS_Y, TMPTR + LDY #$00 + LDA (CHARPTR),Y + SEC + SBC PARMS_OFFSET + BCC PUTS_FILL + BEQ PUTS_FILL + STA PARMS_LEN + LDA PARMS_OFFSET +; SEC ; SKIP LEN BYTE + ADC CHARPTR + STA CHARPTR + SEI + BCC PUTS_LP + INC CHARPTR+1 +PUTS_LP: LDA PARMS_X + LSR + TAY + LDX #$00 + LDA (CHARPTR,X) + BCS :+ + INX +: STA $C054,X ; PAGE1 OR PAGE2 + ORA #$80 + AND $32 + CMP #$60 + BCS :+ + CMP #$40 + BCC :+ + EOR $24 +: STA (TMPTR),Y + DEC PARMS_COUNT + BEQ ARETURN + INC PARMS_X + DEC PARMS_LEN + BEQ PUTS_FILL + INC CHARPTR + BNE PUTS_LP + INC CHARPTR+1 + BNE PUTS_LP +; BEQ ARETURN +DRETURN: DVM_EXIT +ARETURN: + BIT $C054 ; LEAVE PAGE1 SELECTED +.IFDEF DEBUG + LDX #$FF + STX $32 + INX + STX $24 +.ENDIF + CLI + LDY #(MOUSESTATE - DISPATCH) + LDA (NATIVECODEPTR),Y + BPL :+ + DVM_ENTER + CALL UNHIDECURSOR + DVM_EXIT +: LDA #$00 + PHA + PHA + PHA + LDA PARMS_STATUS ; PUSH RETURN STATUS + PHA + LDA $A5 ; PUSH RETURN ADDRESS + PHA + LDA $A4 + PHA + LDA HMETHODCODE ; UNLOCK METHOD AND RETURN + LDX HMETHODCODE+1 + JMP (LINK_HMEMUNLOCK) +; +; PUT BYTE ARRAY OF CHARS +; +PUTCHARS: DVM_EXIT + LDY #$01 + LDA (CHARPTR),Y + DEY + BEQ :+ + LDA #$FF + BNE :++ +: LDA (CHARPTR),Y +: SEC + SBC PARMS_OFFSET + BCC PUTC_EXIT + BEQ PUTC_EXIT + STA PARMS_LEN + LDA #$02 + CLC + ADC CHARPTR + BCC :+ + INC CHARPTR+1 + CLC +: ADC PARMS_OFFSET + STA CHARPTR + BCC :+ + INC CHARPTR+1 +: CALCBASE PARMS_Y, TMPTR + CHECKMOUSE PARMS_Y, TMPTR + LDA PARMS_X + LSR + TAY + LDX #$00 + SEI + BCS PUTC_ODD +PUTC_EVN: STA $C055 ; PAGE2 + LDA (CHARPTR,X) + STA (TMPTR),Y + DEC PARMS_COUNT + BEQ PUTC_EXIT + DEC PARMS_LEN + BEQ PUTC_EXIT + INC CHARPTR + BNE PUTC_ODD + INC CHARPTR+1 +PUTC_ODD: STA $C054 ; PAGE1 + LDA (CHARPTR,X) + STA (TMPTR),Y + INY + DEC PARMS_COUNT + BEQ PUTC_EXIT + DEC PARMS_LEN + BEQ PUTC_EXIT + INC CHARPTR + BNE PUTC_EVN + INC CHARPTR+1 + BNE PUTC_EVN +PUTC_EXIT: DVM_ENTER + JUMP DRETURN +; +; GET CHARS INTO BYTE ARRAY +; +GETCHARS: DVM_EXIT + LDY #$01 + LDA (CHARPTR),Y + DEY + BEQ :+ + LDA #$FF + BNE :++ +: LDA (CHARPTR),Y +: SEC + SBC PARMS_OFFSET + BCC GETC_EXIT + BEQ GETC_EXIT + STA PARMS_LEN + LDA #$02 + CLC + ADC CHARPTR + BCC :+ + INC CHARPTR+1 + CLC +: ADC PARMS_OFFSET + STA CHARPTR + BCC :+ + INC CHARPTR+1 +: CALCBASE PARMS_Y, TMPTR + CHECKMOUSE PARMS_Y, TMPTR + LDA PARMS_X + LSR + TAY + LDX #$00 + SEI + BCS GETC_ODD +GETC_EVN: STA $C055 ; PAGE2 + LDA (TMPTR),Y + STA (CHARPTR,X) + DEC PARMS_COUNT + BEQ GETC_EXIT + DEC PARMS_LEN + BEQ GETC_EXIT + INC CHARPTR + BNE GETC_ODD + INC CHARPTR+1 +GETC_ODD: STA $C054 ; PAGE1 + LDA (TMPTR),Y + INY + STA (CHARPTR,X) + DEC PARMS_COUNT + BEQ GETC_EXIT + DEC PARMS_LEN + BEQ GETC_EXIT + INC CHARPTR + BNE GETC_EVN + INC CHARPTR+1 + BNE GETC_EVN +GETC_EXIT: DVM_ENTER + JUMP DRETURN +; +; SCROLL RECT OF CHARS +; +SCROLLRECT: LDZPB PARMS_YDST + LDZPB PARMS_Y + BRAB SCROLLDOWN +SCROLLUP: CALL SCROLLROW + DVM_EXIT + INC PARMS_Y + INC PARMS_YDST + DEC PARMS_HEIGHT + BEQ GETC_EXIT + DVM_ENTER + BRNCH SCROLLUP +SCROLLDOWN: LDZPB PARMS_Y + LDZPB PARMS_HEIGHT + ADDB + DECRB + STZPB PARMS_Y + LDZPB PARMS_YDST + LDZPB PARMS_HEIGHT + ADDB + DECRB + STZPB PARMS_YDST +: CALL SCROLLROW + DVM_EXIT + DEC PARMS_Y + DEC PARMS_YDST + DEC PARMS_HEIGHT + BEQ GETC_EXIT + DVM_ENTER + BRNCH :- +SCROLLROW: DVM_EXIT + CALCBASE PARMS_Y, CHARPTR + CHECKMOUSE PARMS_Y, CHARPTR + CALCBASE PARMS_YDST, TMPTR + CHECKMOUSE PARMS_YDST, TMPTR + LDA PARMS_X + LSR + TAY + LDX PARMS_WIDTH + SEI + BCS SCRL_ODD +SCRL_EVN: STA $C055 ; PAGE2 + LDA (CHARPTR),Y + STA (TMPTR),Y + DEX + BEQ :+ +SCRL_ODD: STA $C054 ; PAGE1 + LDA (CHARPTR),Y + STA (TMPTR),Y + INY + DEX + BNE SCRL_EVN +: STA $C054 ; PAGE1 + CLI + DVM_ENTER + RET +; +; UPDATE MOUSE +; +UPDATEMOUSE: LDPB (NATIVECODEPTR), MOUSESTATE - DISPATCH + BRZB :+ ; DISABLED + DVM_EXIT + LDY #(MOUSEY - DISPATCH) + LDA (NATIVECODEPTR),Y + STA $24 + CALCBASE $24, TMPTR + DVM_ENTER + LDZPW TMPTR + CALL HIDECURSOR + LDZPB PARMS_X + STPB (NATIVECODEPTR), MOUSEX - DISPATCH + LDZPB PARMS_Y + STPB (NATIVECODEPTR), MOUSEY - DISPATCH + LDZPB PARMS_CURSOR + STPB (NATIVECODEPTR), MOUSECURSOR - DISPATCH + DVM_EXIT + CALCBASE PARMS_Y, TMPTR + DVM_ENTER + LDZPW TMPTR + CALL SHOWCURSOR +: JUMP DRETURN +; +; HIDE MOUSE +; +HIDEMOUSE: LDPB (NATIVECODEPTR), MOUSESTATE - DISPATCH + BRZB :+ ; ALREADY DISABLED + JUMP DRETURN + LD0B ; CLEAR ENABLED FLAG + STPB (NATIVECODEPTR), MOUSESTATE - DISPATCH + LDPB (NATIVECODEPTR), MOUSEY - DISPATCH + DVM_EXIT + PLA + STA PARMS_Y + CALCBASE PARMS_Y, TMPTR + DVM_ENTER + LDZPW TMPTR + CALL HIDECURSOR + LDCB $FF + STPB (NATIVECODEPTR), MOUSEY - DISPATCH +: JUMP DRETURN +; +; HIDE MOUSE CURSOR +; +HIDECURSOR: STZPW OPADDR + LDPB (NATIVECODEPTR), MOUSESAVEUNDER - DISPATCH + DVM_EXIT + LDY #(MOUSEX - DISPATCH) + LDA (NATIVECODEPTR),Y + LSR + TAY + LDX #$00 + SEI + BCS :+ + INX +: STA $C054,X ; PAGE1 OR PAGE2 + PLA ; PULL SAVEUNDER CHARACTER + STA (OPADDR),Y + STA $C054 ; PAGE1 + CLI + LDY #(MOUSESTATE - DISPATCH) + LDA (NATIVECODEPTR),Y + ORA #$80 ; SET CURSOR HIDDEN FLAG + STA (NATIVECODEPTR),Y + DVM_ENTER + RET +; +; SHOW MOUSE +; +SHOWMOUSE: LDPB (NATIVECODEPTR), MOUSESTATE - DISPATCH + BRNZB :+ ; ALREADY ENABLED + LD1B ; SET ENABLED FLAG / CLEAR HIDDEN FLAG + STPB (NATIVECODEPTR), MOUSESTATE - DISPATCH + LDZPB PARMS_X + STPB (NATIVECODEPTR), MOUSEX - DISPATCH + LDZPB PARMS_Y + STPB (NATIVECODEPTR), MOUSEY - DISPATCH + DVM_EXIT + CALCBASE PARMS_Y, TMPTR + DVM_ENTER + LDZPW TMPTR + CALL SHOWCURSOR +: JUMP DRETURN +; +; UNHIDE MOUSE CURSOR +; +UNHIDECURSOR: LD1B ; SET ENABLED FLAG / CLEAR HIDDEN FLAG + STPB (NATIVECODEPTR), MOUSESTATE - DISPATCH + LDPB (NATIVECODEPTR), MOUSEY - DISPATCH + STZPB PARMS_Y + DVM_EXIT + CALCBASE PARMS_Y, TMPTR + DVM_ENTER + LDZPW TMPTR +; +; SHOW MOUSE CURSOR +; +SHOWCURSOR: STZPW OPADDR + LDPB (NATIVECODEPTR), MOUSECURSOR - DISPATCH + DVM_EXIT + LDY #(MOUSEX - DISPATCH) + LDA (NATIVECODEPTR),Y + LSR + TAY + LDX #$00 + SEI + BCS :+ + INX +: STA $C054,X ; PAGE1 OR PAGE2 + LDA (OPADDR),Y + TAX + PLA ; PULL MOUSECURSOR + STA (OPADDR),Y + STA $C054 ; PAGE1 + CLI + TXA + LDY #(MOUSESAVEUNDER - DISPATCH) + STA (NATIVECODEPTR),Y + LDY #(MOUSESTATE - DISPATCH) + LDA (NATIVECODEPTR),Y + AND #$7F ; CLEAR CURSOR HIDDEN FLAG + ORA #$01 ; SET ACTIVE FLAG + STA (NATIVECODEPTR),Y + DVM_ENTER + RET +; +; TONE +; +TONE: DVM_EXIT + LDA PARMS_FREQUENCY + EOR #$FF + STA PARMS_LEN + LDA PARMS_FREQUENCY + SEC + SBC PARMS_TIMBRE + STA PARMS_FREQUENCY + SEI ; DISABLE INTERRUPTS +TONELOOPOUTR: LDX PARMS_LEN +TONELOOP: LDY PARMS_TIMBRE + BIT $C030 +TONEDELAY1: DEY + BNE TONEDELAY1 + BIT $C030 + LDY PARMS_FREQUENCY +TONEDELAY2: DEY + BNE TONEDELAY2 + DEX + BNE TONELOOP + DEC PARMS_DURATION + BNE TONELOOPOUTR + DVM_ENTER + JUMP DRETURN +; +; INIT TEXT MODE AND MOUSETEXT +; +INIT: DVM_EXIT + LDX #$FF + LDA MACHID + BPL :+ + BIT ROMIN +.IFDEF DEBUG_DUMP + LDA $36 + PHA + LDA $37 + PHA +.ENDIF + LDA #$00 + TAX + TAY + JSR $C300 + LDA #$1B ; TURN ON MOUSETEXT + JSR $FDED +.IFDEF DEBUG_DUMP + PLA + STA $37 + PLA + STA $36 +.ENDIF + SEI + BIT LCBNK2 + BIT LCBNK2 + CLI + LDX #$00 +: STX $A8 + DVM_ENTER + JUMP DRETURN +; +; TURN OFF MOUSETEXT AND CLEAN UP +; +CLEANUP: DVM_EXIT + LDX #$FF + STX $32 + INX + STX $24 + STX PARMS_STATUS + BIT ROMIN + BIT $C054 + JSR $FC58 ; HOME + LDA #$18 ; TURN OFF MOUSETEXT + JSR $FDED + LDA #$11 ; TURN OFF 80 COLUMN + JSR $FDED + SEI + BIT LCBNK2 + BIT LCBNK2 + CLI + DVM_ENTER + JUMP DRETURN +M1C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M1A0END: +;* +;* GLOBAL ATTRIBUTES +;* + .BYTE $00,$00 ; ATTRIB COUNT 0 diff --git a/src/org/vm02/cui/cuiDriver.java b/src/org/vm02/cui/cuiDriver.java new file mode 100755 index 0000000..71e33ca --- /dev/null +++ b/src/org/vm02/cui/cuiDriver.java @@ -0,0 +1,10 @@ +package org.vm02.cui; + +public class cuiDriver +{ + public static int dispatch(byte params[], Object text) + { + String Code = "6502"; + return 0; + } +} \ No newline at end of file diff --git a/src/org/vm02/cui/cuiDropDownMenu.java b/src/org/vm02/cui/cuiDropDownMenu.java new file mode 100755 index 0000000..af2c667 --- /dev/null +++ b/src/org/vm02/cui/cuiDropDownMenu.java @@ -0,0 +1,128 @@ +// +// java - character user interface +// +package org.vm02.cui; + +public class cuiDropDownMenu extends cuiPopUp +{ + private char menuAccels[]; + private String menuList[]; + private int choice, hilite; + private byte menuLeft, menuRight, menuWidth; + + public cuiDropDownMenu(int dropMenuX, int dropMenuWidth, String dropSpecialTitle, String dropMenuList[], char dropMenuAccels[]) + { + super(dropMenuX, 1, dropMenuWidth, dropMenuList.length - 1, false); + menuList = dropMenuList; + menuAccels = dropMenuAccels; + menuLeft = (byte)dropMenuX; + menuWidth = (byte)dropMenuWidth; + menuRight = (byte)(dropMenuX + dropMenuWidth); + if (dropSpecialTitle != null) + cui.drawMouseString(dropMenuX, 0, dropSpecialTitle); + else + cui.drawString(dropMenuX, 0, menuList[0]); + for (int l = 1; l < menuList.length; l++) + if (menuList[l] != null) + cui.drawString(dropMenuX, l, menuList[l]); + else + cui.fillRect(dropMenuX, l, dropMenuWidth, 1, (byte)'S', (byte)'S'); + } + private void chooseMouse() + { + int titleRight = menuLeft + menuList[0].length(); + choice = 0; + while ((cui.bttnMouse != 0) + && ((cui.yMouse > 0) + || ((cui.xMouse >= menuLeft) + && (cui.xMouse < titleRight)))) + { + int prevHilite = hilite; + if ((cui.xMouse >= menuLeft) + && (cui.xMouse < menuRight) + && (cui.yMouse >= 1) + && (cui.yMouse < menuList.length)) + hilite = cui.yMouse; + else + hilite = -1; + if (prevHilite != hilite) + { + if ((prevHilite > 0) && (menuList[prevHilite] != null)) + cui.drawString(menuLeft, prevHilite, menuList[prevHilite]); + if ((hilite > 0) && menuList[hilite] != null) + cui.drawInverseString(menuLeft, hilite, menuList[hilite]); + } + cui.updateMouse(); + } + if ((cui.xMouse >= menuLeft) + && (cui.xMouse < menuRight) + && (cui.yMouse < menuList.length) + && (menuList[cui.yMouse] != null)) + choice = cui.yMouse; + } + public int choose() + { + if (cui.bttnMouse != 0) + { + hilite = -1; + chooseMouse(); + } + else + { + choice = -1; + hilite = 1; + cui.drawInverseString(menuLeft, 1, menuList[1]); + while (choice < 0) eventDispatch(cui.INPUT_KEYBOARD | cui.INPUT_MOUSEBTTNDOWN, -1); + } + delete(); + return choice; + } + public boolean event(int msg, int msgData) + { + switch (msg) + { + case EVENT_KEYPRESS: + switch (cui.codeKey) + { + case cui.KEY_ESC: + case cui.KEY_ARROWRIGHT: + case cui.KEY_ARROWLEFT: + choice = 0; + break; + case cui.KEY_RETURN: + choice = hilite; + break; + case cui.KEY_ARROWUP: + if (hilite > 1) + { + cui.drawString(menuLeft, hilite, menuList[hilite]); + while (menuList[--hilite] == null); + cui.drawInverseString(menuLeft, hilite, menuList[hilite]); + } + break; + case cui.KEY_ARROWDOWN: + if (hilite < menuList.length - 1) + { + if (hilite > 0) cui.drawString(menuLeft, hilite, menuList[hilite]); + while (menuList[++hilite] == null); + cui.drawInverseString(menuLeft, hilite, menuList[hilite]); + } + break; + default: + for (int a = 1; a < menuAccels.length; a++) + if (cui.codeKey == menuAccels[a]) + { + choice = a + 1; + return true; + } + } + break; + case EVENT_MOUSEBTTNDOWN: + if (choice == -1) + chooseMouse(); // only switch to mouse mode if currently in keyboard mode + break; + } + return true; + }; + +} diff --git a/src/org/vm02/cui/cuiListBox.java b/src/org/vm02/cui/cuiListBox.java new file mode 100755 index 0000000..c6c5a6f --- /dev/null +++ b/src/org/vm02/cui/cuiListBox.java @@ -0,0 +1,194 @@ +// +// java - character user interface +// +package org.vm02.cui; + +public class cuiListBox extends cuiControl +{ + public final static int EVENT_LISTITEMSELECT = 500; + public final static int EVENT_LISTITEMDRAW = 501; + public final static int EVENT_LISTITEMDRAWHILITE = 502; + protected int itemCount, itemTop, hilite; + protected cuiScrollBar listScroll; + + public cuiListBox(int listX, int listY, int listWidth, int listHeight, int listCount, cuiControl listOwner) + { + super(listX, listY, listWidth, listHeight, 0, (char)-1, 0, listOwner); + int i; + cui.frameRect(listX - 1, listY - 1, listWidth + 2, listHeight + 2, 0x80 | ' ', true, null); + itemCount = listCount; + itemTop = hilite = 0; + if (listCount > listHeight) + { + width--; + right--; + listScroll = new cuiScrollBar(x + width, y, height, listCount, 0, (cuiControl)this); + i = listHeight; + } + else + i = listCount; + while (--i >= 0) + drawItem(i); + } + protected void drawItem(int itemIndex) + { + owner.event(EVENT_LISTITEMDRAW, (x << 24) | ((y + (itemIndex - itemTop)) << 16) | (width << 8) | (itemIndex & 0xFF)); + } + protected void drawSelectedItem(int itemIndex) + { + owner.event(EVENT_LISTITEMDRAWHILITE, (x << 24) | ((y + (itemIndex - itemTop)) << 16) | (width << 8) | (itemIndex & 0xFF)); + } + public int getHilite() + { + return itemTop + hilite; + } + private void scrollList(int dir) + { + int diff; + int prevHilite = hilite; + int prevTop = itemTop; + int newTop = itemTop; + hilite += dir; + if (hilite < 0) + { + newTop += hilite; + hilite = 0; + if (newTop < 0) + newTop = 0; + } + else + { + if (hilite >= height) + { + newTop += hilite - height + 1; + hilite = height - 1; + } + if (hilite + newTop >= itemCount) + { + newTop = itemCount - height; + if (newTop < 0) + { + newTop = 0; + hilite = itemCount - 1; + } + } + } + drawItem(prevTop + prevHilite); + itemTop = newTop; + if (newTop < prevTop) + { + diff = prevTop - newTop; + if (diff < height) + cui.scrollRect(x, y, width, height - diff, y + diff); + else + diff = height; + while (--diff > 0) + drawItem(newTop + diff); + } + else if (newTop > prevTop) + { + diff = newTop - prevTop; + if (diff < height) + cui.scrollRect(x, y + diff, width, height - diff, y); + else + diff = height; + while (--diff > 0) + drawItem(newTop + height - diff - 1); + } + drawSelectedItem(newTop + hilite); + if (listScroll != null) listScroll.setPosition(newTop + hilite); + } + public cuiControl setFocus() + { + cuiControl prevFocus = super.setFocus(); + drawSelectedItem(itemTop + hilite); + return prevFocus; + } + public void unFocus() + { + super.unFocus(); + drawItem(itemTop + hilite); + } + public void delete() + { + if (listScroll != null) + { + listScroll.delete(); + listScroll = null; + } + super.delete(); + } + public boolean event(int msg, int msgData) + { + switch (msg) + { + case EVENT_KEYPRESS: + if (isFocus) + { + if (listScroll != null && listScroll.event(msg, msgData)) + return true; + if ((cui.codeKey == cui.KEY_RETURN) || (cui.codeKey == cui.KEY_SPACEBAR)) + { + owner.event(EVENT_LISTITEMSELECT, itemTop + hilite); + return true; + } + if (cui.codeKey == cui.KEY_ARROWUP) + { + scrollList(-1); + return true; + } + if (cui.codeKey == cui.KEY_ARROWDOWN) + { + scrollList(1); + return true; + } + if (cui.codeKey == (0x80 | cui.KEY_ARROWUP)) + { + scrollList(-(height >> 1)); + return true; + } + if (cui.codeKey == (0x80 | cui.KEY_ARROWDOWN)) + { + scrollList(height >> 1); + return true; + } + } + break; + case EVENT_MOUSEBTTNDOWN: + while (cui.bttnMouse != 0) + { + int dir = cui.yMouse - y - hilite; + if (dir != 0) + scrollList(dir); + cui.updateMouse(); + } + return true; + case EVENT_MOUSEDBLDOWN: + owner.event(EVENT_LISTITEMSELECT, itemTop + hilite); + return true; + case cuiScrollBar.EVENT_SCROLLUP: + scrollList(-1); + return true; + case cuiScrollBar.EVENT_SCROLLDOWN: + scrollList(1); + return true; + case cuiScrollBar.EVENT_SCROLLPAGEUP: + scrollList(-(height >> 1)); + return true; + case cuiScrollBar.EVENT_SCROLLPAGEDOWN: + scrollList(height >> 1); + return true; + case cuiScrollBar.EVENT_SCROLLTO: + scrollList(listScroll.getPosition() - itemTop - hilite); + return true; + case cuiScrollBar.EVENT_SCROLLTOP: + scrollList(-(itemTop + hilite)); + return true; + case cuiScrollBar.EVENT_SCROLLBOTTOM: + scrollList(itemCount - itemTop); + return true; + } + return false; + } + +} diff --git a/src/org/vm02/cui/cuiMenuBar.java b/src/org/vm02/cui/cuiMenuBar.java new file mode 100755 index 0000000..483bec1 --- /dev/null +++ b/src/org/vm02/cui/cuiMenuBar.java @@ -0,0 +1,153 @@ +// +// java - character user interface +// +package org.vm02.cui; +import apple2.*; + +public class cuiMenuBar extends cuiControl +{ + public final static int MENUBAR_ID = 1; + public final static int EVENT_MENUBARITEMSELECT = 200; + private static String sysMenuList[] = {" _@Z ", " About ", null, " Reboot "}; + private boolean dropDone; + private cuiControl menuOwner; + private String menuLists[][]; + private char menuListsAccel[][]; + private byte menuLeft[], menuRight[], menuWidth[]; + + public cuiMenuBar(String newMenuLists[][], char newMenuListsAccel[][], cuiControl newMenuOwner) + { + super(0, 0, 80, 1, MENUBAR_ID, (char)(cui.MODKEY_OPENAPPLE | cui.KEY_ESC), FLAGS_NOMOUSEFOCUS, (cuiControl)null); + menuOwner = newMenuOwner; + menuLists = new String[newMenuLists.length + 1][]; + menuListsAccel = new char[newMenuListsAccel.length + 1][]; + menuLeft = new byte[menuLists.length]; + menuRight = new byte[menuLists.length]; + menuWidth = new byte[menuLists.length]; + cui.fillRect(0, 0, 80, 1, ' ', ' '); + int l = 1; + for (int b = 0; b < menuLists.length; b++) + { + if (b == 0) + { + menuLists[0] = sysMenuList; + cui.drawMouseString(l, 0, menuLists[b][0]); + } + else + { + menuLists[b] = newMenuLists[b - 1]; + menuListsAccel[b] = newMenuListsAccel[b - 1]; + cui.drawInverseString(l, 0, menuLists[b][0]); + } + menuLeft[b] = (byte)l; + l += menuLists[b][0].length(); + menuRight[b] = (byte)l; + for (int w = 1; w < menuLists[b].length; w++) + if ((menuLists[b][w] != null) && (menuLists[b][w].length() > menuWidth[b])) + menuWidth[b] = (byte)menuLists[b][w].length(); + } + } + private void activate(int menuIndex) + { + cuiControl prevFocus = setFocus(); + dropDone = false; + do + { + cuiDropDownMenu menuDrop = new cuiDropDownMenu(menuLeft[menuIndex], menuWidth[menuIndex], (menuIndex == 0) ? " _AZ " : (String)null, menuLists[menuIndex], menuListsAccel[menuIndex]); + int choice = menuDrop.choose(); + menuDrop = null; + if (choice != 0) + { + if (menuIndex == 0) + { + cuiMessageBox msgBox; + if (choice == 1) + { + msgBox = new cuiMessageBox("About VM02", "Version 1.0", "Copyright (c) 2010 David Schmenk", cuiMessageBox.MSGBOX_OK); + msgBox.reply(); + } + else if (choice == 3) + { + msgBox = new cuiMessageBox("Reboot Verification", "Really reboot?", "You will lose all unsaved data.", cuiMessageBox.MSGBOX_OK | cuiMessageBox.MSGBOX_CANCEL); + if (msgBox.reply() == EVENT_OK) + { + cui.shutDown(); + vm02.call(0, 0xEA); // Reboot + } + } + msgBox = null; + } + else + menuOwner.event(EVENT_MENUBARITEMSELECT, (menuIndex << 16) | choice); + dropDone = true; + } + else + { + if (cui.bttnMouse != 0) + { + while ((cui.bttnMouse != 0) + && (cui.yMouse != 0 || (cui.xMouse < menuLeft[0] || cui.xMouse >= menuRight[menuLists.length - 1]))) + cui.updateMouse(); + if (cui.bttnMouse == 0) + return; + for (menuIndex = 0; menuIndex < menuLists.length; menuIndex++) + { + if (cui.xMouse >= menuLeft[menuIndex] && cui.xMouse < menuRight[menuIndex]) + break; + } + } + else + { + if (cui.codeKey == cui.KEY_ARROWRIGHT) + { + if (++menuIndex >= menuLists.length) + menuIndex = 0; + } + else if (cui.codeKey == cui.KEY_ARROWLEFT) + { + if (--menuIndex < 0) + menuIndex = menuLists.length - 1; + } + else + dropDone = true; + } + } + } while (!dropDone); + if (prevFocus != null) prevFocus.setFocus(); + } + public boolean event(int msg, int msgData) + { + switch (msg) + { + case EVENT_KEYPRESS: + if (cui.codeKey == accel) + { + activate(0); + return true; + } + for (int i = 0; i < menuListsAccel.length; i++) + for (int j = 0; j < menuListsAccel[i].length; j++) + if (cui.codeKey == menuListsAccel[i][j]) + { + menuOwner.event(EVENT_MENUBARITEMSELECT, (i << 16) | (j + 1)); + return true; + } + break; + case EVENT_MOUSEBTTNDOWN: + while ((cui.bttnMouse != 0) + && (cui.yMouse != 0 || (cui.xMouse < menuLeft[0] || cui.xMouse >= menuRight[menuLists.length - 1]))) + cui.updateMouse(); + if (cui.bttnMouse != 0) + for (int b = 0; b < menuLists.length; b++) + { + if (cui.xMouse >= menuLeft[b] && cui.xMouse < menuRight[b]) + { + activate(b); + return true; + } + } + return true; + } + return false; + } +} diff --git a/src/org/vm02/cui/cuiMessageBox.java b/src/org/vm02/cui/cuiMessageBox.java new file mode 100755 index 0000000..6c25149 --- /dev/null +++ b/src/org/vm02/cui/cuiMessageBox.java @@ -0,0 +1,54 @@ +// +// java - character user interface +// +package org.vm02.cui; + +public class cuiMessageBox extends cuiPopUp +{ + public final static int MSGBOX_OK = 1; + public final static int MSGBOX_CANCEL = 2; + private int msgReply; + + public cuiMessageBox(String msgTitle, String msgText, int buttons) + { + super(20, 8, 40, 9, false); + drawBox(msgTitle, null, msgText, null, buttons); + } + public cuiMessageBox(String msgTitle, String msgText1, String msgText2, int buttons) + { + super(20, 8, 40, 9, false); + drawBox(msgTitle, msgText1, null, msgText2, buttons); + } + public cuiMessageBox(String msgTitle, String msgText1, String msgText2, String msgText3, int buttons) + { + super(20, 8, 40, 9, false); + drawBox(msgTitle, msgText1, msgText2, msgText3, buttons); + } + private void drawBox(String msgTitle, String msgText1, String msgText2, String msgText3, int buttons) + { + cuiButton bttnCancel, bttnOK; + cui.fillRect(20, 7, 40, 1, ' ', ' '); + cui.drawInverseString(20 + ((40 - msgTitle.length()) >> 1), 7, msgTitle); + if (msgText1 != null) cui.drawString(20 + ((40 - msgText1.length()) >> 1), 9, msgText1); + if (msgText2 != null) cui.drawString(20 + ((40 - msgText2.length()) >> 1), 10, msgText2); + if (msgText3 != null) cui.drawString(20 + ((40 - msgText3.length()) >> 1), 11, msgText3); + if ((buttons & MSGBOX_CANCEL) != 0) + bttnCancel = new cuiButton(26, 13, 12, 3, "Cancel", true, cui.KEY_ESC, EVENT_CANCEL, (cuiControl)this); + if ((buttons & MSGBOX_OK) != 0) + bttnOK = new cuiButton(42, 13, 12, 3, "Okay", true, cui.KEY_RETURN, EVENT_OK, (cuiControl)this); + } + public int reply() + { + msgReply = -1; + while (msgReply < 0) eventDispatch(cui.INPUT_KEYBOARD | cui.INPUT_MOUSEBTTNDOWN, -1); + delete(); + return msgReply; + } + public boolean event(int msg, int msgData) + { + if (msg == cuiButton.EVENT_BUTTONPRESS) + msgReply = msgData; + return true; + } + +} diff --git a/src/org/vm02/cui/cuiPopUp.java b/src/org/vm02/cui/cuiPopUp.java new file mode 100755 index 0000000..23011dc --- /dev/null +++ b/src/org/vm02/cui/cuiPopUp.java @@ -0,0 +1,39 @@ +// +// java - character user interface +// +package org.vm02.cui; + +public class cuiPopUp extends cuiControl +{ + protected byte saveUnder[][]; + protected byte saveX, saveY; + private cuiControl prevFocus; + + public cuiPopUp(int popX, int popY, int popWidth, int popHeight, boolean popTop) + { + super(0, 0, 80, 24, 0, (char)-1, FLAGS_NOMOUSEFOCUS, (cuiControl)null); + prevFocus = clearFocus(); + popX--; + popY--; + popWidth += 2; + popHeight += 2; + saveX = (byte)popX; + saveY = (byte)popY; + saveUnder = cui.saveRect(saveX, saveY, popWidth, popHeight); + cui.frameRect(popX, popY, popWidth, popHeight, 0x80 | ' ', popTop, null); + } + public void delete() + { + super.delete(); + if (saveUnder != null) + { + cui.restoreRect(saveX, saveY, saveUnder); + saveUnder = null; + } + if (prevFocus != null) + { + prevFocus.setFocus(); + prevFocus = null; + } + } +} diff --git a/src/org/vm02/cui/cuiPopUpMenu.java b/src/org/vm02/cui/cuiPopUpMenu.java new file mode 100755 index 0000000..8f52dd4 --- /dev/null +++ b/src/org/vm02/cui/cuiPopUpMenu.java @@ -0,0 +1,127 @@ +// +// java - character user interface +// +package org.vm02.cui; + +public class cuiPopUpMenu extends cuiPopUp +{ + char accels[]; + String items[]; + int choice, hilite; + boolean selected = false; + + public cuiPopUpMenu(int menuX, int menuY, int menuWidth, String menuItems[], char menuAccels[]) + { + super(menuX, menuY, menuWidth, menuItems.length, true); + items = menuItems; + accels = menuAccels; + for (int l = 0; l < menuItems.length; l++) + if (menuItems[l] != null) + cui.drawString(menuX, menuY + l, menuItems[l]); + else + cui.fillRect(menuX, menuY + l, menuWidth, 1, (byte)'S', (byte)'S'); + } + private void chooseMouse() + { + while (cui.bttnMouse != 0) + { + if ((cui.xMouse >= x) + && (cui.xMouse < right) + && (cui.yMouse >= y) + && (cui.yMouse < bottom)) + { + int oldHilite = hilite; + hilite = cui.yMouse - y; + if ((oldHilite >= 0) && (oldHilite != hilite)) + { + if (items[oldHilite] != null) + cui.drawString(x, y + oldHilite, items[oldHilite]); + } + if (items[hilite] != null) + cui.drawInverseString(x, y + hilite,items[hilite]); + } + else + { + if ((hilite >= 0) && (items[hilite] != null)) + cui.drawString(x, y + hilite, items[hilite]); + hilite = -1; + } + cui.updateMouse(); + } + choice = EVENT_CANCEL; + if ((cui.xMouse >= x) + && (cui.xMouse < right) + && (cui.yMouse >= y) + && (cui.yMouse < bottom) + && (items[cui.yMouse - y] != null)) + choice = cui.yMouse - y; + } + public int choose() + { + choice = -1; + hilite = -1; + if (cui.bttnMouse != 0) + chooseMouse(); + else + while (choice < 0) eventDispatch(cui.INPUT_KEYBOARD | cui.INPUT_MOUSEBTTNDOWN, -1); + delete(); + return choice; + } + public boolean event(int msg, int msgData) + { + switch (msg) + { + case EVENT_KEYPRESS: + if (cui.codeKey == cui.KEY_ESC) + { + choice = EVENT_CANCEL; + return true; + } + if (cui.codeKey == cui.KEY_RETURN) + { + choice = hilite; + return true; + } + if (cui.codeKey == cui.KEY_ARROWUP) + { + if (hilite >= 1) + { + cui.drawString(x, y + hilite, items[hilite]); + while (items[--hilite] == null); + cui.drawInverseString(x, y + hilite,items[hilite]); + } + return true; + } + if (cui.codeKey == cui.KEY_ARROWDOWN) + { + if (y + hilite < bottom - 1) + { + if (hilite >= 0) cui.drawString(x, y + hilite, items[hilite]); + while (items[++hilite] == null); + cui.drawInverseString(x, y + hilite,items[hilite]); + } + return true; + } + if (cui.codeKey == cui.KEY_ARROWRIGHT) + { + return true; + } + if (cui.codeKey == cui.KEY_ARROWLEFT) + { + return true; + } + for (int a = 0; a < accels.length; a++) + if (cui.codeKey == accels[a]) + { + choice = a; + return true; + } + break; + case EVENT_MOUSEBTTNDOWN: + chooseMouse(); + break; + } + return true; + } + +} diff --git a/src/org/vm02/cui/cuiScrollBar.java b/src/org/vm02/cui/cuiScrollBar.java new file mode 100755 index 0000000..c8cf636 --- /dev/null +++ b/src/org/vm02/cui/cuiScrollBar.java @@ -0,0 +1,134 @@ +// +// java - character user interface +// +package org.vm02.cui; + +public class cuiScrollBar extends cuiControl +{ + public final static int EVENT_SCROLLUP = 300; + public final static int EVENT_SCROLLPAGEUP = 301; + public final static int EVENT_SCROLLTOP = 302; + public final static int EVENT_SCROLLDOWN = 303; + public final static int EVENT_SCROLLPAGEDOWN = 304; + public final static int EVENT_SCROLLBOTTOM = 305; + public final static int EVENT_SCROLLTO = 306; + private int pos, range, indicator; + + public cuiScrollBar(int scrollX, int scrollY, int scrollHeight, int scrollRange, int scrollID, cuiControl scrollOwner) + { + super(scrollX, scrollY, 1, scrollHeight, scrollID, (char)-1, FLAGS_OWNERFOCUS | FLAGS_NOKEYBOARDFOCUS, scrollOwner); + range = scrollRange; + pos = 0; + cui.fillRect(x, y, 1, 1, 'R', 'R'); + cui.fillRect(x, y + height - 1, 1, 1, 'Q', 'Q'); + updateScrollBar(); + } + + public void setRange(int scrollRange) + { + range = scrollRange; + updateScrollBar(); + } + public void setPosition(int scrollPos) + { + pos = scrollPos; + updateScrollBar(); + } + public int getPosition() + { + return pos; + } + private void updateScrollBar() + { + indicator = y + 1 + pos * (height - 2) / range; + cui.fillRect(x, y + 1, 1, height - 2, 'V', 'W'); + cui.fillRect(x, indicator, 1, 1, 'N', 'N'); + + } + public boolean event(int msg, int msgData) + { + switch (msg) + { + case EVENT_KEYPRESS: + if (owner.isFocus) + switch (cui.codeKey) + { + case cui.KEY_ARROWUP: + owner.event(EVENT_SCROLLUP, ID); + return true; + case cui.KEY_ARROWDOWN: + owner.event(EVENT_SCROLLDOWN, ID); + return true; + case (cui.MODKEY_OPENAPPLE | cui.KEY_ARROWUP): + owner.event(EVENT_SCROLLPAGEUP, ID); + return true; + case (cui.MODKEY_OPENAPPLE | cui.KEY_ARROWDOWN): + owner.event(EVENT_SCROLLPAGEDOWN, ID); + return true; + case (cui.MODKEY_OPENAPPLE | ','): + owner.event(EVENT_SCROLLTOP, ID); + return true; + case (cui.MODKEY_OPENAPPLE | '.'): + owner.event(EVENT_SCROLLBOTTOM, ID); + return true; + } + break; + case EVENT_MOUSEBTTNDOWN: + if (cui.yMouse == y) + { + do + { + owner.event(EVENT_SCROLLUP, ID); + cui.updateMouse(); + } while (cui.bttnMouse != 0); + } + else if (cui.yMouse == bottom - 1) + { + do + { + owner.event(EVENT_SCROLLDOWN, ID); + cui.updateMouse(); + } while (cui.bttnMouse != 0); + } + else if (cui.yMouse == indicator) + { + do + { + if ((cui.updateMouse() & cui.INPUT_MOUSEMOVE) != 0) + { + indicator = cui.yMouse; + if (indicator <= y) + { + pos = 0; + indicator = y + 1; + } + else if (indicator >= (bottom - 1)) + { + pos = range - 1; + indicator = bottom - 2; + } + else + { + pos = (indicator - y - 1) * range / (height - 2); + } + owner.event(EVENT_SCROLLTO, ID); + } + cui.updateMouse(); + } while (cui.bttnMouse != 0); + } + else + { + do + { + if (cui.yMouse < indicator) + owner.event(EVENT_SCROLLPAGEUP, ID); + else if (cui.yMouse > indicator) + owner.event(EVENT_SCROLLPAGEDOWN, ID); + cui.updateMouse(); + } while (cui.bttnMouse != 0); + } + return true; + } + return false; + } +} diff --git a/src/org/vm02/cui/cuiTextEntry.java b/src/org/vm02/cui/cuiTextEntry.java new file mode 100755 index 0000000..e6e29d5 --- /dev/null +++ b/src/org/vm02/cui/cuiTextEntry.java @@ -0,0 +1,174 @@ +// +// java - character user interface +// +package org.vm02.cui; + +public class cuiTextEntry extends cuiControl +{ + public final static int EVENT_TEXTENTRY = 400; + + private String text; + private byte textChars[]; + private byte cursorPos, cursorSave, textLength; + + public cuiTextEntry(int enterX, int enterY, int enterWidth, String enterText, boolean enterFrame, int enterID, cuiControl enterOwner) + { + super(enterX, enterY, enterWidth, 1, enterID, (char)-1, 0, enterOwner); + if (enterFrame) + cui.frameRect(enterX - 1, enterY - 1, enterWidth + 2, 3, 0x80 | ' ', true, null); + + setText(enterText); + } + public cuiTextEntry(int enterX, int enterY, int enterWidth, boolean enterFrame, int enterID, cuiControl enterOwner) + { + super(enterX, enterY, enterWidth, 1, enterID, (char)-1, 0, enterOwner); + if (enterFrame) + cui.frameRect(enterX - 1, enterY - 1, enterWidth + 2, 3, 0x80 | ' ', true, null); + setText(null); + } + + private void textToChars() + { + textChars = new byte[width + 1]; + if (text != null) + { + int i; + textLength = (byte)((text.length() <= width) ? text.length() : width); + for (i = textLength - 1; i >= 0; i--) + textChars[i] = (byte)(0x80 | text.charAt(i)); + } + else + textLength = 0; + textChars[textLength] = (byte)(0x80 | ' '); + cursorSave = textChars[cursorPos]; + textChars[cursorPos] = (byte)(cursorSave & (((cursorSave & 0xE0) == 0xC0) ? 0x1F : 0x7F)); + int textWidth = textLength + ((cursorPos == textLength) ? 1 : 0); + cui.putChars(x, y, 0, textWidth, textChars); + if (textWidth < width) + cui.fillRect(x + textWidth, y, width - textWidth, 1, 0x80 | ' ', 0x80 | ' '); + } + private void charsToText() + { + int i; + for (i = textLength - 1; i >= 0; i--) + textChars[i] &= (byte)0x7F; + text = new String(textChars, 0, textLength); + if (isFocus) + for (i = textLength - 1; i >= 0; i--) + textChars[i] |= (byte)0x80; + else + textChars = null; + cui.drawString(x, y, 0, width, text, 0x80 | ' '); + } + public void setText(String newText) + { + text = newText; + if (text != null) + { + cui.drawString(x, y, 0, width, text, 0x80 | ' '); + cursorPos = (byte)text.length(); + } + else + { + cui.fillRect(x, y, width, 1, 0x80 | ' ', 0x80 | ' '); + cursorPos = 0; + } + if (cursorPos >= width) + cursorPos = (byte)width; + + if (isFocus) + textToChars(); + } + public String getText() + { + if (textChars != null) + charsToText(); + return text; + } + public cuiControl setFocus() + { + cuiControl prevFocus = super.setFocus(); + textToChars(); + return prevFocus; + } + public void unFocus() + { + super.unFocus(); + charsToText(); + } + public boolean event(int msg, int msgData) + { + switch (msg) + { + case EVENT_KEYPRESS: + if (isFocus && ((cui.codeKey < 0x80) || (cui.codeKey == (cui.MODKEY_OPENAPPLE | cui.KEY_DELETE)))) + { + textChars[cursorPos] = cursorSave; + if (cui.codeKey >= ' ' && cui.codeKey <= '~') + { + if (textLength < width) + { + if (cursorPos < textLength++) + for (int c = textLength - 1; c > cursorPos; c--) + textChars[c] = textChars[c - 1]; + textChars[cursorPos++] = (byte)(0x80 | cui.codeKey); + } + else + cui.tone(100, 15, 1); + + } + else if (cui.codeKey == cui.KEY_DELETE) + { + if (cursorPos > 0) + { + textLength--; + for (int c = --cursorPos; c < textLength ; c++) + textChars[c] = textChars[c + 1]; + } + else + cui.tone(100, 15, 1); + } + else if (cui.codeKey == (cui.MODKEY_OPENAPPLE | cui.KEY_DELETE)) + { + if (cursorPos < textLength) + { + textLength--; + for (int c = cursorPos; c < textLength ; c++) + textChars[c] = textChars[c + 1]; + } + } + else if (cui.codeKey == cui.KEY_ARROWLEFT) + { + if (cursorPos > 0) + cursorPos--; + } + else if (cui.codeKey == cui.KEY_ARROWRIGHT) + { + if (cursorPos < textLength) + cursorPos++; + } + else if (cui.codeKey == cui.KEY_RETURN) + { + owner.event(EVENT_TEXTENTRY, ID); + } + if (cursorPos >= width) + { + cursorPos = (byte)(width - 1); + cui.tone(100, 15, 1); + } + textChars[textLength] = (byte)(0x80 | ' '); + cursorSave = textChars[cursorPos]; + textChars[cursorPos] = (byte)(cursorSave & (((cursorSave & 0xE0) == 0xC0) ? 0x1F : 0x7F)); + int textWidth = textLength + ((cursorPos == textLength) ? 1 : 0); + cui.putChars(x, y, 0, textWidth, textChars); + if (textWidth < width) + cui.fillRect(x + textWidth, y, width - textWidth, 1, 0x80 | ' ', 0x80 | ' '); + return true; + } + break; + case EVENT_MOUSEBTTNDOWN: + return true; + } + return false; + } +} diff --git a/src/org/vm02/cui/cuiTopLevelWindow.java b/src/org/vm02/cui/cuiTopLevelWindow.java new file mode 100755 index 0000000..bbb4124 --- /dev/null +++ b/src/org/vm02/cui/cuiTopLevelWindow.java @@ -0,0 +1,36 @@ +// +// java - character user interface +// +package org.vm02.cui; + +public class cuiTopLevelWindow extends cuiWindow +{ + public cuiTopLevelWindow(int topX, int topY, int topWidth, int topHeight, int topID, String topTitle, cuiControl topOwner) + { + super(topX, topY, topWidth, topHeight, topID, topTitle, topOwner); + } + + public cuiControl setFocus() + { + cuiControl prevFocus = super.setFocus(); + nextFocus(this.next); + return prevFocus; + } + public boolean event(int msg, int msgData) + { + switch (msg) + { + case EVENT_KEYPRESS: + if (cui.codeKey == (cui.MODKEY_OPENAPPLE | cui.KEY_TAB)) + { + if (focus != null) + focus.nextFocus(this.next); + else + this.nextFocus(this.next); + return true; + } + break; + } + return false; + } +} diff --git a/src/org/vm02/cui/cuiWindow.java b/src/org/vm02/cui/cuiWindow.java new file mode 100755 index 0000000..90ad9df --- /dev/null +++ b/src/org/vm02/cui/cuiWindow.java @@ -0,0 +1,13 @@ +// +// java - character user interface +// +package org.vm02.cui; + +public class cuiWindow extends cuiControl +{ + public cuiWindow(int winX, int winY, int winWidth, int winHeight, int winID, String winTitle, cuiControl winOwner) + { + super(winX, winY, winWidth, winHeight, winID, (char)-1, 0, winOwner); + cui.frameRect(winX - 1, winY - 1, winWidth + 2, winHeight + 2, 0x80 | ' ', true, winTitle); + } +} diff --git a/src/org/vm02/favac/Scanner.java b/src/org/vm02/favac/Scanner.java new file mode 100755 index 0000000..2ef6a06 --- /dev/null +++ b/src/org/vm02/favac/Scanner.java @@ -0,0 +1,498 @@ +// +// SLACKER - Simple Lexical Analyzer with Constant and Keyword EvaluatoR +// +package org.vm02.favac; +import java.io.*; + +public class Scanner +{ + public final static int TOK_ID = 1; + public final static int TOK_HEXCONST = 2; + public final static int TOK_INTCONST = 3; + public final static int TOK_FLOATCONST = 4; + public final static int TOK_CHARCONST = 5; + public final static int TOK_STRINGCONST = 6; + public final static int TOK_COMMENT = 14; + public final static int TOK_SCANNING = 15; + public final static int TOK_KEYWORD = 16; + public final static int TOK_TOKEN = 128; + public final static int TOK_ENDOFINPUT = 0; + public final static int TOK_ERR = -1; + public final static int TOK_HEXERR = -2; + public final static int TOK_INTERR = -3; + public final static int TOK_FLOATERR = -4; + public final static int TOK_CHARERR = -5; + public final static int TOK_STRINGERR = -6; + public final static int TOK_COMMENTERR = -7; + private final static float[] twoPow10 = {1E+1F,1E+2F,1E+4F,1E+8F,1E+16F,1E+32F,0F,0F}; + private boolean ignoreCase, inComment; + private String keywords[], tokens[]; + private byte inputBlock[]; + private int nextChar; + private InputStream inputFile; + byte inputLine[]; + int inputLen, matchPos; + int intValue; + float floatValue; + String stringValue; + + /* + * Create new inpt scanner of tokens and optional keywords. + */ + public Scanner(InputStream in, String[] tok, String[] kw, boolean kwCase) + { + tokens = tok; + keywords = kw; + ignoreCase = kwCase; + inputFile = in; + inputLine = new byte[256]; + inputBlock = new byte[512]; + nextChar = inputBlock.length; + matchPos = 0; + inputLen = 0; + inComment = false; + } + public Scanner(InputStream in, String[] tok) + { + tokens = tok; + keywords = null; + ignoreCase = false; + inputFile = in; + inputLine = new byte[256]; + inputBlock = new byte[512]; + nextChar = inputBlock.length; + matchPos = 0; + inputLen = 0; + inComment = false; + } + public Scanner(byte[] input, String[] tok, String[] kw, boolean kwCase) + { + tokens = tok; + keywords = kw; + ignoreCase = kwCase; + inputFile = null; + inputLine = input; + inputBlock = inputLine; + nextChar = 0; + matchPos = 0; + inputLen = 0; + inComment = false; + } + private void cleanup() + { + // + // Dereference resources + // + inputLine = null; + inputBlock = null; + tokens = null; + keywords = null; + inputFile = null; + } + protected void finalize() + { + cleanup(); + } + public void finished() + { + cleanup(); + } + private boolean readBlock() + { + /* + * Fetch next block of input. + */ + if (inputFile != null) + { + try + { + int len = inputFile.read(inputBlock); + if (len < inputBlock.length) + { + if (len < 0) + { + nextChar = -1; + return false; + } + else + { + /* + * Shift data to end of inputBlock. + */ + nextChar = inputBlock.length - len; + for (int i = 1; i <= len; i++) + inputBlock[inputBlock.length - i] = inputBlock[len - i]; + } + } + else + nextChar = 0; + } + catch (IOException e) + { + nextChar = -1; + return false; + } + } + else + return false; + return true; + } + /* + * Return escaped character value. + */ + private static byte escapeChar(int esc) + { + switch (esc) + { + case 'n': + return (byte)'\n'; + case 'r': + return (byte)'\r'; + case 't': + return (byte)'\t'; + case 'b': + return (byte)'\b'; + case '\\': + return (byte)'\\'; + case '\'': + return (byte)'\''; + case '\"': + return (byte)'\"'; + } + return (byte)esc; + } + /* + * Get next token from input stream. + */ + public int getToken() + { + byte scanLine[] = inputLine; + int c, p, C, tt; + int matchEnd, matchLen, tokenLen; + String matchToken; + do + { + if (matchPos >= inputLen) + { + /* + * Read until EOL. + */ + if (nextChar < 0) + return TOK_ENDOFINPUT; + /* + * Read until a non-blank line or EOF. + */ + do + { + /* + * Skip leading whitespace. + */ + if (nextChar == inputBlock.length) + { + if (!readBlock()) + return TOK_ENDOFINPUT; + } + + } while (inputBlock[nextChar++] <= ' '); + scanLine[0] = inputBlock[nextChar - 1]; + p = 1; + do + { + /* + * Read until EOL. + */ + if (nextChar == inputBlock.length) + { + if (!readBlock()) + { + if (p++ == 0) + return TOK_ENDOFINPUT; + break; + } + } + c = scanLine[p++] = inputBlock[nextChar++]; + } while (c != '\r' && c != '\n' && p < scanLine.length); + scanLine[p--] = 0; + inputLen = p; + matchPos = 0; + } + /* + * Scan the input line. + */ + C = (c = scanLine[matchPos]) & 0x5F; + /* + * Check for comments + */ + if (inComment) + { + if ((c == '*') && (scanLine[matchPos + 1] == '/')) + { + /* + * Return to scanning for tokens. + */ + inComment = false; + matchPos += 2; + } + else + { + /* + * Eat characters. + */ + while ((++matchPos < (inputLen - 1)) + && (scanLine[matchPos] != '*') + && (scanLine[matchPos + 1] != '/')); + } + } + else if ((c == '/') && (scanLine[matchPos + 1] == '*')) + { + /* + * Inside of comment block. + */ + inComment = true; + matchPos += 2; + } + else if ((c == '/') && (scanLine[matchPos + 1] == '/')) + /* + * Eat rest of line. + */ + inputLen = 0; + else if (c <= ' ') + /* + * Eat whitespace characters. + */ + matchPos++; + /* + * Look for token matches. + */ + else if ((C >= 'A' && C <= 'Z') || (c == '_')) + { + /* + * Match identifier. + */ + matchEnd = matchPos; + do + { + C = (c = scanLine[++matchEnd]) & 0x5F; + } while ((C >= 'A' && C <= 'Z') + || (c >= '0' && c <= '9') + || (c == '_')); + matchLen = matchEnd - matchPos; + if (keywords != null) + { + /* + * Check for keyword match. + */ + for (tt = 0; tt matchLen) + /* + * No match - tokens in acsending length order. + */ + break; + if (matchLen == tokenLen) + { + if (ignoreCase) + for (p = 0; (p < tokenLen) && ((scanLine[matchPos + p] & 0x5F) == matchToken.charAt(p)); p++); + else + for (p = 0; (p < tokenLen) && (scanLine[matchPos + p] == matchToken.charAt(p)); p++); + if (p == tokenLen) + { + /* + * Update current token match. + */ + stringValue = matchToken; + matchPos = matchEnd; + return tt + TOK_KEYWORD; + } + } + } + } + /* + * Create string from token chars. + */ + stringValue = new String(scanLine, matchPos, matchLen); + matchPos = matchEnd; + return TOK_ID; + } + else if ((c == '0') && ((scanLine[matchPos + 1] & 0x5F) == 'X')) + { + /* + * Match hex number constant. + */ + int hex = 0; + matchPos += 2; + while (((c = scanLine[matchPos++]) >= '0' && c <= '9') + || (c >= 'A' && c <= 'F') + || (c >= 'a' && c <= 'f')) + { + C = c & 0x5F; + hex = hex * 16 + (C >= 'A' ? C - ('A' - 10) : c - '0'); + } + intValue = hex; + return TOK_HEXCONST; + } + else if ((c >= '0' && c <= '9') + || (c == '.' && (((p = scanLine[matchPos + 1]) >= '0' && p <= '9')))) + { + /* + * Match number constant. + */ + int mant = 0; + int dp = 0; + boolean negExp = false; + int tokenType = TOK_INTCONST; + while (c >= '0' && c <= '9') + { + mant = mant * 10 + (c - '0'); + c = scanLine[++matchPos]; + } + if (c == '.') + { + /* + * Float fraction. + */ + tokenType = TOK_FLOATCONST; + while (((c = scanLine[++matchPos]) >= '0') && (c <= '9')) + { + dp--; + mant = mant * 10 + (c - '0'); + } + } + if ((c & 0x5F) == 'E') + { + /* + * Float exponent. + */ + int exp = 0; + tokenType = TOK_FLOATCONST; + c = scanLine[++matchPos]; + if (c == '-') + { + negExp = true; + c = scanLine[++matchPos]; + } + else if (c == '+') + c = scanLine[++matchPos]; + if (c >= '0' && c <= '9') + { + exp = c - '0'; + if ((c = scanLine[++matchPos]) >= '0' && c <= '9') + { + exp = exp * 10 + (c - '0'); + c = scanLine[++matchPos]; + } + } + else + return TOK_FLOATERR; // Malformed exponent + if (negExp) + exp = -exp; + dp += exp; + } + if ((c & 0x5F) == 'F') + { + /* + * Force float type. + */ + tokenType = TOK_FLOATCONST; + matchPos++; + } + if (tokenType == TOK_INTCONST) + intValue = mant; + else + { + int place; + float scale; + + if (dp < 0) + { + dp = -dp; + negExp = true; + } + else + negExp = false; + // + // Apply scale + // + for (place = 0, scale = 1.0F; dp != 0; dp >>= 1, place++) + if ((dp & 1) != 0) + scale *= twoPow10[place]; + if (negExp) + floatValue = (float)mant / scale; + else + floatValue = (float)mant * scale; + } + return tokenType; + } + else if (c == '\'') + { + /* + * Match character constant. + */ + tokenLen = 0; + if ((c = scanLine[++matchPos]) == '\\') + intValue = escapeChar(scanLine[++matchPos]); + else + intValue = c; + if (scanLine[++matchPos] != '\'') + return TOK_CHARERR; // Malformed char literal + matchPos++; + return TOK_CHARCONST; + } + else if (c == '\"') + { + /* + * Match string literal. + */ + matchEnd = ++matchPos; + do + { + if ((c = scanLine[matchEnd++]) == '\\') + { + scanLine[matchEnd - 1] = escapeChar(scanLine[matchEnd]); + /* + * Move input down. + */ + for (p = matchEnd; p < inputLen; p++) + scanLine[p] = scanLine[p + 1]; + inputLen--; + } + } while (c != '\"'); + /* + * Create string from token chars. + */ + stringValue = new String(scanLine, matchPos, matchEnd - matchPos - 1); + matchPos = matchEnd; + return TOK_STRINGCONST; + } + else + { + /* + * Match token. + */ + for (tt = 0; tt 0) + { + try + { + input = new FileInputStream(args[0]); + } + catch (FileNotFoundException e) + { + System.err.println("Unable to open file: " + args[0]); + System.exit(-1); + } + catch (IOException e) + { + System.err.println("Unable to access file: " + args[0]); + System.exit(-1); + } + } + Scanner lex = new Scanner(input, fasmTokens, fasmKeywords, true); + while ((tt = lex.getToken()) >= 0) + { + switch (tt) + { + case Scanner.TOK_ID: + System.out.println(lex.stringValue); + break; + case Scanner.TOK_HEXCONST: + case Scanner.TOK_INTCONST: + System.out.println(lex.intValue); + break; + case Scanner.TOK_FLOATCONST: + System.out.println(lex.floatValue); + break; + case Scanner.TOK_CHARCONST: + System.out.println("\'" + (char)lex.intValue + "\'"); + break; + case Scanner.TOK_STRINGCONST: + System.out.println("\"" + lex.stringValue + "\""); + break; + default: + System.out.println(lex.stringValue); + } + } + lex.finished(); + } +} diff --git a/src/org/vm02/favac/favac.java b/src/org/vm02/favac/favac.java new file mode 100755 index 0000000..7657f5a --- /dev/null +++ b/src/org/vm02/favac/favac.java @@ -0,0 +1,182 @@ +// +// favac class +// +package org.vm02.favac; +import java.io.*; + +class favac +{ + private static String favaKeywords[] = { + "if", + "do", + "int", + "new", + "for", + "try", + "void", + "char", + "long", + "else", + "case", + "byte", + "true", + "null", + "float", + "short", + "while", + "break", + "false", + "catch", + "class", + "return", + "static", + "public", + "switch", + "double", + "import", + "default", + "finally", + "private", + "boolean", + "package", + "protected" + }; + private static String favaTokens[] = { + ";", // Statement terminator + "{", // Left brace + "}", // Right brace + "(", // Left paren + ")", // Right paren + ",", // Comma + ".", // Period + "[", // Left bracket + "]", // Right bracket + "==", // Is equal + "=", // Set + "<<", // Left shift + "<=", // Less than or equal + "<", // Less than + ">>>", // Unsigned right shift + ">>", // Right shift + ">=", // Greater than or equal + ">", // Greater than + "++", // Increment operator + "+=", // Plus equals + "+", // Add operator + "--", // Decrement operator + "-=", // Minus equals + "-", // Subract and negate operator + "*=", // Times equals + "*", // Multiply operator + "/=", // Divide equals + "/", // Divide operator + "!=", // Not equal + "!", // Logical not + "%=", // Mod equals + "%", // Mod operator + "||", // Logical OR + "|=", // Bitwise OR equals + "|", // Bitwise OR + "&&", // Logical AND + "&=", // Bitwise AND equals + "&", // Bitwise AND + "^=", // Bitwise XOR equals + "^", // Bitwise XOR + "~=", // Bitwise Compliment equals + "~", // Bitwise compliment + "?", // Question mark - Tertiary if-then-else + ":", // Colon + "\\", // Backslash + "@", // At sign + "#", // Pound sign + "$" // Dollar sign + }; + + static void printIndent(int indent) + { + for (int i = 0; i < indent; i++) + System.out.print(" "); + } + public static void main(String args[]) + { + int tt, prevToken = -1, indent = 0; + InputStream input = System.in; + if (args.length > 0) + { + try + { + input = new FileInputStream(args[0]); + } + catch (FileNotFoundException e) + { + System.err.println("Unable to open file: " + args[0]); + System.exit(-1); + } + catch (IOException e) + { + System.err.println("Unable to access file: " + args[0]); + System.exit(-1); + } + System.out.println(args[0]); + } + Scanner lex = new Scanner(input, favaTokens, favaKeywords, false); + int start = (int)System.currentTimeMillis(); + while ((tt = lex.getToken()) > 0) + { + switch (tt) + { + case Scanner.TOK_ID: + if (prevToken == Scanner.TOK_ID) + System.out.print(' '); + System.out.print(lex.stringValue); + break; + case Scanner.TOK_HEXCONST: + System.out.print("0x"); + System.out.print(Integer.toHexString(lex.intValue)); + break; + case Scanner.TOK_INTCONST: + System.out.print(lex.intValue); + break; + case Scanner.TOK_FLOATCONST: + System.out.print(lex.floatValue); + break; + case Scanner.TOK_CHARCONST: + System.out.print("\'" + (char)lex.intValue + "\'"); + break; + case Scanner.TOK_STRINGCONST: + System.out.print("\"" + lex.stringValue + "\""); + break; + case Scanner.TOK_TOKEN+0: + System.out.println(";"); + printIndent(indent); + break; + case Scanner.TOK_TOKEN+1: + System.out.println(""); + printIndent(indent); + System.out.println("{"); + printIndent(++indent); + break; + case Scanner.TOK_TOKEN+2: + System.out.print("\b\b\b\b"); + System.out.println("}"); + printIndent(--indent); + break; + case Scanner.TOK_TOKEN+5: + System.out.print(", "); + break; + default: + if (tt >= Scanner.TOK_KEYWORD && tt < Scanner.TOK_TOKEN) + System.out.print(lex.stringValue + " "); + else + if (tt > 136 && tt != 146 && tt != 149) + System.out.print(" " + lex.stringValue + " "); + else + System.out.print(lex.stringValue); + } + prevToken = tt; + } + int stop = (int)System.currentTimeMillis(); + lex.finished(); + System.out.println("Elapsed time = " + (stop - start) + " milliseconds"); + } +} diff --git a/src/samples/Catalog.java b/src/samples/Catalog.java new file mode 100755 index 0000000..667bd51 --- /dev/null +++ b/src/samples/Catalog.java @@ -0,0 +1,80 @@ +// +// Catalog.java +// +// +// Created by Astro on 9/26/08. +// Copyright 2008 __MyCompanyName__. All rights reserved. +// +import apple2.*; +import java.io.*; + +public class Catalog +{ + public static void main(String args[]) throws IOException + { + int i, io_buffer, ref_num, bytes_read; + int first_block, entry_length, entries_block, file_count, entry_offset; + String pfx; + byte data_buffer[] = new byte[512]; + + if (args.length > 0) + { + if (ProDOS.setPrefix(args[0]) < 0) + { + System.err.println("Bad prefix: " + args[0]); + return; + } + } + pfx = ProDOS.getPrefix(); + System.out.println(pfx); + io_buffer = ProDOS.allocIOBuffer(); + ref_num = ProDOS.open(pfx, io_buffer); + if (ref_num < 0) + { + System.err.println("Open directory error: " + ref_num); + return; + } + first_block = 1; + entry_length = 0x26; + entries_block = 14; + file_count = 0; + do + { + bytes_read = ProDOS.read(ref_num, data_buffer); + if (bytes_read == 512) + { + if (first_block == 1) + { + entry_length = (int)data_buffer[0x23] & 0xFF; + entries_block = (int)data_buffer[0x24] & 0xFF; + file_count = ((int)data_buffer[0x25] & 0xFF) + | (((int)data_buffer[0x26] & 0xFF) << 8); + } + for (i = first_block; i < entries_block; i++) + { + entry_offset = i * entry_length + 4; + if (data_buffer[entry_offset] != 0) + { + int len = data_buffer[entry_offset] & 0x0F; + System.out.write(data_buffer, entry_offset + 1, len); + if ((data_buffer[entry_offset] & 0xF0) == 0xD0) // Is it a directory? + { + System.out.print('/'); + len++; + } + while (len++ < 40) + System.out.print(' '); + file_count--; + } + } + first_block = 0; + } + else + file_count = 0; + } while (file_count > 0); + ProDOS.close(ref_num); + ProDOS.freeIOBuffer(io_buffer); + System.out.print("\nPress RETURN key..."); + System.in.read(); + } +} diff --git a/src/samples/Copy.java b/src/samples/Copy.java new file mode 100755 index 0000000..a975bcb --- /dev/null +++ b/src/samples/Copy.java @@ -0,0 +1,63 @@ +// +// Sample class to copy a file +// +import java.io.*; + +class Copy +{ + public static void main(String args[]) + { + InputStream input = System.in; + OutputStream output = System.out; + if (args.length > 0) + { + try + { + input = new FileInputStream(args[0]); + } + catch (FileNotFoundException e) + { + System.err.println("Unable to open file: " + args[0]); + System.exit(-1); + } + catch (IOException e) + { + System.err.println("Unable to access file: " + args[0]); + System.exit(-1); + } + } + if (args.length > 1) + { + try + { + output = new FileOutputStream(args[1]); + } + catch (FileNotFoundException e) + { + System.err.println("Unable to open file: " + args[1]); + System.exit(-1); + } + catch (IOException e) + { + System.err.println("Unable to access file: " + args[1]); + System.exit(-1); + } + } + byte buffer[] = new byte[512]; + int len; + try + { + while ((len = input.read(buffer)) > 0) + output.write(buffer, 0, len); + } + catch (IOException e) + { + System.err.println("Error copying file"); + } + finally + { + input.close(); + output.close(); + } + } +} \ No newline at end of file diff --git a/src/samples/Edit.java b/src/samples/Edit.java new file mode 100755 index 0000000..7730a88 --- /dev/null +++ b/src/samples/Edit.java @@ -0,0 +1,9 @@ +import apple2.*; + +public class Edit +{ + public void main(String args[]) + { + + } +} \ No newline at end of file diff --git a/src/samples/FloatStuff.java b/src/samples/FloatStuff.java new file mode 100755 index 0000000..22ac9d4 --- /dev/null +++ b/src/samples/FloatStuff.java @@ -0,0 +1,7 @@ +public class FloatStuff +{ + public static int fpbits(float fp) + { + return(0); + } +} \ No newline at end of file diff --git a/src/samples/Hello.java b/src/samples/Hello.java new file mode 100755 index 0000000..62b467d --- /dev/null +++ b/src/samples/Hello.java @@ -0,0 +1,49 @@ +import apple2.*; +import java.io.*; + +public class Hello { + public static int getLine(byte line[]) throws IOException + { + int k,i = 0; + + while (i < line.length) + { + k = System.in.read(); + switch (k) + { + case -1: + case '\r': + case '\n': + return i; + case 0x08: // BS + case 0x7F: // DEL + if (i > 0) + { + i--; + System.out.print((char)8); // BS + } + else + System.out.print((char)7); // BELL + break; + default: + line[i++] = (byte)k; + } + } + return i; + } + + public static void main(String args[]) throws IOException + { + int i; + byte inputLine[] = new byte[80]; + +// vm02.call(0, 0xC300); + System.out.print("Hello. Enter your name:"); + System.out.flush(); + i = getLine(inputLine); + System.out.print('\n'); + System.out.print("Nice to meet you, "); + System.out.write(inputLine, 0, i); + System.out.println('.'); + } +} diff --git a/src/samples/HelloApple.java b/src/samples/HelloApple.java new file mode 100755 index 0000000..6bf9853 --- /dev/null +++ b/src/samples/HelloApple.java @@ -0,0 +1,70 @@ +class Test1 +{ + public final static int MYCONST = 100000; + public int myInt; + + public void Hello() + { + conio.putchar('1'); + conio.putcr(); + } +} + +class Test2 extends Test1 +{ + public void Hello() + { + conio.putchar('2'); + conio.putcr(); + } +} + +public class TestThread extends Thread +{ + private static void putdigit(int i) + { + if (i > 9) + { + putdigit(i / 10); + } + conio.putchar((char)('0' + i % 10)); + } + public static void putint(int i) + { + if (i < 0) + { + conio.putchar('-'); + i = -i; + } + putdigit(i); + } + public void run() + { + int i; + for (i = 0; i < 1000; i++) + { + conio.gotoxy(20,8); + putint(i); + conio.putcr(); + } + conio.putcr(); + } + public static void main(String[] args) + { + int i, j, k; + float f, g, h; + TestThread thread2 = new TestThread(); + + thread2.setPriority(6); + thread2.start(); + for (i = 0; i < 1000; i++) + { + conio.gotoxy(20,16); + putint(i); + conio.putcr(); + } + conio.putcr(); + return; + } +} + diff --git a/src/samples/HelloWorld.java b/src/samples/HelloWorld.java new file mode 100755 index 0000000..80cb9d2 --- /dev/null +++ b/src/samples/HelloWorld.java @@ -0,0 +1,95 @@ +import apple2.*; + +public class HelloWorld extends Thread +{ + private static boolean finished = false; + private static Object sync = new Object(); + public short SampleShort; + public int SampleInst; + public String Title; + public int TitleRow; + + HelloWorld(String s, int r) + { + Title = s; + TitleRow = r; + } + + public void run() + { + int i = 0; + int ix = 1; + while (!finished) + { + synchronized (sync) + { + conio.gotoXY(i, TitleRow); + conio.print(Title); + } + i = i + ix; + if (i < 0) + { + i = 1; + ix = 1; + } + else if (i > (39 - Title.length())) + { + i = 38 - Title.length(); + ix = -1; + } + sleep(100); + } + } + + public static void main(String[] args) + { + int i, px, key; + HelloWorld h1 = new HelloWorld(" Hello world ", 0); + HelloWorld h2 = new HelloWorld(" Press ESC key to quit... ", 3); + + conio.home(); + conio.gotoXY(0, 5); + conio.print(":_"); + Thread.currentThread().setPriority(6); + h1.start(); // Start HelloWorld thread 1 + h2.start(); // Start HelloWorld thread 2 + px = 1; + while ((key = conio.getKey()) != 27) + { + synchronized (sync) + { + if (key < 32) + { + if (key == 8) // LEFT ARROW + { + if (--px > 0) + { + conio.gotoXY(px,5); + conio.print("_ "); + } + else + px = 1; + } + } + else + { + conio.gotoXY(px, 5); + conio.print((char)key); + conio.print('_'); + if (++px > 38) + { + conio.gotoXY(0,5); + conio.print(":_ "); + px = 1; + } + } + } + } + finished = true; // Flag HelloWorld threads to exit + sleep(500); + conio.home(); + Thread.currentThread().dumpStack(); + conio.println("That's all folks..."); + } +} + diff --git a/src/samples/HiResDemo.java b/src/samples/HiResDemo.java new file mode 100755 index 0000000..c8608aa --- /dev/null +++ b/src/samples/HiResDemo.java @@ -0,0 +1,107 @@ +import apple2.*; + +public class HiResDemo +{ + private static short scanLineAddr[]; + + public static void bitBLT(int xCoord, int yCoord, byte sprite[][], int width, int height, int fillMode) + { + int offset = 0; + int mod7 = xCoord % 7; + int div7 = xCoord / 7; + + switch (fillMode) + { + case 0: + while (height-- > 0) + { + vm02.pokeWord(0xDE, (short)(scanLineAddr[yCoord++] + div7)); // DSTADDR + vm02.call(width, 0x44); // MEMCLR + } + break; + case 1: + while (height-- > 0) + { + vm02.pokeBytes(scanLineAddr[yCoord++] + div7, sprite[mod7], offset, width); + offset += width; + } + break; + case 15: + while (height-- > 0) + { + vm02.pokeWord(0xDE, (short)(scanLineAddr[yCoord++] + div7)); // DSTADDR + vm02.call(0xFF0000 | width, 0x5A); // MEMSET + } + break; + } + } + public static void main(String args[]) + { + byte ball[][] = {{0x1C, 0x00, 0x3E, 0x00, 0x7F, 0x00, 0x7F, 0x00, 0x7F, 0x00, 0x3E, 0x00, 0x1C, 0x00}, + {0x38, 0x00, 0x7C, 0x00, 0x7E, 0x01, 0x7E, 0x01, 0x7E, 0x01, 0x7C, 0x00, 0x38, 0x00}, + {0x70, 0x00, 0x78, 0x01, 0x7C, 0x03, 0x7C, 0x03, 0x7C, 0x03, 0x78, 0x01, 0x70, 0x00}, + {0x60, 0x01, 0x70, 0x03, 0x78, 0x07, 0x78, 0x07, 0x78, 0x07, 0x70, 0x03, 0x60, 0x01}, + {0x40, 0x03, 0x60, 0x07, 0x70, 0x0F, 0x70, 0x0F, 0x70, 0x0F, 0x60, 0x07, 0x40, 0x03}, + {0x00, 0x07, 0x40, 0x0F, 0x60, 0x1F, 0x60, 0x1F, 0x60, 0x1F, 0x40, 0x0F, 0x00, 0x07}, + {0x00, 0x0E, 0x00, 0x1F, 0x40, 0x3F, 0x40, 0x3F, 0x40, 0x3F, 0x00, 0x1F, 0x00, 0x0E}}; + int y, x, yc, xc, w, h, w7, ox, oy; + + if (AppleStuff.hiRes() == false) + { + conio.println("Unable to allocate Hi Res screen."); + return; + } + // + // Fill scanline address array + // + scanLineAddr = new short[192]; + for (y = 0; y < 192; y++) + { + int y210 = y & 0x07; + int y543 = y & 0x38; + int y76 = y & 0xC0; + scanLineAddr[y] = (short)(0x4000 | (y210 << 10) | (y543 << 4) | (y76 >> 1) | (y76 >> 3)); + } + // + // Bounce ball around screen + // + ox = x = 140; + oy = y = 86; + xc = 1; + yc = 1; + w = 2; + h = 7; + w7 = w * 7; + while (!AppleStuff.keyPressed()) + { + bitBLT(ox, oy, ball, w, h, 0); + bitBLT(x, y, ball, w, h, 1); + ox = x; + x += xc; + if (x < 0) + { + xc = -xc; + x = 0; + } + if (x > (279 - w7)) + { + xc = -xc; + x = (279 - w7); + } + oy = y; + y += yc; + if (y < 0) + { + yc = -yc; + y = 0; + } + if (y > (191 - h)) + { + yc = -yc; + y = (191 - h); + } + } + AppleStuff.getKey(); + AppleStuff.text(); + } +} \ No newline at end of file diff --git a/src/samples/HiResPlot.java b/src/samples/HiResPlot.java new file mode 100755 index 0000000..156ae3f --- /dev/null +++ b/src/samples/HiResPlot.java @@ -0,0 +1,27 @@ +import apple2.*; + +public class HiResPlot +{ + + public static void main(String args[]) + { + float x, y, z; + + AppleStuff.hiRes(); + AppleStuff.hrColor(3); + for (y = -1.0F; y <= 1.0F; y += 0.1F) + { + x = -1.0F; + z = -(x * x - y * y); + AppleStuff.hrPlot((int)(x*100) + (int)(y*39) + 140, (int)(y*10) + (int)(z*40) + 96); + while (x < 1.0F) + { + x += 0.1F; + z = -(x * x - y * y); + AppleStuff.hrLineTo((int)(x*100) + (int)(y*39) + 140, (int)(y*10) + (int)(z*40) + 96); + } + } + AppleStuff.getKey(); + AppleStuff.text(); + } +} \ No newline at end of file diff --git a/src/samples/List.java b/src/samples/List.java new file mode 100755 index 0000000..3b9fb91 --- /dev/null +++ b/src/samples/List.java @@ -0,0 +1,164 @@ +import apple2.*; + +public class List +{ + private static char spinner[] = {'!', '/', '-', '\\'}; + public static void show_page(String line_buffer[], int topline) + { + // + // Set text cursor home using direct calls into ROM + // + vm02.pokeByte(0x24, (byte)0); + vm02.pokeByte(0x25, (byte)0); + vm02.call(0, 0xFBC1); + for (int row = 0; row < 23; row++) + // + // Call directly into VM02 to display a string + // + vm02.call(vm02.refAsBits(line_buffer[topline + row]), 0x52); + } + public static void main(String args[]) + { + int io_buffer, ref_num, bytes_read, key, last_line, current_line, current_pos, spin; + boolean carriage_return; + String list_file; + String line_buffer[] = new String[1000]; + byte data_buffer[] = new byte[512]; + byte fill_buffer[] = new byte[40]; + + list_file = (args.length == 1) ? args[0] : "README.TXT"; + conio.home(); + conio.gotoXY(0,23); + conio.print("Loading "); + conio.print(list_file); + io_buffer = ProDOS.allocIOBuffer(); + ref_num = ProDOS.open(list_file, io_buffer); + if (ref_num < 0) + { + conio.print("Open file error: "); + conio.println(-ref_num); + return; + } + // + // Read entire file into line buffer + // + last_line = 0; + current_pos = 0; + spin = 0; + carriage_return = true; + do + { + bytes_read = ProDOS.read(ref_num, data_buffer); + if (bytes_read > 0) + { + conio.gotoXY(38, 23); + conio.print(spinner[spin++ % 4]); + for (int i = 0; i < bytes_read; i++) + { + byte b = (byte)(data_buffer[i] & 0x7F); + if (b == '\n') b = '\r'; + else if (b == 9) b = ' '; + fill_buffer[current_pos] = b; + switch (current_pos) + { + case 39: + int c, wrap; + for (c = 39; c >= 0 && fill_buffer[c] > ' '; c--); + if (c < 0) + { + wrap = 40; + c = 39; + current_pos = 0; + } + else + { + wrap = c + 1; + current_pos = 39 - c; + while (c >= 0 && fill_buffer[c] <= ' ') + c--; + c++; + } + if (c > 0) + line_buffer[last_line] = new String(fill_buffer, 0, c); + for (c = 0; wrap < 40; fill_buffer[c++] = fill_buffer[wrap++]); + if (++last_line >= 1000) + i = bytes_read; + break; + case 0: + if (b <= ' ' && !carriage_return) + // + // Disregard wrapped white space + // + break; + if (b == '\r') + { + carriage_return = true; + if (++last_line >= 1000) + i = bytes_read ; + break; + } + carriage_return = false; + // + // Fall thru + // + default: + if (b >= ' ') + current_pos++; + else if (b == '\r') + { + line_buffer[last_line] = new String(fill_buffer, 0, current_pos); + current_pos = 0; + carriage_return = true; + // + // Display the file as it gets loaded + // + if (++last_line < 24) + show_page(line_buffer, 0); + else if (last_line >= 1000) + i = bytes_read ; + } + } + } + } + } while (bytes_read == data_buffer.length && last_line < 1000); + ProDOS.close(ref_num); + ProDOS.freeIOBuffer(io_buffer); + conio.gotoXY(0, 23); + conio.inverse(); + conio.print(" PRESS ESC TO EXIT, ARROWS TO SCROLL "); + conio.normal(); + current_line = 0; + do + { + show_page(line_buffer, current_line); + key = conio.getKey(); + switch (key) + { + case 'A': + case 'a': + case 'I': + case 'i': + case 0x08: + case 0x0B: + if (--current_line < 0) + current_line = 0; + break; + case 'Z': + case 'z': + case 'M': + case 'm': + case 0x15: + case 0x0A: + if (++current_line + 22 > last_line) + { + current_line = last_line - 22; + if (current_line < 0) + current_line = 0; + } + break; + } + } while (key != 27); // ESC key + if (args.length == 0) + ProDOS.destroy("STARTUP"); + } +} \ No newline at end of file diff --git a/src/samples/Moire.java b/src/samples/Moire.java new file mode 100755 index 0000000..5c54813 --- /dev/null +++ b/src/samples/Moire.java @@ -0,0 +1,36 @@ +import apple2.*; + +public class Moire { + + static void fan(int xc, int yc, int s) + { + int x, y; + + for (x = 0; x < 279; x += s) + { + AppleStuff.hrColor(3); + AppleStuff.hrLine(x, 0, xc, yc); + AppleStuff.hrLineTo(279-x, 191); + AppleStuff.hrColor(0); + AppleStuff.hrLine(x+1, 0, xc, yc); + AppleStuff.hrLineTo(278-x, 191); + } + for (y = 0; y < 191; y += s) + { + AppleStuff.hrColor(3); + AppleStuff.hrLine(279, y, xc, yc); + AppleStuff.hrLineTo(0, 191-y); + AppleStuff.hrColor(0); + AppleStuff.hrLine(279, y+1, xc, yc); + AppleStuff.hrLineTo(0, 190-y); + } + } + + public static void main(String args[]) + { + AppleStuff.hiRes(); + fan(160, 85, 3); + while(!AppleStuff.keyPressed()); + AppleStuff.text(); + } +} \ No newline at end of file diff --git a/src/samples/NextChain.java b/src/samples/NextChain.java new file mode 100755 index 0000000..1371303 --- /dev/null +++ b/src/samples/NextChain.java @@ -0,0 +1,13 @@ +import apple2.*; + +public class NextChain +{ + public static void main(String args[]) + { + System.out.println("Passed arguments:"); + for (int i = 0; i < args.length; i++) + System.out.println(args[i]); + System.out.print("Exit status:"); + System.out.println(vm02.peekWord(0x03E8)); // EXIT_STATUS + } +} diff --git a/src/samples/P8.java b/src/samples/P8.java new file mode 100755 index 0000000..0ddba5d --- /dev/null +++ b/src/samples/P8.java @@ -0,0 +1,86 @@ +import apple2.*; +import java.io.*; + +public class P8 { + public static void main(String args[]) throws IOException + { + int i, io_buffer, ref_num, bytes_read; + int first_block, entry_length, entries_block, file_count, entry_offset; + String pfx, vols[], dump_file; + byte data_buffer[] = new byte[512]; + + System.out.println("Online Volumes:"); + vols = ProDOS.online(); + for (i = 0; i < vols.length; i++) + System.out.println(vols[i]); + pfx = ProDOS.getPrefix(); + System.out.print('\n'); + System.out.print(pfx); + System.out.println(':'); + io_buffer = ProDOS.allocIOBuffer(); + ref_num = ProDOS.open(pfx, io_buffer); + if (ref_num < 0) + { + System.out.print("Open dir error: "); + System.out.println(-ref_num); + return; + } + first_block = 1; + entry_length = 0x26; + entries_block = 14; + file_count = 0; + do + { + bytes_read = ProDOS.read(ref_num, data_buffer); + if (bytes_read == 512) + { + if (first_block == 1) + { + entry_length = (int)data_buffer[0x23] & 0xFF; + entries_block = (int)data_buffer[0x24] & 0xFF; + file_count = ((int)data_buffer[0x25] & 0xFF) + | (((int)data_buffer[0x26] & 0xFF) << 8); + } + for (i = first_block; i < entries_block; i++) + { + entry_offset = i * entry_length + 4; + if (data_buffer[entry_offset] != 0) + { + System.out.write(data_buffer, entry_offset + 1, data_buffer[entry_offset] & 0x0F); + if ((data_buffer[entry_offset] & 0xF0) == 0xD0) // Is it a directory? + System.out.println('/'); + else + System.out.print('\n'); + file_count--; + } + } + first_block = 0; + } + else + file_count = 0; + } while (file_count > 0); + ProDOS.close(ref_num); + dump_file = "P8.java"; + if (args.length == 1) + dump_file = args[0]; + System.out.print('\n'); + System.out.print(pfx); + System.out.println(dump_file); + System.out.print('\n'); + ref_num = ProDOS.open(dump_file, io_buffer); + if (ref_num < 0) + { + System.out.print("Open file error: "); + System.out.println(-ref_num); + return; + } + do + { + bytes_read = ProDOS.read(ref_num, data_buffer); + if (bytes_read > 0) + System.out.write(data_buffer, 0, bytes_read); + } while (bytes_read == data_buffer.length); + ProDOS.close(ref_num); + ProDOS.freeIOBuffer(io_buffer); + } +} diff --git a/src/samples/RodsColors.java b/src/samples/RodsColors.java new file mode 100755 index 0000000..36c4bfd --- /dev/null +++ b/src/samples/RodsColors.java @@ -0,0 +1,38 @@ +import apple2.*; + +public class RodsColors { + + public static void main(String args[]) + { + int i, j, k, w, fmi, fmk, color; + + AppleStuff.loResMix(); + conio.gotoXY(10,22); + conio.print("PRESS ANY KEY TO EXIT."); + while (true) { + for (w = 3; w <= 50; ++w) { + for (i = 1; i <= 19; ++i) { + for (j = 0; j <= 19; ++j) { + k = i + j; + color = (j * 3) / (i + 3) + i * w / 12; + fmi = 40 - i; + fmk = 40 - k; + AppleStuff.lrColor(color); + AppleStuff.lrPlot(i, k); + AppleStuff.lrPlot(k, i); + AppleStuff.lrPlot(fmi, fmk); + AppleStuff.lrPlot(fmk, fmi); + AppleStuff.lrPlot(k, fmi); + AppleStuff.lrPlot(fmi, k); + AppleStuff.lrPlot(i, fmk); + AppleStuff.lrPlot(fmk, i); + if (AppleStuff.keyPressed()) { + AppleStuff.text(); + return; + } + } + } + } + } + } +} \ No newline at end of file diff --git a/src/samples/SimplePong.java b/src/samples/SimplePong.java new file mode 100755 index 0000000..38d782d --- /dev/null +++ b/src/samples/SimplePong.java @@ -0,0 +1,105 @@ +import apple2.*; + +public class SimplePong +{ + public static void main(String[] args) + { + int xBall, yBall, ixBall, iyBall; + int nxBall, nyBall, oxBall, oyBall, hPaddle, spin; + + /* + * Disable VBL interrupts. Causes problems on IIc's. + */ + Mouse.disableIRQ(); + AppleStuff.loRes(); + /* + * Draw bounds. + */ + AppleStuff.lrHLine(0, 39, 0, 15); + AppleStuff.lrVLine(0, 0, 47, 15); + AppleStuff.lrVLine(39, 0, 47, 15); + /* + * Initialize ball. + */ + xBall = 20*32; + ixBall = 1; + yBall = 24*32; + iyBall = 1; + while (!AppleStuff.button(0)) + { + /* + * Update paddle. + */ + hPaddle = AppleStuff.paddle(0) >> 3; + if (hPaddle > 31) hPaddle = 31; + if (hPaddle > 0) + AppleStuff.lrHLine(0, hPaddle - 1, 47, 0); + AppleStuff.lrHLine(hPaddle, hPaddle + 8, 47, 15); + if (hPaddle < 31) + AppleStuff.lrHLine(hPaddle + 9, 39, 47, 0); + /* + * Update ball. + */ + oxBall = xBall >> 5; + oyBall = yBall >> 5; + xBall += ixBall; + if (xBall > (int)(38.9*32) || xBall < 1*32) + { + /* + * Bounce off left or right walls. + */ + AppleStuff.tone(20, 1); + ixBall = -ixBall; + xBall += ixBall; + } + nxBall = xBall >> 5; + yBall += iyBall; + if (yBall < 1*32) + { + /* + * Bounce off top wall. + */ + AppleStuff.tone(20, 1); + iyBall = -iyBall; + yBall += iyBall; + } + else if (yBall > 47*32) + { + if (nxBall >= hPaddle && nxBall <= hPaddle + 8) + { + /* + * Bounce off paddle. + */ + AppleStuff.tone(40, 1); + iyBall = -iyBall - 1; + yBall += iyBall; + spin = (nxBall - hPaddle - 4) << 1; + if (ixBall < 0) + ixBall += spin; + else + ixBall -= spin; + } + else + { + /* + * Missed ball, restart. + */ + AppleStuff.tone(0,3); + xBall = 20*32; + nxBall = xBall >> 5; + ixBall = (ixBall > 0) ? 1 : -1; + yBall = 24*32; + iyBall = 1; + } + } + nyBall = yBall >> 5; + if (oxBall != nxBall || oyBall != nyBall) + { + AppleStuff.lrPlot(oxBall, oyBall, 0); + AppleStuff.lrPlot(nxBall, nyBall, 4); + } + } + AppleStuff.text(); + } +} + diff --git a/src/samples/StressMem.java b/src/samples/StressMem.java new file mode 100755 index 0000000..02bdabf --- /dev/null +++ b/src/samples/StressMem.java @@ -0,0 +1,16 @@ +import java.io.*; + +public class StressMem { + public static void main(String args[]) throws IOException + { + int i, j; + byte stress[][] = new byte[256][256]; + + for (i = 0; i < 256; i++) + { + for (j = 0; j < 256; j++) + stress[i][j] = 69; + System.out.println(i); + } + } +} diff --git a/src/samples/Terminal.java b/src/samples/Terminal.java new file mode 100755 index 0000000..e36c80f --- /dev/null +++ b/src/samples/Terminal.java @@ -0,0 +1,85 @@ +//import java.io.*; +import apple2.*; +/* + * This class interfaces directly with the console and serial port device drivers + * for functiuonality testing and upmost performance. + */ +public class Terminal extends Thread +{ + static boolean done; + static int slot; + + public void run() + { + // + // Set input buffer + // + int sscRead = 0x70 + (slot << 1); + int sscCtrl = 0x90 + (slot << 1); + int sscSlot = slot << 16; + byte inBuff[] = new byte[256]; + int bufferptr = (vm02.call(vm02.refAsBits((Object)inBuff), 0x0E) & 0xFFFF) + 2; // HMEM_LOCK + vm02.call(sscSlot | ((bufferptr & 0xFF) << 8) | 7, sscCtrl); // IOCTL_INBUFFL + vm02.call(sscSlot | (bufferptr & 0xFF00) | 8, sscCtrl); // IOCTL_INBUFFH + while (!done) + // + // Get available char on serial port and send to console + // + vm02.call(vm02.call(sscSlot, sscRead), 0x86); + vm02.call(sscSlot | 7, sscCtrl); // IOCTL_INBUFFL + vm02.call(sscSlot | 8, sscCtrl); // IOCTL_INBUFFH + } + + public static void main(String args[]) + { + int sscSlot, sscCtrl, sscWrite; + Terminal t = new Terminal(); + + // + // Search for super serial card + // + for (slot = 1; slot < 8; slot++) + { + int ssc = vm02.call(1, 0x90 + (slot << 1)); // ID device + if ((ssc & 0x010000FF) == 0x31) // CARRY clear == valid device IOCTL, 0x31 == serial port ID + break; + } + if (slot == 8) + { + System.out.println("Unable to find serial card"); + return; + } + /* + * Disable VBL interrupts to improve serial port IRQ handling. + */ + Mouse.disableIRQ(); + System.out.print("Using serial card in slot #"); + System.out.println(slot); + System.out.println("Settings: 9600,8,1,N"); + System.out.println("Ctrl-Z to quit."); + sscWrite = 0x80 + (slot << 1); + sscCtrl = 0x90 + (slot << 1); + sscSlot = slot << 16; + vm02.call(sscSlot | 2, sscCtrl); // init port + vm02.call(sscSlot | 0x0100 | 20, sscCtrl); // XON/XOFF flow control + vm02.call(sscSlot | 0x0000 | 19, sscCtrl); // 8 data bits + vm02.call(sscSlot | 0x0000 | 18, sscCtrl); // no parity bits + vm02.call(sscSlot | 0x0000 | 17, sscCtrl); // 1 stop bit + vm02.call(sscSlot | 0x0E00 | 16, sscCtrl); // 9600 Baud + vm02.call(sscSlot | 3, sscCtrl); // enable port + done = false; + t.start(); // Start serial port reader thread 1 + while (!done) + { + // + // Get available char on console and send to serial port + // + int key = vm02.call(0, 0x76) & 0x7F; + if (key == 0x1A) // Ctrl-Z = quit + done = true; + else + vm02.call(sscSlot | key , sscWrite); + } + vm02.call(sscSlot | 4, sscCtrl); // disable port + } +} \ No newline at end of file diff --git a/src/samples/TestArp.java b/src/samples/TestArp.java new file mode 100755 index 0000000..207cd28 --- /dev/null +++ b/src/samples/TestArp.java @@ -0,0 +1,179 @@ +import apple2.*; + +public class TestArp extends Thread +{ + private static final int PRTYPE_IP = 0x0800; + private static final int PRTYPE_ARP = 0x0806; + private static final int PRTYPE_RARP = 0x8035; + private static final int ARP_HW_ETH = 1; // ethernet hardware type code + private static final int ARP_REQUEST = 1; + private static final int ARP_REPLY = 2; + private static final int ARP_HEADER_SIZE = 8; + private static final int ARP_HW_TYPE_OFS = 0; // LEN = 2 + private static final int ARP_PR_TYPE_OFS = 2; // LEN = 2 + private static final int ARP_HW_LEN_OFS = 4; // LEN = 1 + private static final int ARP_PR_LEN_OFS = 5; // LEN = 1 + private static final int ARP_OP_OFS = 6; // LEN = 2 + private static final int ARP_SEND_HW_ADDR_OFS = 8; // LEN = ? + private static int ARP_SEND_PR_ADDR_OFS; // LEN = ? + private static int ARP_TARG_HW_ADDR_OFS; // LEN = ? + private static int ARP_TARG_PR_ADDR_OFS; // LEN = ? + private static int ARP_PACKET_SIZE; + private static byte[] ipLocal = {(byte)192,(byte)168,(byte)123,(byte)10}; + private static byte[] ipServer = {(byte)192,(byte)168,(byte)123,(byte)1}; + private static boolean done = false; + + public TestArp() + { + } + public static void setDataField(byte[] packet, int offset, byte[] data) + { + for (int i = 0; i < data.length; i++) + packet[offset + i] = data[i]; + } + public static boolean keyPressed() + { + return ((vm02.call((5 << 19), 0x96) & 0xFF) > 0); + } + public void run() + { + byte[] arp = new byte[ARP_PACKET_SIZE]; + // + // Fill in ARP packet + // + arp[ARP_HW_TYPE_OFS] = (byte)(ARP_HW_ETH >> 8); + arp[ARP_HW_TYPE_OFS + 1] = (byte) ARP_HW_ETH; + arp[ARP_PR_TYPE_OFS] = (byte)(PRTYPE_IP >> 8); + arp[ARP_PR_TYPE_OFS + 1] = (byte) PRTYPE_IP; + arp[ARP_HW_LEN_OFS] = (byte) Ethernet.localAddr().length; + arp[ARP_PR_LEN_OFS] = (byte) ipLocal.length; + arp[ARP_OP_OFS] = (byte)(ARP_REQUEST >> 8); + arp[ARP_OP_OFS + 1] = (byte) ARP_REQUEST; + setDataField(arp, ARP_SEND_HW_ADDR_OFS, Ethernet.localAddr()); + setDataField(arp, ARP_SEND_PR_ADDR_OFS, ipLocal); + setDataField(arp, ARP_TARG_PR_ADDR_OFS, ipServer); + while (!done) + { + System.out.println("Sending ARP ethernet header"); + System.out.print("Sending ARP for address:"); + System.out.print(ipServer[0] & 0xFF); + System.out.print("."); + System.out.print(ipServer[1] & 0xFF); + System.out.print("."); + System.out.print(ipServer[2] & 0xFF); + System.out.print("."); + System.out.println(ipServer[3] & 0xFF); + if (!Ethernet.sendHeader(Ethernet.broadcastAddr(), PRTYPE_ARP, ARP_PACKET_SIZE)) + { + System.out.println("Error sending header!"); + // System.exit(-1); + } + else + { + System.out.println("Sending ARP packet"); + Ethernet.sendData(arp); + Ethernet.xferComplete(); + System.out.println("Waiting for reply packet..."); + } + sleep(10000); // sleep for 10 seconds + } + } + public static void main(String[] args) + { + int len; + byte[] header; + byte[] arp; + + System.out.print('.'); + if (!Ethernet.enable()) + { + System.out.println("Unable to open ethernet device"); + System.exit(-1); + } + System.out.print('.'); + // + // Calculate offsets for remaining fields + // + ARP_SEND_PR_ADDR_OFS = ARP_SEND_HW_ADDR_OFS + Ethernet.localAddr().length; + ARP_TARG_HW_ADDR_OFS = ARP_SEND_PR_ADDR_OFS + ipLocal.length; + ARP_TARG_PR_ADDR_OFS = ARP_TARG_HW_ADDR_OFS + Ethernet.localAddr().length; + ARP_PACKET_SIZE = ARP_TARG_PR_ADDR_OFS + ipLocal.length; + System.out.print('.'); + header = Ethernet.newHeader(); + System.out.print('.'); + arp = new byte[ARP_PACKET_SIZE]; + System.out.print('.'); + TestArp arpSend = new TestArp(); + System.out.print('.'); + Thread.currentThread().setPriority(6); + System.out.print('.'); + arpSend.start(); // Start ARP send thread + System.out.println('!'); + while (!keyPressed()) + { + if ((len = Ethernet.recvHeader(header)) > 0) + { + System.out.print("Received packet of len:"); + System.out.println(len + header.length); + if (Ethernet.getHeaderType(header) == PRTYPE_ARP) + { + if (len > ARP_PACKET_SIZE) len = ARP_PACKET_SIZE; + Ethernet.recvData(arp, 0, len); + System.out.print(" ARP packet type = 0x"); + System.out.println(Integer.toHexString(((arp[ARP_OP_OFS] & 0xFF) << 8) | (arp[ARP_OP_OFS + 1] & 0xFF))); + System.out.print(" from:"); + System.out.print(arp[ARP_SEND_PR_ADDR_OFS] & 0xFF); + System.out.print("."); + System.out.print(arp[ARP_SEND_PR_ADDR_OFS+1] & 0xFF); + System.out.print("."); + System.out.print(arp[ARP_SEND_PR_ADDR_OFS+2] & 0xFF); + System.out.print("."); + System.out.println(arp[ARP_SEND_PR_ADDR_OFS+3] & 0xFF); + System.out.print(" Hardware address:"); + System.out.print(Integer.toHexString(arp[ARP_SEND_HW_ADDR_OFS] & 0xFF)); + System.out.print(":"); + System.out.print(Integer.toHexString(arp[ARP_SEND_HW_ADDR_OFS+1] & 0xFF)); + System.out.print(":"); + System.out.print(Integer.toHexString(arp[ARP_SEND_HW_ADDR_OFS+2] & 0xFF)); + System.out.print(":"); + System.out.print(Integer.toHexString(arp[ARP_SEND_HW_ADDR_OFS+3] & 0xFF)); + System.out.print(":"); + System.out.print(Integer.toHexString(arp[ARP_SEND_HW_ADDR_OFS+4] & 0xFF)); + System.out.print(":"); + System.out.println(Integer.toHexString(arp[ARP_SEND_HW_ADDR_OFS+5] & 0xFF)); + System.out.print(" to:"); + System.out.print(arp[ARP_TARG_PR_ADDR_OFS] & 0xFF); + System.out.print("."); + System.out.print(arp[ARP_TARG_PR_ADDR_OFS+1] & 0xFF); + System.out.print("."); + System.out.print(arp[ARP_TARG_PR_ADDR_OFS+2] & 0xFF); + System.out.print("."); + System.out.println(arp[ARP_TARG_PR_ADDR_OFS+3] & 0xFF); + System.out.print(" Hardware address:"); + System.out.print(Integer.toHexString(arp[ARP_TARG_HW_ADDR_OFS] & 0xFF)); + System.out.print(":"); + System.out.print(Integer.toHexString(arp[ARP_TARG_HW_ADDR_OFS+1] & 0xFF)); + System.out.print(":"); + System.out.print(Integer.toHexString(arp[ARP_TARG_HW_ADDR_OFS+2] & 0xFF)); + System.out.print(":"); + System.out.print(Integer.toHexString(arp[ARP_TARG_HW_ADDR_OFS+3] & 0xFF)); + System.out.print(":"); + System.out.print(Integer.toHexString(arp[ARP_TARG_HW_ADDR_OFS+4] & 0xFF)); + System.out.print(":"); + System.out.println(Integer.toHexString(arp[ARP_TARG_HW_ADDR_OFS+5] & 0xFF)); + } + else + { + System.out.print(" Non-ARP packet type = 0x"); + System.out.println(Integer.toHexString(Ethernet.getHeaderType(header))); + } + } + else + System.out.println("Received bad packet"); + Ethernet.xferComplete(); + } + System.out.println("Exiting..."); + done = true; + sleep(10500); + } +} diff --git a/src/samples/TestCUI.java b/src/samples/TestCUI.java new file mode 100755 index 0000000..e12e68b --- /dev/null +++ b/src/samples/TestCUI.java @@ -0,0 +1,169 @@ +import org.vm02.cui.*; + +public class TestCUI extends cuiApp +{ + int xBanner = 55; + String banner = "This is a scrolling message for your amusement while you figure out what to do..."; + String listText[] = { + "Welcome to the VM02 Character User Interface", + "demonstration. Keyboard users should use the", + "arrow keys to move up and down in this list. The", + "shortcut key to the menu bar is OpenApple-ESC.", + "Use OpenApple-TAB to move between the main controls", + "in the screen. OpenApple-X is the accelerator key", + "for the Exit button. When a pop-up window contains", + "a Cancel and/or Okay button, ESC will Cancel, RETURN", + "will accept. Mouse users should feel right at home.", + "Remember that this is just an 8 bit, 1 Mhz computer with", + "128K of RAM. Don't expect too much from it. 95% of", + "this environment is running as Java bytecode; DVM and", + "6502 code make up the rest in the device drivers.", + "", + "Feel free to look around,", + "Dave..."}; + cuiListBox listBox; + cuiTextEntry textEnter; + + public void start() + { + super.start(); + String menuItems[][] = { + {" File ", " New O-N ", " Open O-O ", " Save O-S ", " Save As ", " Close O-W ", null, " Quit O-Q "}, + {" Edit ", " Undo O-Z ", " Copy O-C ", " Paste O-V ", " Cut O-X ", null, " Find O-F ", " Replace O-R "}, + {" Help ", " Show Help O-H "}}; + char menuItemsAccel[][] = { + {(char)(cui.MODKEY_OPENAPPLE|'n'), (char)(cui.MODKEY_OPENAPPLE|'o'), (char)(cui.MODKEY_OPENAPPLE|'s'), (char)-1, (char)(cui.MODKEY_OPENAPPLE|'w'), (char)-1, (char)(cui.MODKEY_OPENAPPLE|'q')}, + {(char)(cui.MODKEY_OPENAPPLE|'c'), (char)(cui.MODKEY_OPENAPPLE|'v'), (char)(cui.MODKEY_OPENAPPLE|'x'), (char)-1, (char)(cui.MODKEY_OPENAPPLE|'f'), (char)(cui.MODKEY_OPENAPPLE|'r')}, + {(char)(cui.MODKEY_OPENAPPLE|'h')}}; + cuiMenuBar menuBar = new cuiMenuBar(menuItems, menuItemsAccel, (cuiControl)this); + //cuiConsole winDbg = new cuiConsole(2, 18, 40, 5, 666, " Debug Console ", (cuiControl)this); + cuiTopLevelWindow winMain = new cuiTopLevelWindow(10, 3, 60, 18, 0, " Hello World ", (cuiControl)this); + listBox = new cuiListBox(11, 7, 58, 5, listText.length, (cuiControl)this); + textEnter = new cuiTextEntry(11, 14, 58, "Enter banner text here", true, 0, (cuiControl)this); + cuiButton bttn = new cuiButton(33, 17, 15, 3, "Exit", true, (char)(cui.MODKEY_OPENAPPLE|'x'), 69, (cuiControl)this); + listBox.setFocus(); + } + public boolean event(int msg, int msgData) + { + int itemX, itemY, itemWidth, itemIndex; + switch (msg) + { + case EVENT_TIMEOUT: + if (xBanner >= 0) + { + cui.drawString(xBanner + 12, 5, 0, 56 - xBanner, banner, cui.MODKEY_OPENAPPLE|' '); + xBanner--; + } + else + { + cui.drawString(12, 5, -xBanner, 56, banner, cui.MODKEY_OPENAPPLE|' '); + if (xBanner-- < -banner.length()) + xBanner = 55; + } + return true; + case cuiListBox.EVENT_LISTITEMDRAW: + itemX = msgData >> 24; + itemY = (msgData >> 16) & 0xFF; + itemWidth = (msgData >> 8) & 0xFF; + itemIndex = msgData & 0xFF; + cui.drawString(itemX, itemY, 0, itemWidth, listText[itemIndex], cui.MODKEY_OPENAPPLE | ' '); + return true; + case cuiListBox.EVENT_LISTITEMDRAWHILITE: + itemX = msgData >> 24; + itemY = (msgData >> 16) & 0xFF; + itemWidth = (msgData >> 8) & 0xFF; + itemIndex = msgData & 0xFF; + cui.drawInverseString(itemX, itemY, 0, itemWidth, listText[itemIndex], ' '); + return true; + case cuiListBox.EVENT_LISTITEMSELECT: + textEnter.setText(listText[msgData]); + return true; + case cuiMenuBar.EVENT_MENUBARITEMSELECT: + switch (msgData) + { + case 0x00010001: + fileNew(); + break; + case 0x00010002: + fileOpen(); + break; + case 0x00010003: + fileSave(); + break; + case 0x00010004: + fileSaveAs(); + break; + case 0x00010005: + fileClose(); + break; + case 0x00010007: + quit(); + break; + case 0x00020001: + editCopy(); + break; + case 0x00020002: + editPaste(); + break; + case 0x00020003: + editCut(); + break; + case 0x00030001: + help(); + break; + } + return true; + case cuiTextEntry.EVENT_TEXTENTRY: + banner = textEnter.getText(); + case cuiButton.EVENT_BUTTONPRESS: + if (msgData == 69) + quit(); + break; + } + return false; + } + private void quit() + { + cuiMessageBox msgBox = new cuiMessageBox("Quit Verification", "Really quit?", cuiMessageBox.MSGBOX_OK | cuiMessageBox.MSGBOX_CANCEL); + if (msgBox.reply() == EVENT_OK) + quit = true; + } + private void fileNew() + { + } + private void fileOpen() + { + cuiMessageBox msgBox = new cuiMessageBox("OpenFile", "Select a file here, someday", cuiMessageBox.MSGBOX_OK); + msgBox.reply(); + } + private void fileSave() + { + } + private void fileSaveAs() + { + } + private void fileClose() + { + } + private void editCopy() + { + } + private void editPaste() + { + } + private void editCut() + { + } + private void help() + { + } + + public static void main(String args[]) + { + TestCUI testApp = new TestCUI(); + testApp.start(); + testApp.eventTimeOut = 333; + testApp.run(12); + testApp.stop(); + } +} \ No newline at end of file diff --git a/src/samples/TestChain.java b/src/samples/TestChain.java new file mode 100755 index 0000000..8bf1e2b --- /dev/null +++ b/src/samples/TestChain.java @@ -0,0 +1,19 @@ +import apple2.*; + +public class TestChain +{ + public static void main(String args[]) + { + String ChainCmd = "samples/NextChain Hello"; + System.out.println("Test chain command.."); + System.out.print("Sending chain: "); + System.out.println(ChainCmd); + int stringptr = vm02.call(vm02.refAsBits((Object)ChainCmd), 0x0E) & 0xFFFF; // HMEM_LOCK + vm02.call(stringptr+1, 0x3E); // MEMSRC + vm02.call(0x0200, 0x40); // MEMDST + vm02.call(ChainCmd.length(), 0x42); // MEMCPY + vm02.call(vm02.refAsBits((Object)ChainCmd), 0x10); // HMEM_UNLOCK + vm02.pokeByte(0x03EC, (byte)ChainCmd.length()); // CHAIN_CMD + System.exit(1234); + } +} diff --git a/src/samples/TestSelect.java b/src/samples/TestSelect.java new file mode 100755 index 0000000..ba2ed57 --- /dev/null +++ b/src/samples/TestSelect.java @@ -0,0 +1,50 @@ +import apple2.*; + +public class TestSelect +{ + public static int select(int mask) throws InterruptedException + { + return (vm02.call(mask | 0x08, 0x80) & 0xFF); + } + public static void main(String args[]) + { + int curtid = vm02.call(0, 0x1C) & 0x00FF0000; // THREAD_GET_CURRENT + int selectMask; + + conio.home(); + if (Mouse.enable()) + { + selectMask = Mouse.slotMask(); + conio.print("Mouse slot mask = "); + conio.println(selectMask); + } + else + { + conio.println("Unable to find mouse card"); + return; + } + do + { + vm02.call(curtid | 10000, 0x1E); // THREAD_SETTIMEOUTL for 10 seconds + // vm02.call(curtid | (tparam >> 16 ), 0x20); // THREAD_SETTIMEOUTH + try + { + if (select(selectMask | 0x08) == selectMask) + { + Mouse.update(); + conio.gotoXY(8,6); + conio.print("X Pos:"); conio.print(Mouse.xPos); conio.print(" "); + conio.gotoXY(8,8); + conio.print("Y Pos:"); conio.print(Mouse.yPos); conio.print(" "); + conio.gotoXY(8,10); + conio.print("Status:"); conio.print(Mouse.status); conio.print(" "); + } + } + catch (InterruptedException e) + { + conio.println("Timed out"); + } + } while (!conio.keyPressed()); + Mouse.disable(); + } +} \ No newline at end of file diff --git a/src/samples/TestThread.java b/src/samples/TestThread.java new file mode 100755 index 0000000..ea883d7 --- /dev/null +++ b/src/samples/TestThread.java @@ -0,0 +1,71 @@ +public class TestThread extends Thread +{ + private static boolean done; + private int htab, vtab; + + TestThread(int x, int y) + { + htab = x; + vtab = y; + } + + private static void putdigit(int i) + { + if (i > 9) + { + putdigit(i / 10); + } + conio.putchar((char)('0' + i % 10)); + } + public static void putint(int i) + { + if (i < 0) + { + conio.putchar('-'); + i = -i; + } + putdigit(i); + } + synchronized public static void printat(int x, int y, int i) + { + conio.gotoxy(x, y); + putint(i); + } + synchronized public static void printat(int x, int y, char c) + { + conio.gotoxy(x, y); + conio.putchar(c); + } + public void run() + { + int i = 0; + while (!done) + { + printat(htab, vtab, i++); + } + } + public static void main(String[] args) + { + int cx, cy; + char key; + TestThread thread2 = new TestThread(20, 8); + done = false; + conio.home(); + cx = 0; + cy = 20; + thread2.start(); + do + { + key = conio.getchar(); + printat(cx, cy, key); + if (++cx > 39) + { + while (--cx > 0) + printat(cx,cy, ' '); + } + } while ((key & 0x7F) != 'Q'); + done = true; + return; + } +} + diff --git a/src/samples/Timer.java b/src/samples/Timer.java new file mode 100755 index 0000000..57f26de --- /dev/null +++ b/src/samples/Timer.java @@ -0,0 +1,12 @@ +public class Timer { + public static void main(String args[]) + { + int i; + while (System.in.available() == 0) + { + i = (int)System.currentMillis(); + System.out.println(i); + Thread.currentThread().yield(); + } + } +} \ No newline at end of file diff --git a/src/samples/Volumes.java b/src/samples/Volumes.java new file mode 100755 index 0000000..1d5b4f9 --- /dev/null +++ b/src/samples/Volumes.java @@ -0,0 +1,24 @@ +// +// Volumes.java +// +// +// Created by Astro on 9/26/08. +// Copyright 2008 __MyCompanyName__. All rights reserved. +// +import apple2.*; +import java.io.*; + +public class Volumes +{ + public static void main(String args[]) throws IOException + { + String vols[]; + + System.out.println("Online Volumes:"); + vols = ProDOS.online(); + for (int i = 0; i < vols.length; i++) + System.out.println(vols[i] + "/"); + System.out.print("\nPress RETURN key..."); + System.in.read(); + } +} diff --git a/src/sscdrvr.s b/src/sscdrvr.s new file mode 100755 index 0000000..707cd24 --- /dev/null +++ b/src/sscdrvr.s @@ -0,0 +1,344 @@ +;* +;* SUPER SERIAL CARD DEVICE DRIVER +;* +; +; SERIAL PORT DEFINES +; +;HW_FLOWCTRL EQU 1 +XON EQU $11 +XOFF EQU $13 +SSC_INIT: LDA #$00 ; ZERO OUT INBUFF GET/PUT INDECES + STA $0578,Y + STA $05F8,Y + STA $07F8,Y ; CLEAR FLAGS + LDX SLOT2IO,Y + LDA #$00 + STA $C089,X ; PROGRAMMED RESET + CLC + RTS +SSC_DRIVER: +SSC_DRVR_SZ: .WORD SSC_DRVR_END - SSC_DRVR_START +SSC_READ_OFS: .WORD SSC_READ - SSC_DRVR_START +SSC_WRITE_OFS: .WORD SSC_WRITE - SSC_DRVR_START +SSC_CTRL_OFS: .WORD SSC_CTRL - SSC_DRVR_START +SSC_IRQ_OFS: .WORD SSC_IRQ - SSC_DRVR_START +SSC_DRVR_START: +SSC_READ: TYA ; READ CHARACTER FROM BUFFER + TAX +SSCRRETRY: SEI + LDA $0578,X ; GET INDEX + CMP $05F8,X ; CHECK FOR EMPTY + BNE :+ + CLI + TXA + PHA + LDY CURRENT_THREAD + JSR THREAD_NOTIMEOUT + PLA + TAY ; LOAD SLOT # + PHA + JSR THREAD_WAITIO + PLA + TAX + LDA $07F8,X + AND #$01 ; PORT STILL ACTIVE? + BNE SSCRRETRY + RTS ; NOPE +: LDY $0678,X ; SET UP BUFFER POINTERS + STY TMPTR + LDY $06F8,X + STY TMPTR+1 + TAY + LDA (TMPTR),Y + PHA + INY + TYA + STA $0578,X ; INCREMENT GET INDEX + CMP $05F8,X + BEQ :+ + TXA + PHA + TAY + JSR THREAD_NOTIFYIO ; NOTIFY SELECT_IO + PLA + TAX +: PLA + LDY $07F8,X + BMI :+ ; CHECK FOR XON/XOFF + CLC + RTS +: PHA + TYA + AND #$40 + BEQ SSCXONEXIT + LDA $05F8,X + SEC + SBC $0578,X + CMP #$10 + BCS SSCXONEXIT + TYA + AND #$BF + STA $07F8,X + LDY SLOT2IO,X +.IFDEF HW_FLOWCTRL + LDA $C08A,Y ; ENABLE RECEIVER + ORA #$01 + STA $C08A,Y +.ELSE +: LDA $C089,Y + AND #$10 + BEQ :- + LDA #XON ; SEND XON + STA $C088,Y +.ENDIF + SEI + TXA + TAY + JSR THREAD_NOTIFYIO ; WAKE UP ANY WAITING WRITES +SSCXONEXIT: PLA + CLC + RTS +SSC_WRITE: PHA ; WRITE CHARACTER TO SERIAL PORT + LDA $07F8,Y + BPL SSCWRETRY ; CHECK FOR FLOW CONTROL + AND #$40 + BEQ SSCWRETRY + TYA + PHA + LDY CURRENT_THREAD + JSR THREAD_NOTIMEOUT + PLA + TAY ; LOAD SLOT # + PHA + JSR THREAD_WAITIO + PLA + TAY + LDA $07F8,Y + AND #$01 ; PORT STILL ACTIVE? + TAX + PLA + DEX + BEQ SSC_WRITE + RTS +SSCWRETRY: LDX SLOT2IO,Y +: LDA $C089,X ; DO THIS WITH INTS ENABLED + AND #$10 ; SO READS DON'T GET STARVED + BEQ :- ; HOPEFULLY WON'T CLEAR INT BEFORE IRQ + PLA + STA $C088,X + CLC + RTS +SSC_CTRL: PHA + TYA ; GET ENCODED IOCTL + AND #$F8 ; MASK OFF SLOT # + PHA + TYA + AND #$07 ; GET SLOT # + TAY + PLA + CMP #IOCTL_AVAIL + BNE :+ + PLA + SEI ; AVAILABLE CHARS IN BUFFER + LDA $05F8,Y ; GET INDEX + SEC + SBC $0578,Y ; MINUS PUT INDEX + CLC + RTS +: CMP #IOCTL_SPACE + BNE :+ + PLA + LDA $07F8,Y ; CHECK FOR FLOW CONTROL + AND #$40 + ASL + ASL + ROL + EOR #$01 + RTS +: CMP #SERCTL_BAUD + BNE :+ + PLA + STX TMP + LDX SLOT2IO,Y + LDA $C08B,X + AND #$E0 + ORA TMP + EOR #$10 + STA $C08B,X + CLC + RTS +: CMP #SERCTL_DATABITS + BNE :+ + PLA + TXA + ASL + ASL + ASL + ASL + ASL + STA TMP + LDX SLOT2IO,Y + LDA $C08B,X + AND #$9F + ORA TMP + STA $C08B,X + CLC + RTS +: CMP #SERCTL_PARITYBITS + BNE :+ + PLA + TXA + ASL + ASL + ASL + ASL + ASL + STA TMP + LDX SLOT2IO,Y + LDA $C08A,X + AND #$1F + ORA TMP + STA $C08A,X + CLC + RTS +: CMP #SERCTL_STOPBITS + BNE :+ + PLA + TXA + LSR + ROR + STA TMP + LDX SLOT2IO,Y + LDA $C08B,X + AND #$7F + ORA TMP + STA $C08B,X + CLC + RTS +: CMP #SERCTL_XONXOFF + BNE :+ + PLA + LDA $07F8,Y + AND #$7F + STA $07F8,Y + TXA + LSR + LDA #$00 + ROR + ORA $07F8,Y + STA $07F8,Y + CLC + RTS +: CMP #IOCTL_INBUFF + BNE :+ + TXA + STA $06F8,Y + PLA + STA $0678,Y + CLC + RTS +;: CMP #IOCTL_INBUFFSZL +; BNE :+ +;: CMP #IOCTL_INBUFFSZH +; BNE :+ +: CMP #IOCTL_OPEN + BNE :+ + PLA + LDX SLOT2IO,Y + LDA $C08A,X + AND #$F0 ; ENABLE XFER & INTS + ORA #$09 + STA $C08A,X + LDA $07F8,Y ; SET ENABLE FLAG + ORA #$01 + STA $07F8,Y + LDA #$00 + STA $04F8,Y ; CLEAR STATUS ON IIC + CLC + RTS +: CMP #IOCTL_CLOSE + BNE :+ + LDA #IOCTL_DEACTIVATE +: CMP #IOCTL_DEACTIVATE + BNE :+ + PLA + LDX SLOT2IO,Y + LDA $C08A,X + AND #$F0 ; DISABLE XFER & INTS + STA $C08A,X + LDA $07F8,Y ; CLEAR ENABLE FLAG + AND #$FE + STA $07F8,Y +; TYA + JSR THREAD_NOTIFYIO ; WAKE UP ANY WAITING THREADS + CLC + RTS +: CMP #IOCTL_ID + BEQ :+ + PLA + SEC + RTS +: PLA + LDA #$31 ; SSC ID + CLC + RTS +SSC_IRQ: TAX ; A = IRQ SLOT # + LDA MACHID + AND #$08 ; CHECK FOR IIC + BNE SSC_IRQIIC + LDY SLOT2IO,X + LDA $C089,Y ; LOAD STATUS + BMI SSCSERVINT ; IRQ = BIT 7 + SEC + RTS +SSC_IRQIIC: LDA $04F8,X ; LOAD SAVED STATUS + BMI SSCSERVINTIIC + SEC + RTS +SSCSERVINTIIC: AND #$7F ; MARK INT CLEAR + STA $04F8,X + LDY SLOT2IO,X +SSCSERVINT: AND #$08 ; RECEIVE DATA + BEQ SSCEXIT + LDA $C088,Y ; READ CHARACTER + LDY $0678,X ; SET UP BUFFER POINTERS + STY TMPTR + LDY $06F8,X + STY TMPTR+1 + LDY $05F8,X ; PUT INDEX + STA (TMPTR),Y ; STORE CHAR IN BUFF + INY + TYA + CMP $0578,X ; CHECK FOR FULL + BEQ SSCEXIT ; FULL, SKIP INC + STA $05F8,X ; INC PUT INDEX + LDY $07F8,X ; CHECK FOR XON/XOFF ENABLE + BMI :+ +SSCEXIT: CLC + RTS +: SEC + SBC $0578,X + CMP #$E0 ; ABOVE THRESHOLD? + BCC SSCEXIT+1 + TYA + AND #$40 ; ALREAD SENT XOFF? + BNE SSCEXIT + LDY SLOT2IO,X +.IFDEF HW_FLOWCTRL + LDA $C08A,Y ; DISABLE RECEIVER + AND #$FE + STA $C08A,Y +.ELSE +: LDA $C089,Y + BMI SSCSERVINT + AND #$10 + BEQ :- + LDA #XOFF ; SEND XOFF + STA $C088,Y +.ENDIF + LDA $07F8,X + ORA #$40 ; SET XOFF FLAG + STA $07F8,X + CLC + RTS +SSC_DRVR_END EQU * diff --git a/src/string.clasm b/src/string.clasm new file mode 100755 index 0000000..b675fbe --- /dev/null +++ b/src/string.clasm @@ -0,0 +1,1569 @@ +;* +;* CLASS FILE _String.class +;* + .ORG $1000 ; DUMMY ADDRESS + .BYTE $CA,$FE,$BA,$BE ; MAGIC + .BYTE $00,$00 ; MINOR 0 + .BYTE $00,$31 ; MAJOR 49 +;* +;* CONSTANT POOL +;* + .BYTE $00,$46 ; CONST POOL COUNT 70 +;* CONST POOL INDEX 1 + .BYTE $0A ; METHODREF + .BYTE $00,$03 ; CLASS #3 + .BYTE $00,$41 ; NAME AND TYPE #65 +;* CONST POOL INDEX 2 + .BYTE 07 ; CLASS + .BYTE $00,68 ; #68 +;* CONST POOL INDEX 3 + .BYTE 07 ; CLASS + .BYTE $00,67 ; #67 +;* CONST POOL INDEX 4 + .BYTE $01 ; UTF8 + .BYTE $00,$01 ; STRLEN + .BYTE "_" +;* CONST POOL INDEX 5 + .BYTE $01 ; UTF8 + .BYTE $00,$01 ; STRLEN + .BYTE "I" +;* CONST POOL INDEX 6 + .BYTE $01 ; UTF8 + .BYTE $00,$06 ; STRLEN + .BYTE "" +;* CONST POOL INDEX 7 + .BYTE $01 ; UTF8 + .BYTE $00,$03 ; STRLEN + .BYTE "()V" +;* CONST POOL INDEX 8 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "Code" +;* CONST POOL INDEX 9 + .BYTE $01 ; UTF8 + .BYTE $00,$06 ; STRLEN + .BYTE "([BI)V" +;* CONST POOL INDEX 10 + .BYTE $01 ; UTF8 + .BYTE $00,$07 ; STRLEN + .BYTE "([BII)V" +;* CONST POOL INDEX 11 + .BYTE $01 ; UTF8 + .BYTE $00,$05 ; STRLEN + .BYTE "([C)V" +;* CONST POOL INDEX 12 + .BYTE $01 ; UTF8 + .BYTE $00,$07 ; STRLEN + .BYTE "([CII)V" +;* CONST POOL INDEX 13 + .BYTE $01 ; UTF8 + .BYTE $00,$15 ; STRLEN + .BYTE "(Ljava/lang/String;)V" +;* CONST POOL INDEX 14 + .BYTE $01 ; UTF8 + .BYTE $00,$1B ; STRLEN + .BYTE "(Ljava/lang/StringBuffer;)V" +;* CONST POOL INDEX 15 + .BYTE $01 ; UTF8 + .BYTE $00,$06 ; STRLEN + .BYTE "charAt" +;* CONST POOL INDEX 16 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "(I)C" +;* CONST POOL INDEX 17 + .BYTE $01 ; UTF8 + .BYTE $00,$09 ; STRLEN + .BYTE "compareTo" +;* CONST POOL INDEX 18 + .BYTE $01 ; UTF8 + .BYTE $00,$15 ; STRLEN + .BYTE "(Ljava/lang/String;)I" +;* CONST POOL INDEX 19 + .BYTE $01 ; UTF8 + .BYTE $00,$06 ; STRLEN + .BYTE "concat" +;* CONST POOL INDEX 20 + .BYTE $01 ; UTF8 + .BYTE $00,$26 ; STRLEN + .BYTE "(Ljava/lang/String;)Ljava/lang/String;" +;* CONST POOL INDEX 21 + .BYTE $01 ; UTF8 + .BYTE $00,$0B ; STRLEN + .BYTE "copyValueOf" +;* CONST POOL INDEX 22 + .BYTE $01 ; UTF8 + .BYTE $00,$16 ; STRLEN + .BYTE "([C)Ljava/lang/String;" +;* CONST POOL INDEX 23 + .BYTE $01 ; UTF8 + .BYTE $00,$18 ; STRLEN + .BYTE "([CII)Ljava/lang/String;" +;* CONST POOL INDEX 24 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "endsWith" +;* CONST POOL INDEX 25 + .BYTE $01 ; UTF8 + .BYTE $00,$15 ; STRLEN + .BYTE "(Ljava/lang/String;)Z" +;* CONST POOL INDEX 26 + .BYTE $01 ; UTF8 + .BYTE $00,$06 ; STRLEN + .BYTE "equals" +;* CONST POOL INDEX 27 + .BYTE $01 ; UTF8 + .BYTE $00,$15 ; STRLEN + .BYTE "(Ljava/lang/Object;)Z" +;* CONST POOL INDEX 28 + .BYTE $01 ; UTF8 + .BYTE $00,$10 ; STRLEN + .BYTE "equalsIgnoreCase" +;* CONST POOL INDEX 29 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "getBytes" +;* CONST POOL INDEX 30 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "(II[BI)V" +;* CONST POOL INDEX 31 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "getChars" +;* CONST POOL INDEX 32 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "(II[CI)V" +;* CONST POOL INDEX 33 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "hashCode" +;* CONST POOL INDEX 34 + .BYTE $01 ; UTF8 + .BYTE $00,$03 ; STRLEN + .BYTE "()I" +;* CONST POOL INDEX 35 + .BYTE $01 ; UTF8 + .BYTE $00,$07 ; STRLEN + .BYTE "indexOf" +;* CONST POOL INDEX 36 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "(I)I" +;* CONST POOL INDEX 37 + .BYTE $01 ; UTF8 + .BYTE $00,$05 ; STRLEN + .BYTE "(II)I" +;* CONST POOL INDEX 38 + .BYTE $01 ; UTF8 + .BYTE $00,$16 ; STRLEN + .BYTE "(Ljava/lang/String;I)I" +;* CONST POOL INDEX 39 + .BYTE $01 ; UTF8 + .BYTE $00,$06 ; STRLEN + .BYTE "intern" +;* CONST POOL INDEX 40 + .BYTE $01 ; UTF8 + .BYTE $00,$14 ; STRLEN + .BYTE "()Ljava/lang/String;" +;* CONST POOL INDEX 41 + .BYTE $01 ; UTF8 + .BYTE $00,$0B ; STRLEN + .BYTE "lastIndexOf" +;* CONST POOL INDEX 42 + .BYTE $01 ; UTF8 + .BYTE $00,$06 ; STRLEN + .BYTE "length" +;* CONST POOL INDEX 43 + .BYTE $01 ; UTF8 + .BYTE $00,$0D ; STRLEN + .BYTE "regionMathces" +;* CONST POOL INDEX 44 + .BYTE $01 ; UTF8 + .BYTE $00,$19 ; STRLEN + .BYTE "(ZILjava/lang/String;II)Z" +;* CONST POOL INDEX 45 + .BYTE $01 ; UTF8 + .BYTE $00,$18 ; STRLEN + .BYTE "(ILjava/lang/String;II)Z" +;* CONST POOL INDEX 46 + .BYTE $01 ; UTF8 + .BYTE $00,$07 ; STRLEN + .BYTE "replace" +;* CONST POOL INDEX 47 + .BYTE $01 ; UTF8 + .BYTE $00,$16 ; STRLEN + .BYTE "(CC)Ljava/lang/String;" +;* CONST POOL INDEX 48 + .BYTE $01 ; UTF8 + .BYTE $00,$0A ; STRLEN + .BYTE "startsWith" +;* CONST POOL INDEX 49 + .BYTE $01 ; UTF8 + .BYTE $00,$09 ; STRLEN + .BYTE "startWith" +;* CONST POOL INDEX 50 + .BYTE $01 ; UTF8 + .BYTE $00,$16 ; STRLEN + .BYTE "(Ljava/lang/String;I)Z" +;* CONST POOL INDEX 51 + .BYTE $01 ; UTF8 + .BYTE $00,$09 ; STRLEN + .BYTE "subString" +;* CONST POOL INDEX 52 + .BYTE $01 ; UTF8 + .BYTE $00,$15 ; STRLEN + .BYTE "(I)Ljava/lang/String;" +;* CONST POOL INDEX 53 + .BYTE $01 ; UTF8 + .BYTE $00,$16 ; STRLEN + .BYTE "(II)Ljava/lang/String;" +;* CONST POOL INDEX 54 + .BYTE $01 ; UTF8 + .BYTE $00,$0B ; STRLEN + .BYTE "toCharArray" +;* CONST POOL INDEX 55 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "()[C" +;* CONST POOL INDEX 56 + .BYTE $01 ; UTF8 + .BYTE $00,$0B ; STRLEN + .BYTE "toLowerCase" +;* CONST POOL INDEX 57 + .BYTE $01 ; UTF8 + .BYTE $00,$08 ; STRLEN + .BYTE "toString" +;* CONST POOL INDEX 58 + .BYTE $01 ; UTF8 + .BYTE $00,$0B ; STRLEN + .BYTE "toUpperCase" +;* CONST POOL INDEX 59 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "trim" +;* CONST POOL INDEX 60 + .BYTE $01 ; UTF8 + .BYTE $00,$07 ; STRLEN + .BYTE "valueOf" +;* CONST POOL INDEX 61 + .BYTE $01 ; UTF8 + .BYTE $00,$15 ; STRLEN + .BYTE "(Z)Ljava/lang/String;" +;* CONST POOL INDEX 62 + .BYTE $01 ; UTF8 + .BYTE $00,$15 ; STRLEN + .BYTE "(C)Ljava/lang/String;" +;* CONST POOL INDEX 63 + .BYTE $01 ; UTF8 + .BYTE $00,$15 ; STRLEN + .BYTE "(F)Ljava/lang/String;" +;* CONST POOL INDEX 64 + .BYTE $01 ; UTF8 + .BYTE $00,$26 ; STRLEN + .BYTE "(Ljava/lang/Object;)Ljava/lang/String;" +;* CONST POOL INDEX 65 + .BYTE $0C ; NAME AND TYPE + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$07 ; DESC #7 +;* CONST POOL INDEX 66 + .BYTE $01 ; UTF8 + .BYTE $00,$06 ; STRLEN + .BYTE "String" +;* CONST POOL INDEX 67 + .BYTE $01 ; UTF8 + .BYTE $00,$10 ; STRLEN + .BYTE "java/lang/Object" +;* CONST POOL INDEX 68 + .BYTE $01 ; UTF8 + .BYTE $00,$10 ; STRLEN + .BYTE "java/lang/String" +;* CONST POOL INDEX 69 + .BYTE $01 ; UTF8 + .BYTE $00,$04 ; STRLEN + .BYTE "6502" +;* +;* ACCESS FLAGS +;* + .BYTE $00,$31 ; 0x0031 +;* +;* THIS CLASS +;* + .BYTE $00,$02 ; #2 +;* +;* SUPER CLASS +;* + .BYTE $00,$03 ; #3 +;* +;* INTERFACES +;* + .BYTE $00,$00 ; IFACE COUNT 0 +;* +;* FIELDS +;* +.IF 0 + .BYTE $00,$01 ; FIELD COUNT 1 +;******* FIELD INDEX 0 ******** + .BYTE $00,$02 ; ACCESS FLAGS 0x0002 + .BYTE $00,$04 ; NAME #4 + .BYTE $00,$05 ; DESC #5 + .BYTE $00,$00 ; ATTRIB COUNT 0 +.ELSE + .BYTE $00,$00 ; FIELDS COUNT 0 +.ENDIF +;* +;* METHODS +;* +; .BYTE $00,$2F ; METHOD COUNT 47 + .BYTE $00,5 ; METHOD COUNT 5 +;******* METHOD INDEX 0 - String() ******** + .BYTE $01,$01 ; ACCESS FLAGS 0x0101 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$07 ; DESC #7 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,69 ; NAME #69 + .BYTE $00,$00,>(M0A0END-M0A0BGN),<(M0A0END-M0A0BGN) +M0A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M0C0END-M0C0BGN),<(M0C0END-M0C0BGN) +M0C0BGN: + PERR "HELLO FROM STRING " + PLA + TAX + PLA + TAY + PLA + PLA + PLA + PLA + TYA + PHA + TXA + PHA + RTS +M0C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M0A0END: +;******* METHOD INDEX 1 - String(byte ascii[], int hibyte) ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$09 ; DESC #9 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M1A0END-M1A0BGN),<(M1A0END-M1A0BGN) +M1A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$03 ; MAX LOCALS 3 + .BYTE $00,$00,>(M1C0END-M1C0BGN),<(M1C0END-M1C0BGN) +M1C0BGN: + .BYTE $2A ; 00000: aload_0 + .BYTE $B7,$00,$01 ; 00001: invokespecial #1 + .BYTE $B1 ; 00004: return +M1C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M1A0END: +;******* METHOD INDEX 2 - String(byte ascii[], int offset, int count) ******** + .BYTE $01,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$0A ; DESC #10 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,69 ; NAME #69 + .BYTE $00,$00,>(M2A0END-M2A0BGN),<(M2A0END-M2A0BGN) +M2A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$05 ; MAX LOCALS 5 + .BYTE $00,$00,>(M2C0END-M2C0BGN),<(M2C0END-M2C0BGN) +M2C0BGN: + LDA $A2 + LDX $A3 + JSR HMEM_LOCK ; LOCK METHOD + PLA ; SAVE RETURN ADDRESS + STA $AE + PLA + STA $AF + PLA ; POP COUNT + STA $A4 + PLA +.IFDEF DEBUG + STA $A5 +.ENDIF + PLA +.IFDEF DEBUG + ORA $A5 +.ENDIF + PLA +.IFDEF DEBUG + ORA $A5 + BEQ :+ + PERR "NEW STRING TOO LONG" + JMP THROW_INTERNALERR +: +.ENDIF + PLA ; POP OFFSET + STA $A5 + PLA + STA $A6 + PLA +.IFDEF DEBUG + STA $A7 +.ENDIF + PLA +.IFDEF DEBUG + ORA $A7 + BEQ :+ + PERR "NEW STRING OFFSET TOO BIG" + JMP THROW_INTERNALERR +: +.ENDIF + PLA ; POP ASCII[] + STA $A7 + PLA + STA $A8 + PLA + PLA + PLA ; POP THIS + PLA + PLA + PLA + LDA $A7 + LDX $A8 + JSR HMEM_LOCK ; GET ARRAY ADDRESS AND LOCK +.IFDEF DEBUG + STA $A9 + STX $AA + LDY #$00 + LDA $A5 + LDX $A6 + CLC + ADC $A4 + BCC :+ + INX +: CMP ($A9),Y + INY + TXA + SBC ($A9),Y + BCC :+ + BEQ :+ + PERR "NEW STRING ARRAY OVERRUN" + JMP THROW_INTERNALERR +: LDA $A9 + LDX $AA +.ENDIF + CLC + ADC #$01 + BCC :+ + INX + CLC +: ADC $A5 ; ADD OFFSET + STA $A9 + TXA + ADC $A6 + STA $AA + LDY #$00 + LDA ($A9),Y ; SAVE CURRENT BYTE + PHA + LDA $A4 ; STICK LEN THERE FOR NOW + STA ($A9),Y + LDA $A9 + LDX $AA + JSR HSTRPL_ADD + STA $AB ; SAVE HANDLE + STX $AC + STY $AD + LDY #$00 + PLA + STA ($A9),Y ; RESTORE CURRENT BYTE + LDA $A7 ; UNLOCK ARRAY + LDX $A8 + JSR HMEM_UNLOCK + TSX +.IFDEF DEBUG + LDA $0103,X + CMP #CL_STR + BEQ :+ + PERR "NEW STRING REF NOT ON STACK" + JMP THROW_INTERNALERR +: +.ENDIF + LDA $0101,X + TAY + LDA $0102,X + TAX + TYA + JSR HMEM_FREE ; FREE NEW REF ON STACK + TSX + LDA $AD ; OVERWRITE NEW STRING REF ON STACK + STA $0104,X + LDA #$80|CL_STR + STA $0103,X + LDA $AC + STA $0102,X + LDA $AB + STA $0101,X + LDA $AF ; RESTORE RETURN ADDRESS + PHA + LDA $AE + PHA + LDA $A2 + LDX $A3 + JMP HMEM_UNLOCK ; UNLOCK METHOD +M2C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M2A0END: +;******* METHOD INDEX 3 - charAt ******** + .BYTE $01,$01 ; ACCESS FLAGS 0x0101 + .BYTE $00,$0F ; NAME #15 + .BYTE $00,$10 ; DESC #16 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,69 ; NAME #69 + .BYTE $00,$00,>(M7A0END-M7A0BGN),<(M7A0END-M7A0BGN) +M7A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M7C0END-M7C0BGN),<(M7C0END-M7C0BGN) +M7C0BGN: + LDA $A2 + LDX $A3 + JSR HMEM_LOCK ; LOCK METHOD + PLA ; SAVE RETURN ADDRESS + STA $A4 + PLA + STA $A5 + PLA + STA $A6 ; INDEX + PLA + PLA + PLA + PLA ; STRING INSTANCE + STA $A8 + PLA + STA $A9 + PLA + PLA + LDA $A8 ; GET POINTER TO STRING + LDX $A9 + JSR HMEM_PTR + STA $A8 + STX $A9 + LDY $A6 + INY + LDA #$00 + PHA + PHA + PHA + LDA ($A8),Y + PHA + LDA $A5 + PHA + LDA $A4 + PHA + LDA $A2 + LDX $A3 + JMP HMEM_UNLOCK ; UNLOCK METHOD +M7C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M7A0END: +;******* METHOD INDEX 4 - length ******** + .BYTE $01,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$2A ; NAME #42 + .BYTE $00,$22 ; DESC #34 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,69 ; NAME #69 + .BYTE $00,$00,>(M27A0END-M27A0BGN),<(M27A0END-M27A0BGN) +M27A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M27C0END-M27C0BGN),<(M27C0END-M27C0BGN) +M27C0BGN: + LDA $A2 + LDX $A3 + JSR HMEM_LOCK ; LOCK METHOD + PLA ; SAVE RETURN ADDRESS + STA $A4 + PLA + STA $A5 + PLA ; STRING INSTANCE + STA $A8 + PLA + STA $A9 + PLA + PLA + LDA $A8 ; GET POINTER TO STRING + LDX $A9 + JSR HMEM_PTR + STA $A8 + STX $A9 + LDA #$00 + TAY + PHA + PHA + PHA + LDA ($A8),Y ; GET LENGTH + PHA + LDA $A5 + PHA + LDA $A4 + PHA + LDA $A2 + LDX $A3 + JMP HMEM_UNLOCK ; UNLOCK METHOD +M27C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M27A0END: +;******* METHOD INDEX 5 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$0B ; DESC #11 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M3A0END-M3A0BGN),<(M3A0END-M3A0BGN) +M3A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M3C0END-M3C0BGN),<(M3C0END-M3C0BGN) +M3C0BGN: + .BYTE $2A ; 00000: aload_0 + .BYTE $B7,$00,$01 ; 00001: invokespecial #1 + .BYTE $B1 ; 00004: return +M3C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M3A0END: +;******* METHOD INDEX 6 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$0C ; DESC #12 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M4A0END-M4A0BGN),<(M4A0END-M4A0BGN) +M4A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$04 ; MAX LOCALS 4 + .BYTE $00,$00,>(M4C0END-M4C0BGN),<(M4C0END-M4C0BGN) +M4C0BGN: + .BYTE $2A ; 00000: aload_0 + .BYTE $B7,$00,$01 ; 00001: invokespecial #1 + .BYTE $B1 ; 00004: return +M4C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M4A0END: +;******* METHOD INDEX 7 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$0D ; DESC #13 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M5A0END-M5A0BGN),<(M5A0END-M5A0BGN) +M5A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M5C0END-M5C0BGN),<(M5C0END-M5C0BGN) +M5C0BGN: + .BYTE $2A ; 00000: aload_0 + .BYTE $B7,$00,$01 ; 00001: invokespecial #1 + .BYTE $B1 ; 00004: return +M5C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M5A0END: +;******* METHOD INDEX 8 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$06 ; NAME #6 + .BYTE $00,$0E ; DESC #14 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M6A0END-M6A0BGN),<(M6A0END-M6A0BGN) +M6A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M6C0END-M6C0BGN),<(M6C0END-M6C0BGN) +M6C0BGN: + .BYTE $2A ; 00000: aload_0 + .BYTE $B7,$00,$01 ; 00001: invokespecial #1 + .BYTE $B1 ; 00004: return +M6C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M6A0END: +;******* METHOD INDEX 9 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$11 ; NAME #17 + .BYTE $00,$12 ; DESC #18 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M8A0END-M8A0BGN),<(M8A0END-M8A0BGN) +M8A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M8C0END-M8C0BGN),<(M8C0END-M8C0BGN) +M8C0BGN: + .BYTE $03 ; 00000: iconst_0 + .BYTE $AC ; 00001: ireturn +M8C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M8A0END: +;******* METHOD INDEX 10 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$13 ; NAME #19 + .BYTE $00,$14 ; DESC #20 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M9A0END-M9A0BGN),<(M9A0END-M9A0BGN) +M9A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M9C0END-M9C0BGN),<(M9C0END-M9C0BGN) +M9C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M9C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M9A0END: +;******* METHOD INDEX 11 ******** + .BYTE $00,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$15 ; NAME #21 + .BYTE $00,$16 ; DESC #22 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M10A0END-M10A0BGN),<(M10A0END-M10A0BGN) +M10A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M10C0END-M10C0BGN),<(M10C0END-M10C0BGN) +M10C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M10C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M10A0END: +;******* METHOD INDEX 12 ******** + .BYTE $00,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$15 ; NAME #21 + .BYTE $00,$17 ; DESC #23 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M11A0END-M11A0BGN),<(M11A0END-M11A0BGN) +M11A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$03 ; MAX LOCALS 3 + .BYTE $00,$00,>(M11C0END-M11C0BGN),<(M11C0END-M11C0BGN) +M11C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M11C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M11A0END: +;******* METHOD INDEX 13 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$18 ; NAME #24 + .BYTE $00,$19 ; DESC #25 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M12A0END-M12A0BGN),<(M12A0END-M12A0BGN) +M12A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M12C0END-M12C0BGN),<(M12C0END-M12C0BGN) +M12C0BGN: + .BYTE $04 ; 00000: iconst_1 + .BYTE $AC ; 00001: ireturn +M12C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M12A0END: +;******* METHOD INDEX 14 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$1A ; NAME #26 + .BYTE $00,$1B ; DESC #27 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M13A0END-M13A0BGN),<(M13A0END-M13A0BGN) +M13A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M13C0END-M13C0BGN),<(M13C0END-M13C0BGN) +M13C0BGN: + .BYTE $04 ; 00000: iconst_1 + .BYTE $AC ; 00001: ireturn +M13C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M13A0END: +;******* METHOD INDEX 15 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$1C ; NAME #28 + .BYTE $00,$19 ; DESC #25 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M14A0END-M14A0BGN),<(M14A0END-M14A0BGN) +M14A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M14C0END-M14C0BGN),<(M14C0END-M14C0BGN) +M14C0BGN: + .BYTE $04 ; 00000: iconst_1 + .BYTE $AC ; 00001: ireturn +M14C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M14A0END: +;******* METHOD INDEX 16 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$1D ; NAME #29 + .BYTE $00,$1E ; DESC #30 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M15A0END-M15A0BGN),<(M15A0END-M15A0BGN) +M15A0BGN: +;* CODE: + .BYTE $00,$00 ; MAX STACK 0 + .BYTE $00,$05 ; MAX LOCALS 5 + .BYTE $00,$00,>(M15C0END-M15C0BGN),<(M15C0END-M15C0BGN) +M15C0BGN: + .BYTE $B1 ; 00000: return +M15C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M15A0END: +;******* METHOD INDEX 17 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$1F ; NAME #31 + .BYTE $00,$20 ; DESC #32 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M16A0END-M16A0BGN),<(M16A0END-M16A0BGN) +M16A0BGN: +;* CODE: + .BYTE $00,$00 ; MAX STACK 0 + .BYTE $00,$05 ; MAX LOCALS 5 + .BYTE $00,$00,>(M16C0END-M16C0BGN),<(M16C0END-M16C0BGN) +M16C0BGN: + .BYTE $B1 ; 00000: return +M16C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M16A0END: +;******* METHOD INDEX 18 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$21 ; NAME #33 + .BYTE $00,$22 ; DESC #34 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M17A0END-M17A0BGN),<(M17A0END-M17A0BGN) +M17A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M17C0END-M17C0BGN),<(M17C0END-M17C0BGN) +M17C0BGN: + .BYTE $03 ; 00000: iconst_0 + .BYTE $AC ; 00001: ireturn +M17C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M17A0END: +;******* METHOD INDEX 19 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$23 ; NAME #35 + .BYTE $00,$24 ; DESC #36 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M18A0END-M18A0BGN),<(M18A0END-M18A0BGN) +M18A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M18C0END-M18C0BGN),<(M18C0END-M18C0BGN) +M18C0BGN: + .BYTE $03 ; 00000: iconst_0 + .BYTE $AC ; 00001: ireturn +M18C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M18A0END: +;******* METHOD INDEX 20 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$23 ; NAME #35 + .BYTE $00,$25 ; DESC #37 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M19A0END-M19A0BGN),<(M19A0END-M19A0BGN) +M19A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$03 ; MAX LOCALS 3 + .BYTE $00,$00,>(M19C0END-M19C0BGN),<(M19C0END-M19C0BGN) +M19C0BGN: + .BYTE $03 ; 00000: iconst_0 + .BYTE $AC ; 00001: ireturn +M19C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M19A0END: +;******* METHOD INDEX 21 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$23 ; NAME #35 + .BYTE $00,$12 ; DESC #18 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M20A0END-M20A0BGN),<(M20A0END-M20A0BGN) +M20A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M20C0END-M20C0BGN),<(M20C0END-M20C0BGN) +M20C0BGN: + .BYTE $03 ; 00000: iconst_0 + .BYTE $AC ; 00001: ireturn +M20C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M20A0END: +;******* METHOD INDEX 22 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$23 ; NAME #35 + .BYTE $00,$26 ; DESC #38 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M21A0END-M21A0BGN),<(M21A0END-M21A0BGN) +M21A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$03 ; MAX LOCALS 3 + .BYTE $00,$00,>(M21C0END-M21C0BGN),<(M21C0END-M21C0BGN) +M21C0BGN: + .BYTE $03 ; 00000: iconst_0 + .BYTE $AC ; 00001: ireturn +M21C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M21A0END: +;******* METHOD INDEX 23 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$27 ; NAME #39 + .BYTE $00,$28 ; DESC #40 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M22A0END-M22A0BGN),<(M22A0END-M22A0BGN) +M22A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M22C0END-M22C0BGN),<(M22C0END-M22C0BGN) +M22C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M22C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M22A0END: +;******* METHOD INDEX 24 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$29 ; NAME #41 + .BYTE $00,$24 ; DESC #36 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M23A0END-M23A0BGN),<(M23A0END-M23A0BGN) +M23A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M23C0END-M23C0BGN),<(M23C0END-M23C0BGN) +M23C0BGN: + .BYTE $03 ; 00000: iconst_0 + .BYTE $AC ; 00001: ireturn +M23C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M23A0END: +;******* METHOD INDEX 25 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$29 ; NAME #41 + .BYTE $00,$25 ; DESC #37 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M24A0END-M24A0BGN),<(M24A0END-M24A0BGN) +M24A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$03 ; MAX LOCALS 3 + .BYTE $00,$00,>(M24C0END-M24C0BGN),<(M24C0END-M24C0BGN) +M24C0BGN: + .BYTE $03 ; 00000: iconst_0 + .BYTE $AC ; 00001: ireturn +M24C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M24A0END: +;******* METHOD INDEX 26 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$29 ; NAME #41 + .BYTE $00,$12 ; DESC #18 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M25A0END-M25A0BGN),<(M25A0END-M25A0BGN) +M25A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M25C0END-M25C0BGN),<(M25C0END-M25C0BGN) +M25C0BGN: + .BYTE $03 ; 00000: iconst_0 + .BYTE $AC ; 00001: ireturn +M25C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M25A0END: +;******* METHOD INDEX 27 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$29 ; NAME #41 + .BYTE $00,$26 ; DESC #38 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M26A0END-M26A0BGN),<(M26A0END-M26A0BGN) +M26A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$03 ; MAX LOCALS 3 + .BYTE $00,$00,>(M26C0END-M26C0BGN),<(M26C0END-M26C0BGN) +M26C0BGN: + .BYTE $03 ; 00000: iconst_0 + .BYTE $AC ; 00001: ireturn +M26C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M26A0END: +;******* METHOD INDEX 28 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$2B ; NAME #43 + .BYTE $00,$2C ; DESC #44 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M28A0END-M28A0BGN),<(M28A0END-M28A0BGN) +M28A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$06 ; MAX LOCALS 6 + .BYTE $00,$00,>(M28C0END-M28C0BGN),<(M28C0END-M28C0BGN) +M28C0BGN: + .BYTE $04 ; 00000: iconst_1 + .BYTE $AC ; 00001: ireturn +M28C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M28A0END: +;******* METHOD INDEX 29 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$2B ; NAME #43 + .BYTE $00,$2D ; DESC #45 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M29A0END-M29A0BGN),<(M29A0END-M29A0BGN) +M29A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$05 ; MAX LOCALS 5 + .BYTE $00,$00,>(M29C0END-M29C0BGN),<(M29C0END-M29C0BGN) +M29C0BGN: + .BYTE $04 ; 00000: iconst_1 + .BYTE $AC ; 00001: ireturn +M29C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M29A0END: +;******* METHOD INDEX 30 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$2E ; NAME #46 + .BYTE $00,$2F ; DESC #47 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M30A0END-M30A0BGN),<(M30A0END-M30A0BGN) +M30A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$03 ; MAX LOCALS 3 + .BYTE $00,$00,>(M30C0END-M30C0BGN),<(M30C0END-M30C0BGN) +M30C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M30C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M30A0END: +;******* METHOD INDEX 31 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$30 ; NAME #48 + .BYTE $00,$19 ; DESC #25 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M31A0END-M31A0BGN),<(M31A0END-M31A0BGN) +M31A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M31C0END-M31C0BGN),<(M31C0END-M31C0BGN) +M31C0BGN: + .BYTE $04 ; 00000: iconst_1 + .BYTE $AC ; 00001: ireturn +M31C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M31A0END: +;******* METHOD INDEX 32 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$31 ; NAME #49 + .BYTE $00,$32 ; DESC #50 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M32A0END-M32A0BGN),<(M32A0END-M32A0BGN) +M32A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$03 ; MAX LOCALS 3 + .BYTE $00,$00,>(M32C0END-M32C0BGN),<(M32C0END-M32C0BGN) +M32C0BGN: + .BYTE $04 ; 00000: iconst_1 + .BYTE $AC ; 00001: ireturn +M32C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M32A0END: +;******* METHOD INDEX 33 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$33 ; NAME #51 + .BYTE $00,$34 ; DESC #52 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M33A0END-M33A0BGN),<(M33A0END-M33A0BGN) +M33A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$02 ; MAX LOCALS 2 + .BYTE $00,$00,>(M33C0END-M33C0BGN),<(M33C0END-M33C0BGN) +M33C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M33C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M33A0END: +;******* METHOD INDEX 34 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$33 ; NAME #51 + .BYTE $00,$35 ; DESC #53 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M34A0END-M34A0BGN),<(M34A0END-M34A0BGN) +M34A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$03 ; MAX LOCALS 3 + .BYTE $00,$00,>(M34C0END-M34C0BGN),<(M34C0END-M34C0BGN) +M34C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M34C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M34A0END: +;******* METHOD INDEX 35 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$36 ; NAME #54 + .BYTE $00,$37 ; DESC #55 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M35A0END-M35A0BGN),<(M35A0END-M35A0BGN) +M35A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M35C0END-M35C0BGN),<(M35C0END-M35C0BGN) +M35C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M35C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M35A0END: +;******* METHOD INDEX 36 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$38 ; NAME #56 + .BYTE $00,$28 ; DESC #40 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M36A0END-M36A0BGN),<(M36A0END-M36A0BGN) +M36A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M36C0END-M36C0BGN),<(M36C0END-M36C0BGN) +M36C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M36C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M36A0END: +;******* METHOD INDEX 37 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$39 ; NAME #57 + .BYTE $00,$28 ; DESC #40 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M37A0END-M37A0BGN),<(M37A0END-M37A0BGN) +M37A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M37C0END-M37C0BGN),<(M37C0END-M37C0BGN) +M37C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M37C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M37A0END: +;******* METHOD INDEX 38 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$3A ; NAME #58 + .BYTE $00,$28 ; DESC #40 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M38A0END-M38A0BGN),<(M38A0END-M38A0BGN) +M38A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M38C0END-M38C0BGN),<(M38C0END-M38C0BGN) +M38C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M38C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M38A0END: +;******* METHOD INDEX 39 ******** + .BYTE $00,$01 ; ACCESS FLAGS 0x0001 + .BYTE $00,$3B ; NAME #59 + .BYTE $00,$28 ; DESC #40 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M39A0END-M39A0BGN),<(M39A0END-M39A0BGN) +M39A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M39C0END-M39C0BGN),<(M39C0END-M39C0BGN) +M39C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M39C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M39A0END: +;******* METHOD INDEX 40 ******** + .BYTE $00,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$3C ; NAME #60 + .BYTE $00,$3D ; DESC #61 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M40A0END-M40A0BGN),<(M40A0END-M40A0BGN) +M40A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M40C0END-M40C0BGN),<(M40C0END-M40C0BGN) +M40C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M40C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M40A0END: +;******* METHOD INDEX 41 ******** + .BYTE $00,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$3C ; NAME #60 + .BYTE $00,$3E ; DESC #62 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M41A0END-M41A0BGN),<(M41A0END-M41A0BGN) +M41A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M41C0END-M41C0BGN),<(M41C0END-M41C0BGN) +M41C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M41C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M41A0END: +;******* METHOD INDEX 42 ******** + .BYTE $00,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$3C ; NAME #60 + .BYTE $00,$16 ; DESC #22 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M42A0END-M42A0BGN),<(M42A0END-M42A0BGN) +M42A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M42C0END-M42C0BGN),<(M42C0END-M42C0BGN) +M42C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M42C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M42A0END: +;******* METHOD INDEX 43 ******** + .BYTE $00,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$3C ; NAME #60 + .BYTE $00,$17 ; DESC #23 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M43A0END-M43A0BGN),<(M43A0END-M43A0BGN) +M43A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$03 ; MAX LOCALS 3 + .BYTE $00,$00,>(M43C0END-M43C0BGN),<(M43C0END-M43C0BGN) +M43C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M43C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M43A0END: +;******* METHOD INDEX 44 ******** + .BYTE $00,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$3C ; NAME #60 + .BYTE $00,$3F ; DESC #63 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M44A0END-M44A0BGN),<(M44A0END-M44A0BGN) +M44A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M44C0END-M44C0BGN),<(M44C0END-M44C0BGN) +M44C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M44C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M44A0END: +;******* METHOD INDEX 45 ******** + .BYTE $00,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$3C ; NAME #60 + .BYTE $00,$34 ; DESC #52 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M45A0END-M45A0BGN),<(M45A0END-M45A0BGN) +M45A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M45C0END-M45C0BGN),<(M45C0END-M45C0BGN) +M45C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M45C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M45A0END: +;******* METHOD INDEX 46 ******** + .BYTE $00,$09 ; ACCESS FLAGS 0x0009 + .BYTE $00,$3C ; NAME #60 + .BYTE $00,$40 ; DESC #64 + .BYTE $00,$01 ; ATTRIB COUNT 1 +;* ATTRIB INDEX 0 + .BYTE $00,$08 ; NAME #8 + .BYTE $00,$00,>(M46A0END-M46A0BGN),<(M46A0END-M46A0BGN) +M46A0BGN: +;* CODE: + .BYTE $00,$01 ; MAX STACK 1 + .BYTE $00,$01 ; MAX LOCALS 1 + .BYTE $00,$00,>(M46C0END-M46C0BGN),<(M46C0END-M46C0BGN) +M46C0BGN: + .BYTE $01 ; 00000: aconst_null + .BYTE $B0 ; 00001: areturn +M46C0END: +;* EXCEPTION TABLE + .BYTE $00,$00 ; COUNT 0 +;* CODE ATTRIB + .BYTE $00,$00 ; ATTRIB COUNT 0 +M46A0END: +;* +;* GLOBAL ATTRIBUTES +;* + .BYTE $00,$00 ; ATTRIB COUNT 0 diff --git a/src/string.s b/src/string.s new file mode 100755 index 0000000..4bd3d2d --- /dev/null +++ b/src/string.s @@ -0,0 +1,30 @@ +;* +;* JAVA SYSTEM CLASSES FOR 6502 +;* + .INCLUDE "global.inc" + .IMPORT HMEM_ALLOC,HMEM_ALLOC_FIXED,HMEM_FREE,HMEM_LOCK,HMEM_UNLOCK + .IMPORT HMEM_PTR,HMEM_REF_INC,HMEM_REF_DEC + .IMPORT HSTR_HASH,STR_HASH,HSTRPL_ADD,HSTRPL_DEL + .IMPORT MEMSRC,MEMDST,MEMCLR,MEMCPY + .IMPORT HCLASS_DUP + .IMPORT LOADCLASS_MEM + .IMPORT THROW_INTERNALERR + .EXPORT STRINGCLASS_INIT + + .SEGMENT "INIT" +STRINGCLASS_INIT: + LDA #STRING_CLASS_DATA + JSR LOADCLASS_MEM +.IFDEF DEBUG + CPY #CL_STR + BEQ :+ + PERR "STRING CLASS NOT 3!" +: +.ENDIF + RTS +;* +;* MIRROR CLASS FILE STRUCTURE FOR SYSTEM CLASSES +;* +STRING_CLASS_DATA: + .INCLUDE "string.clasm" diff --git a/src/strpool.s b/src/strpool.s new file mode 100755 index 0000000..01dfcd3 --- /dev/null +++ b/src/strpool.s @@ -0,0 +1,285 @@ +;* +;* JAVA STRING POOL MANAGER FOR 6502 +;* +;* +;* THE STRING POOL CONTAINS ALL THE STRING CONSTANTS USED BY THE JVM. A HASH TABLE AIDS +;* IN THE LOOKUP OF THE STRING CONSTANTS. A STRING IS DEFINED BY ITS LENGTH AND +;* CONTENTS. THESE MAP INTO A UNIQUE HANDLE. TWO STRINGS ARE EQUAL IF THEIR HANDLES ARE +;* EQUAL. THE STRING POOL DOES NOT CONTAIN STRING OBJECTS. STRING OBJECTS SIMPLY CONTAIN +;* A HANDLE TO THEIR STRING VALUE. +;* +;* THE HASH VALUE OF A STRING IS CALCULATED BY XORING THE NEXT CHARACTER +;* INTO A ROTATED TOTAL. E.I. HASH = CHARACTER ^ ROL(HASH); +;* + .INCLUDE "global.inc" + .IMPORT INIT_START,INIT_END + .IMPORT PRBYTE,CROUT,PUTS,PUTSLN,PRSTR,PRSTRLN,MEMSRC,MEMDST,MEMCLR,MEMCPY + .IMPORT HMEM_ALLOC,HMEM_ALLOC_FIXED,HMEM_FREE + .IMPORT HMEM_LOCK,HMEM_PTR,HMEM_REF_INC,HMEM_REF_DEC + .EXPORT HSTR_INIT,HSTR_HASH,STR_HASH,HSTRPL_ADD,HSTRPL_DEL + + .SEGMENT "INIT" +;* +;* CREATE EXTERNAL LINKEAGE +;* +HSTR_INIT: LDA #HSTRPL_ADD + STA LINK_HSTRADD+1 + LDA #HSTR_HASHL + AUXZP_ACCESS_ON + JSR MEMDST + LDA #$00 + LDX #$02 + JSR MEMCLR + AUXZP_ACCESS_OFF + RTS + + .CODE +;* +;* ADD A STRING CONSTANT TO THE POOL. RETURN A HANDLE TO THE STRING CONSTANT. IF +;* A MATCHING STRING ALREADY EXISTS, RETURN ITS HANDLE AFTER INCREMENTING THE REF COUNT. +;* +HSTR_HASH: JSR HMEM_PTR +STR_HASH: STA STRPTR ; HASH STRING + STX STRPTR+1 + LDY #$00 + LDA (STRPTR),Y + BEQ STR_EXIT + TAY + LDA #$00 +: CMP #$80 ; COPY MSB INTO CARRY + ROL + EOR (STRPTR),Y + DEY + BNE :- +STR_EXIT: RTS +;* +;* ADD A STRING TO THE POOL +;* ENTRY: AX = POINTER TO STRING +;* EXIT: AX = HANDLE TO STRING IN POOL +;* Y = HASH +;* +HSTRPL_ADD: JSR STR_HASH + STA STRHASH ; SAVE HASH FOR LATER + TAY + AUXZP_ACCESS_ON + LDA HSTR_HASHL,Y + LDX HSTR_HASHH,Y + AUXZP_ACCESS_OFF + BEQ STRNEW ; EMPTY LIST, STRING NOT FOUND +STRMATCH_LOOP: STA HSTR + STX HSTR+1 + JSR HMEM_PTR + STA STRMATCHPTR + STX STRMATCHPTR+1 + LDY #$00 ; COMPARE STRING LENGTHS + LDA (STRPTR),Y + CMP (STRMATCHPTR),Y + BNE STRMATCH_NEXT+2 ; NO NEED TO SET Y TO $00 AGAIN + TAY ; COMPARE STRINGS + BEQ STRMATCH ; CASE OF NULL STRING +: LDA (STRPTR),Y + CMP (STRMATCHPTR),Y + BNE STRMATCH_NEXT + DEY + BNE :- +STRMATCH: LDA HSTR ; STRING EXISTS, INC REF CNT + LDX HSTR+1 + JSR HMEM_REF_INC + LDY STRHASH + RTS +STRMATCH_NEXT: LDY #$00 ; NEXT HANDLE AT END OF STRING + LDA (STRMATCHPTR),Y + CLC + ADC STRMATCHPTR + STA STRMATCHPTR + BCC :+ + INC STRMATCHPTR+1 +: LDY #$02 + LDA (STRMATCHPTR),Y ; GET NEXT STRING IN LIST + DEY + TAX + LDA (STRMATCHPTR),Y + CPX #$00 + BNE STRMATCH_LOOP +; BEQ STRNEW ; END OF LIST, STRING NOT FOUND +STRNEW: LDY #$00 ; ALLOC MEM FOR STRING ... + LDA (STRPTR),Y + LDX #$00 + CLC + ADC #$03 ; ... AND HANDLE TO NEXT STRING IN LIST + BCC :+ + INX +: LDY #$01 + JSR HMEM_ALLOC + STA HSTR + STX HSTR+1 + JSR HMEM_PTR + STA STRMATCHPTR + STX STRMATCHPTR+1 + LDY #$00 ; COPY STRING LENGTH OVER + LDA (STRPTR),Y + STA (STRMATCHPTR),Y + TAY ; COPY STRING CHARACTERS + BEQ STRINSRT +: LDA (STRPTR),Y + STA (STRMATCHPTR),Y + DEY + BNE :- +STRINSRT: LDA (STRMATCHPTR),Y ; INSERT NEW HANDLE AT HEAD OF HASH LIST + INY + CLC + ADC STRMATCHPTR + STA STRMATCHPTR + BCC :+ + INC STRMATCHPTR+1 +: LDX STRHASH + AUXZP_ACCESS_ON + LDA HSTR_HASHL,X + AUXZP_ACCESS_OFF + STA (STRMATCHPTR),Y + INY + AUXZP_ACCESS_ON + LDA HSTR_HASHH,X + AUXZP_ACCESS_OFF + STA (STRMATCHPTR),Y + LDY STRHASH + LDA HSTR+1 + AUXZP_ACCESS_ON + STA HSTR_HASHH,Y + AUXZP_ACCESS_OFF + TAX + LDA HSTR + AUXZP_ACCESS_ON + STA HSTR_HASHL,Y + AUXZP_ACCESS_OFF + RTS +;* +;* DECREMENT REFERENCE COUNT OF STRING FROM THE POOL. DELETE IT IF COUNT IS ZERO. +;* ENTRY: AX = HANDLE TO STRING +;* +HSTRPL_DEL: STA HSTR + STX HSTR+1 + JSR HMEM_LOCK + JSR STR_HASH + STA STRHASH + LDY #$00 + LDA (STRPTR),Y + INY + CLC + ADC STRPTR + STA STRPTR + BCC :+ + INC STRPTR+1 +: LDA (STRPTR),Y + INY + STA HSTRNEXT + LDA (STRPTR),Y + STA HSTRNEXT+1 + LDY STRHASH + AUXZP_ACCESS_ON + LDA HSTR_HASHL,Y + LDX HSTR_HASHH,Y + AUXZP_ACCESS_OFF + BEQ STRBAD ; EMPTY LIST, STRING NOT FOUND + CMP HSTR + BNE HSTRFIND_NEXT + CPX HSTR+1 + BNE HSTRFIND_NEXT + LDA HSTRNEXT + LDX HSTRNEXT+1 +; LDY STRHASH ; UNLINK FROM HEAD OF LIST + AUXZP_ACCESS_ON + STA HSTR_HASHL,Y + TXA + STA HSTR_HASHH,Y + AUXZP_ACCESS_OFF + LDA HSTR + LDX HSTR+1 + JMP HMEM_FREE +HSTRFIND_LOOP: CMP HSTR + BNE HSTRFIND_NEXT + CPX HSTR+1 + BNE HSTRFIND_NEXT + LDY #$01 ; UNLINK STRING FROM LIST + LDA HSTRNEXT + STA (STRMATCHPTR),Y + INY + LDA HSTRNEXT+1 + STA (STRMATCHPTR),Y +HSTRFREE: LDA HSTR ; FREE STRING MEMORY + LDX HSTR+1 + JMP HMEM_FREE +HSTRFIND_NEXT: JSR HMEM_PTR + STA STRMATCHPTR + STX STRMATCHPTR+1 + LDY #$00 ; NEXT HANDLE AT END OF STRING + LDA (STRMATCHPTR),Y + CLC + ADC STRMATCHPTR + STA STRMATCHPTR + BCC :+ + INC STRMATCHPTR+1 +: LDY #$02 + LDA (STRMATCHPTR),Y ; GET NEXT STRING IN LIST + DEY + TAX + LDA (STRMATCHPTR),Y + BNE HSTRFIND_LOOP +STRBAD: +.IFDEF DEBUG + PERR "BAD STRING HANDLE" + JMP HSTRFREE +.ELSE + BEQ HSTRFREE ; END OF LIST, STRING NOT FOUND, FREE IT ANYWAY +.ENDIF +.IFDEF DEBUG_STRPOOL +;* +;* PRINT OUT STRING POOL DETAILS +;* + .EXPORT HSTRPL_DUMP +HSTRPL_DUMP: JSR CROUT + PSTRLN "STRING POOL STATE" + PSTRLN "=================" + LDY #$00 + STY STRHASH +HSTR_HSHDUMP: LDY STRHASH + AUXZP_ACCESS_ON + LDA HSTR_HASHL,Y + LDX HSTR_HASHH,Y + AUXZP_ACCESS_OFF + CPX #$00 + BEQ HSTR_HSHNEXT + STA HSTR + STX HSTR+1 + PSTR "HASH LIST: $" + LDA STRHASH + JSR PRBYTE + JSR CROUT + LDA HSTR + LDX HSTR+1 +HSTR_LSTDUMP: JSR HMEM_PTR + STA STRPTR + STX STRPTR+1 + JSR PRSTRLN + LDY #$00 ; NEXT HANDLE AT END OF STRING + LDA (STRPTR),Y + INY + CLC + ADC STRPTR + STA STRPTR + BCC :+ + INC STRPTR+1 +: LDA (STRPTR),Y ; GET NEXT STRING IN LIST + INY + PHA + LDA (STRPTR),Y + TAX + PLA + BNE HSTR_LSTDUMP +HSTR_HSHNEXT: INC STRHASH + BNE HSTR_HSHDUMP + RTS +.ENDIF \ No newline at end of file diff --git a/src/sysclass.s b/src/sysclass.s new file mode 100755 index 0000000..6beed00 --- /dev/null +++ b/src/sysclass.s @@ -0,0 +1,465 @@ +;* +;* JAVA SYSTEM CLASSES FOR 6502 +;* + .INCLUDE "global.inc" + .INCLUDE "class.inc" + .IMPORT CROUT,COUT,PRSTR,KBWAIT,PRHSTR,PRHSTRLN,PRBYTE + .IMPORT HMEM_ALLOC,HMEM_ALLOC_FIXED,HMEM_FREE,HMEM_LOCK,HMEM_UNLOCK + .IMPORT HMEM_PTR,HMEM_REF_INC,HMEM_REF_DEC + .IMPORT HSTR_HASH,STR_HASH,HSTRPL_ADD,HSTRPL_DEL + .IMPORT HCLASS_NAME,HCLASS_HNDL,HCLASS_ADD,HCLASS_INDEX,CLASS_STRING + .IMPORT CLASS_METHODPTR,CLASS_VIRTCODE,CLASS_LOCKMETHOD,CLASS_UNLOCKMETHOD + .IMPORT MEMSRC,MEMDST,MEMCLR,MEMCPY + .IMPORT CLASS_MATCH_NAME,CLASS_MATCH_DESC,RESOLVE_METHOD,CLASS_METHODPTR + .IMPORT THREAD_WAIT_HOBJL,THREAD_WAIT_HOBJH,THREAD_WAITQ + .IMPORT ASYNC_VIRTUAL + .IMPORT STRINGCLASS_INIT + .IMPORT LOADCLASS_MEM + .IMPORT HFINALNAMESTR,HVOIDDESCSTR + .EXPORT SYSCLASS_INIT,INIT_END + .EXPORT UNREF_OBJECT,SYS_CALL + + .SEGMENT "INIT" +SYSCLASS_INIT: LDA #NATIVE_CALL + STA LINK_VMCALL+1 + LDA #OBJECT_CLASS_DATA + JSR LOADCLASS_MEM +.IFDEF DEBUG + CPY #CL_OBJ + BEQ :+ + PERR "OBJECT CLASS NOT 1!" +: +.ENDIF + LDA #ARRAY_CLASS_DATA + JSR LOADCLASS_MEM +.IFDEF DEBUG + CPY #CL_ARRAY + BEQ :+ + PERR "ARRAY CLASS NOT 2!" +: +.ENDIF + JMP STRINGCLASS_INIT +;* +;* MIRROR CLASS FILE STRUCTURE FOR SYSTEM CLASSES +;* +OBJECT_CLASS_DATA: + .INCLUDE "object.clasm" +ARRAY_CLASS_DATA: + .INCLUDE "array.clasm" +INIT_END := * + + .CODE +;* +;* SYSCLASS OBJECT HELPER ROUTINES +;* +;* +;* UNREFERENCE AN OBJECT INSTANCE +;* ENTRY: STACK = INSTANCE REF +;* +UNREF_OBJECT: TSX + LDA $0103,X + TAY + LDA $0104,X + BEQ OBJUNREFDONE ; SKIP NULL REF + TAX + TYA + JSR HMEM_REF_DEC + CMP #$00 ; IF REF COUNT NOT ZERO, DONE + BNE OBJUNREFDONE + CPX #$00 + BEQ OBJDEL +OBJUNREFDONE: TSX ; REMOVE OBJECT REF FROM STACK + LDA $0101,X + STA $0105,X + LDA $0102,X + STA $0106,X + INX + INX + INX + INX + TXS + RTS +OBJDEL: TSX + LDA $0105,X + CMP #CL_STR+1 ; IS IT A BASIC SYSCLASS? + BCC :+ + JMP FINALIZE ; NO, FINALIZE +: CMP #CL_STR ; IS IT A STRING? + BNE CHKARRAY ; NO, CHECK FOR ARRAY +.IFDEF DEBUG_FINALIZE + PSTRLN "DELETING STRING" + TSX +.ENDIF + LDA $0103,X + TAY + LDA $0104,X + TAX + TYA + JSR HSTRPL_DEL ; DEL STRPL CONST + JMP OBJUNREFDONE +CHKARRAY: CMP #CL_ARRAY + BNE OBJFREE +.IFDEF DEBUG_FINALIZE + PSTR "DELETING ARRAY TYPE:" + TSX + LDA $0106,X + JSR PRBYTE + JSR CROUT + TSX +.ENDIF + LDA $0106,X + CMP #T_REF|$10 ; CHECK ARRAY TYPE + BNE :+ + JMP UNREFARRAYREFS ; UNREF ARRAY OF REFS +: BCC OBJFREE ; IF BASIC ARRAY, JUST DELETE + SBC #$10 ; DECREMENT ARRAY DIMENSION + STA $0106,X + JMP UNREFARRAYARRAY +OBJFREE: TSX + LDA $0103,X + TAY + LDA $0104,X + TAX + TYA + JSR HMEM_FREE ; DELETE INSTANCE + JMP OBJUNREFDONE +FINALIZE: TSX + LDA $0103,X + TAY + LDA $0104,X + TAX + TYA + JSR HMEM_REF_INC ; NEEDED FOR FINALIZE() +.IFDEF DEBUG_FINALIZE + PSTR "FINALIZING OBJECT OF CLASS: " + TSX + LDY $0106,X + JSR CLASS_STRING + JSR PRHSTR + JSR CROUT +; JSR KBWAIT +.ENDIF + LDA HFINALNAMESTR ; LOOK FOR FINALIZE() + LDX HFINALNAMESTR+1 + JSR CLASS_MATCH_NAME + LDA HVOIDDESCSTR + LDX HVOIDDESCSTR+1 + JSR CLASS_MATCH_DESC + TSX + LDA $0106,X ; PUSH *THIS* + PHA + LDA $0105,X + PHA + TAY ; SAVE CLASS + LDA $0104,X + PHA + LDA $0103,X + PHA + JSR RESOLVE_METHOD ; CALL FINALIZE() + JSR ASYNC_VIRTUAL + BCC :+ ; NO EXCEPTION ENCOUNTERED + JSR OBJFREE ; FREE EXCEPTION OBJECT +; +; GET CLASS AND ITERATE THROUGH METHODS LOOKING FOR REFERENCE FIELDS TO UNREF +; +: TSX ; INIT STACK LOCALS + LDA $0105,X + PHA + LDA $0103,X + TAY + LDA $0104,X + TAX + TYA + JSR HMEM_LOCK ; LOCK OBJ INSTANCE + PHA + TXA + PHA +UNREFCLASS: LDA #$00 + PHA +; +; STACK HAS: +; CURRENT CLASS INDEX = $0104,X +; POINTER TO INSTANCE = $0102,X (HI) $0103,X (LO) +; CURRENT FIELD INDEX = $0101,X +; +UNREFFLDS: TSX + LDY $0104,X ; RETRIEVE ICLASS + JSR HCLASS_INDEX ; GET HCLASS + JSR HMEM_PTR ; GET CLASS PTR + STA CCLASSPTR + STX CCLASSPTR+1 + LDY #CLASSFIELDTBL+1 + LDA (CCLASSPTR),Y + BNE :+ + JMP UNREFSUPRCLS ; NO FIELDS FOR THIS CLASS, CHECK SUPER +: DEY + TAX + LDA (CCLASSPTR),Y + JSR HMEM_PTR + STA CCTBLPTR + STX CCTBLPTR+1 + LDY #CLASSFIELDCNT + PLA ; CHECK FOR MAX FIELD INDEX + CMP (CCLASSPTR),Y + PHA + BEQ UNREFSUPRCLS ; UNREF SUBCLASS FIELDS + LDX #$00 ; GET POINTER TO FIELD DEF + JSR MUL_FIELDRECSZ ; FIELD RECORD SIZE + CLC + ADC CCTBLPTR + STA TMPTR + TXA + ADC CCTBLPTR+1 + STA TMPTR+1 + LDY #FIELDACCESS + LDA (TMPTR),Y + AND #$08 ; CHECK FOR STATIC FIELD + BNE UNREFNXTFLD + LDY #FIELDTYPE + LDA (TMPTR),Y + CMP #T_REF|$80 ; CHECK FOR REFERENCE TYPE + BNE UNREFNXTFLD + TSX + INY ; LDY #FIELDINSTOFFSET GET FIELD INSTANCE OFFSET + LDA (TMPTR),Y + INY + CLC + ADC $0103,X + STA FINPTR + LDA (TMPTR),Y + ADC $0102,X + STA FINPTR+1 +.IFDEF DEBUG_FINALIZE + LDY #FIELDNAME + LDA (TMPTR),Y + INY + PHA + LDA (TMPTR),Y + PHA + PSTR "UNREF FIELD: " + PLA + TAX + PLA + JSR PRHSTR + JSR CROUT + JSR KBWAIT +.ENDIF + LDY #$03 + LDA (FINPTR),Y ; UNREF OBJECT FIELD + DEY + PHA + LDA (FINPTR),Y + DEY + PHA + LDA (FINPTR),Y + DEY + PHA + LDA (FINPTR),Y + PHA + JSR UNREF_OBJECT +UNREFNXTFLD: PLA ; INC FIELD INDEX + CLC + ADC #$01 + PHA +; BEQ UNREFSUPRCLS + JMP UNREFFLDS +; +; UNREF SUPER CLASS FIELDS +; +UNREFSUPRCLS: PLA ; POP FIELD COUNT + TSX + LDY $0103,X ; RETRIEVE ICLASS + JSR HCLASS_INDEX ; GET HCLASS + JSR HMEM_PTR + STA CCLASSPTR + STX CCLASSPTR+1 + LDY #CLASSSUPER ; GET SUPERCLASS + LDA (CCLASSPTR),Y + BEQ UNREFFLDDONE + TSX + STA $0103,X + JMP UNREFCLASS +UNREFFLDDONE: PLA ; POP STACK LOCALS + PLA + PLA +.IFDEF DEBUG + TSX + LDA $0103,X + TAY + LDA $0104,X + TAX + TYA + JSR HMEM_REF_DEC ; NEEDED FOR FINALIZE() +.ENDIF + JMP OBJFREE +UNREFARRAYREFS: +.IFDEF DEBUG_FINALIZE + PSTRLN "UNREFING ARRAY REFERENCES" + TSX +.ENDIF + LDA $0103,X ; RETRIEVE ARRAY POINTER + TAY + LDA $0104,X + TAX + TYA + JSR HMEM_PTR + STA TMPTR + STX TMPTR+1 + LDY #$01 + LDA (TMPTR),Y + DEY + STA FINPTR+1 + TAX + LDA (TMPTR),Y + STA FINPTR + BNE :+ + CPX #$00 + BEQ ARRAYDONE ; ALL ARRAY ELEMENTS UNREFERENCED +: SEC ; DEC INDEX + SBC #$01 + BCS :+ + DEX +: STA (TMPTR),Y ; UPDATE INDEX OF NEXT ELEMENT + INY + TXA + STA (TMPTR),Y + LDA FINPTR + ASL + ROL FINPTR+1 + ASL + ROL FINPTR+1 + SEC ; ADJUST FOR LENGTH VALUE = 2 BYTES + SBC #$02 + BCS :+ + DEC FINPTR+1 +: CLC + ADC TMPTR + STA FINPTR + LDA FINPTR+1 + ADC TMPTR+1 + STA FINPTR+1 + LDY #$03 + LDA (FINPTR),Y ; UNREF ARRAY ELEMENT + DEY + PHA + LDA (FINPTR),Y + DEY + PHA + LDA (FINPTR),Y + DEY + PHA + LDA (FINPTR),Y + PHA + JSR UNREF_OBJECT + TSX + JMP UNREFARRAYREFS +ARRAYDONE: JMP OBJFREE +UNREFARRAYARRAY: +.IFDEF DEBUG_FINALIZE + PSTRLN "UNREFING ARRAY ARRAYS" + TSX +.ENDIF + LDA $0103,X ; RETRIEVE ARRAY POINTER + TAY + LDA $0104,X + TAX + TYA + JSR HMEM_PTR + STA TMPTR + STX TMPTR+1 + LDY #$01 + LDA (TMPTR),Y + DEY + STA FINPTR+1 + TAX + LDA (TMPTR),Y + STA FINPTR + BNE :+ + CPX #$00 + BEQ ARRAYDONE ; ALL ARRAY ARRAYS UNREFERENCED +: SEC ; DEC INDEX + SBC #$01 + BCS :+ + DEX +: STA (TMPTR),Y ; UPDATE INDEX OF NEXT ARRAY + INY + TXA + STA (TMPTR),Y + LDA FINPTR + ASL + ROL FINPTR+1 + CLC + ADC TMPTR + STA FINPTR + LDA FINPTR+1 + ADC TMPTR+1 + STA FINPTR+1 + TSX + LDA $0106,X ; RETRIEVE ARRAY TYPE + PHA + LDA #CL_ARRAY + PHA + LDY #$01 + LDA (FINPTR),Y ; UNREF ARRAY ELEMENT + DEY + PHA + LDA (FINPTR),Y + PHA + JSR UNREF_OBJECT + TSX + JMP UNREFARRAYARRAY +;* +;* NATIVE CALL INTO VM OR ROM CODE FROM VM02.CALL() +;* +NATIVE_CALL: PLA ; PULL RETURN ADDRESS + STA $A4 + PLA + STA $A5 + PLA ; PULL CALL ADDRESS + STA $A6 + PLA + STA $A7 + TSX + LDA $A4 ; PUSH RETURN ADDRESS (OVERWRITE HIWORD OF CALL ADDRESS) + STA $0101,X + LDA $A5 + STA $0102,X + LDA $0103,X ; GET REG VALS + STA $A8 ; BUT LEAVE ON STACK FOR RETUN VALS + LDA $0104,X + STA $A9 + LDA $0105,X + STA $AA + LDA $A7 + BEQ :+ + JSR ROMCALL + JMP CALLRET +: LDX $A6 ; PATCH INDIRECT JUMP +SYS_CALL: STX VMCALL+7 + JSR VMCALL +CALLRET: PHP + STA $A8 + STX $A9 + PLA + TSX + STA $0106,X ; PUT RETURN REG VALS BACK ON STACK + TYA + STA $0105,X + LDA $A9 + STA $0104,X + LDA $A8 + STA $0103,X + RTS +VMCALL: LDA $A8 + LDX $A9 + LDY $AA + JMP ($0300) +ROMCALL: BIT $C081 ; SELECT ROM + LDA $A8 + LDX $A9 + LDY $AA + JMP ($A6) diff --git a/src/thread.s b/src/thread.s new file mode 100755 index 0000000..658ee2c --- /dev/null +++ b/src/thread.s @@ -0,0 +1,975 @@ +;* +;* JAVA THREAD SUPPORT FOR 6502 +;* +;* +;* THREADS CONSIST OF ALL THE STATE REQUIRED FOR EXECUTING A STREAM +;* OF JAVA BYTECODES IN A STOPPABLE AND RESTARTABLE FASION. THE +;* THREAD TABLE IS ORGANIZED AS: +;* STATE +;* PRIORITY +;* HMETHOD +;* PC_OFS +;* HFRAME +;* BASE_OFS +;* STACK_OFS +;* TOP_OF_STACK +;* THE THREAD TABLE IS INTERLEAVED SO ALL THE DATA CAN BE ADDRESSED BY PUTTING THE THREAD +;* ID INTO AN INDEX REGISTER AN INDEXING INTO THE FIELDS. +;* + + .INCLUDE "global.inc" + .INCLUDE "class.inc" + .IMPORT HMEM_ALLOC,HMEM_PTR,HMEM_FREE,HMEM_LOCK,HMEM_UNLOCK +.IFDEF IDLE_GC + .IMPORT HMEM_GC_IDLE +.ENDIF +.IFDEF SWAPPING + .IMPORT HMEM_CLRACCESS +.ENDIF + .IMPORT HSTRPL_ADD + .IMPORT COUT,MEMDST,MEMCLR + .IMPORT HCLASS_NAME,HCLASS_HNDL,CLASS_MATCH_NAME,CLASS_MATCH_DESC,CLASS_STRING + .IMPORT RESOLVE_CLASS,RESOLVE_METHOD,CLASS_METHODPTR,INVOKE_STATIC,INVOKE_VIRTUAL + .IMPORT UNREF_OBJECT + .IMPORT LOADCLASS_MEM,HRUNNAMESTR,HVOIDDESCSTR + .IMPORT THROW_SYSEXCEPTN,THROW_INTERNALERR,UNHANDLED_EXCEPTN + .IMPORT EXECBYTECODES,SYSTHROW,CURRENTEXCEPTN + .IMPORT VM_RESTART + .EXPORT CURRENT_THREAD,THREAD_INIT,THREAD_NEW,THREAD_START,THREAD_SETRUN + .EXPORT ITHREAD_PUSH_SP,THREAD_PUSH_TLS,ITHREAD_PUSH_TLS,THREAD_POP_TLS,ITHREAD_POP_TLS + .EXPORT THREAD_YIELD,THREAD_LOCK,THREAD_UNLOCK,SYSTEM_TIC,BEST_THREAD,LOADEXECSTATE + .EXPORT THREAD_WAIT_HOBJL,THREAD_WAIT_HOBJH,THREAD_WAITQ + .EXPORT THREAD_NOTIMEOUT,THREAD_NOTIFYIO,THREAD_WAITIO,THREAD_SELECTIO + .EXPORT THREAD_SELECTIO,IO_NOTIFY, SLOT2MASK + +MAX_SYNC_QUEUES EQU MAX_THREADS*4 +DEFAULT_PRIORITY EQU 5 + + .SEGMENT "INIT" + +THREAD_INIT: LDA #THREAD_LOCK + STA LINK_LOCKENTER+1 + LDA #THREAD_UNLOCK + STA LINK_LOCKEXIT+1 + LDA #THREAD_NEW + STA LINK_THREADNEW+1 + LDA #ITHREAD_PUSH_SP + STA LINK_THREADPUSH+1 + LDA #THREAD_START + STA LINK_THREADSTART+1 + LDA #THREAD_EXIT + STA LINK_THREADEXIT+1 + LDA #THREAD_KILL + STA LINK_THREADKILL+1 + LDA #THREAD_SETSTATE + STA LINK_THREADSETSTATE+1 + LDA #THREAD_GETSTATE + STA LINK_THREADGETSTATE+1 + LDA #THREAD_SETPRIORITY + STA LINK_THREADSETPRIORITY+1 + LDA #THREAD_GETPRIORITY + STA LINK_THREADGETPRIORITY+1 + LDA #THREAD_SETTIMEOUTL + STA LINK_THREADSETTIMEOUTL+1 + LDA #THREAD_SETTIMEOUTH + STA LINK_THREADSETTIMEOUTH+1 + LDA #THREAD_NOTIMEOUT + STA LINK_THREADNOTIMEOUT+1 + LDA #THREAD_SETREF + STA LINK_THREADSETREF+1 + LDA #THREAD_SETCLASS + STA LINK_THREADSETCLASS+1 + LDA #THREAD_GETCLASS + STA LINK_THREADGETCLASS+1 + LDA #THREAD_GETREF + STA LINK_THREADGETREF+1 + LDA #THREAD_GETCURRENT + STA LINK_THREADGETCURRENT+1 + LDA #SYSTEM_TIC + STA LINK_SYSTEMTIC+1 + LDA #SYSTEM_GETTICL + STA LINK_GETTICL+1 + LDA #SYSTEM_GETTICH + STA LINK_GETTICH+1 + LDX #MAX_THREADS-1 +: LDA #S_FREE ; FREE ALL THREADS + STA THREAD_STATE,X + LDA #$00 + STA THREAD_HEXECL,X + STA THREAD_HEXECH,X + DEX + BPL :- + LDX #MAX_SYNC_QUEUES-1 ; NO LOCKED OBJECTS + LDA #$00 +: STA SYNCQ_HOBJL,X + STA SYNCQ_HOBJH,X + DEX + BPL :- + LDY #ZP_THREAD_SIZE-1 + LDA #$00 +: STA ZP_THREAD_STATE,Y ; ZERO THREAD STATE + DEY + BPL :- + STA IO_NOTIFY ; CLEAR PENDING NOTIFICATIONS + LDA CLRKBD + LDA #$00 + STA OPCNT + RTS + + .CODE +;* +;* PUSH WORD ON THREAD'S 6502 STACK +;* ENTRY: AX = WORD TO PUSH +;* Y = THREAD ID +;* EXIT: Y = THREAD ID +;* +ITHREAD_PUSH_SP: + STA TMP ; PUSH X FIRST + TXA + PHA + LDA TMP + PHA ; THEN PUSH A + TYA ; SAVE ITHREAD + PHA + LDA THREAD_HEXECL,Y + LDX THREAD_HEXECH,Y + JSR HMEM_PTR + STA TMPTR + STX TMPTR+1 + PLA ; RETRIEVE ITHREAD INTO X + TAX + LDY THREAD_SP,X + PLA ; PULL A, PUSH THREAD STACK + STA (TMPTR),Y + DEY + PLA ; PULL X, PUSH THREAD STACK + STA (TMPTR),Y + DEY + TYA + STA THREAD_SP,X + TXA + TAY + RTS +;* +;* PUSH WORD ON THREAD LOCAL STORAGE HEAP +;* ENTRY: AX = WORD TO PUSH +;* +THREAD_PUSH_TLS: LDY CURRENT_THREAD +;* +;* PUSH WORD ON THREAD LOCAL STORAGE HEAP +;* ENTRY: AX = WORD TO PUSH +;* Y = THREAD ID +;* EXIT: Y = THREAD ID +;* +ITHREAD_PUSH_TLS: PHA + TXA + PHA + LDA THREAD_TOS,Y ; INC TLS POINTER + CLC + ADC #$02 + STA THREAD_TOS,Y + TYA + ASL ; MULTIPLY BY 16 + ASL + ASL + ASL + CLC + ADC THREAD_TOS,Y + TAY + PLA + TAX + PLA + AUXZP_ACCESS_ON + STA TLS-2,Y + TXA + STA TLS-1,Y + AUXZP_ACCESS_OFF + RTS +;* +;* POP WORD FROM THREAD LOCAL STORAGE HEAP +;* EXIT: AX = WORD POPPED +;* +THREAD_POP_TLS: LDY CURRENT_THREAD +;* +;* POP WORD FROM THREAD LOCAL STORAGE HEAP +;* ENTRY: Y = THREAD_ID +;* EXIT: AX = WORD POPPED +;* Y = THREAD ID +;* +ITHREAD_POP_TLS: LDA THREAD_TOS,Y + SEC ; DEC TLS POINTER + SBC #$02 + STA THREAD_TOS,Y + TYA + ASL ; MULTIPLY BY 16 + ASL + ASL + ASL + CLC + ADC THREAD_TOS,Y + TAY + AUXZP_ACCESS_ON + LDA TLS+1,Y + TAX + LDA TLS,Y + AUXZP_ACCESS_OFF + RTS +;* +;* SETUP NEW THREAD +;* ENTRY: AX = THREAD OBJECT INSTANCE +;* EXIT: Y = THREAD ID +;* C = 0 :: SUCCESS +;* C = 1 :: FAILURE +;* +THREAD_NEW: PHA + TXA + PHA +.IFDEF DEBUG_THREAD + PERR "THREAD_NEW" + .IMPORT KBWAIT + JSR KBWAIT +.ENDIF + LDY #MAX_THREADS-1 +FINDFREE: LDA THREAD_STATE,Y + CMP #S_FREE + BNE FNDNXTFREE + PLA + STA THREAD_HOBJH,Y + PLA + STA THREAD_HOBJL,Y + LDA #$00 + STA THREAD_TOS,Y + LDA #$FF + STA THREAD_SP,Y + LDA #DEFAULT_PRIORITY + STA THREAD_PRIORITY,Y + STY BEST_THREAD + LDA #ZP_THREAD_SIZE ; ALLOC MEMORY FOR EXEC STATE (STACK+ZP) + LDX #$01 + LDY #$00 + JSR HMEM_ALLOC + LDY BEST_THREAD + STA THREAD_HEXECL,Y + TXA + STA THREAD_HEXECH,Y + LDA #S_IDLE + STA THREAD_STATE,Y + LDA THREAD_HEXECL,Y + JSR HMEM_PTR + JSR MEMDST + LDA #ZP_THREAD_SIZE ; CLEAR MEMORY FOR EXEC STATE (STACK+ZP) + LDX #$01 + JSR MEMCLR + LDY BEST_THREAD + CLC + RTS +FNDNXTFREE: DEY + BPL FINDFREE + SEC + PLA + PLA + RTS +;* +;* SET THREAD RUNNABLE +;* ENTRY: A = CLASS INDEX +;* Y = THREAD ID +;* THREADSTACK = PARAM +;* +THREAD_START: STA $A0 + STY $A1 +.IFDEF DEBUG_THREAD + PERR "THREAD_START" + .IMPORT KBWAIT + JSR KBWAIT + LDY $A1 +.ENDIF + LDA HRUNNAMESTR ; RUN METHOD + LDX HRUNNAMESTR+1 + JSR ITHREAD_PUSH_SP + LDA HVOIDDESCSTR + LDX HVOIDDESCSTR+1 + JSR ITHREAD_PUSH_SP + LDY $A0 ; RETRIEVE CLASS NAME + JSR CLASS_STRING + LDY $A1 + JSR ITHREAD_PUSH_SP +THREAD_SETRUN: LDA #>(THREAD_RUN-1) + LDX #<(THREAD_RUN-1) + JSR ITHREAD_PUSH_SP + LDA #S_RUNNABLE + STA THREAD_STATE,Y + RTS +;* +;* SET THREAD STATE +;* +THREAD_SETSTATE: STA THREAD_STATE,Y + JMP (LINK_YIELD) ; RUN SCHEDULER WHEN THREAD STATE CHANGES +;* +;* GET THREAD STATE +;* +THREAD_GETSTATE: LDA THREAD_STATE,Y + RTS +;* +;* SET THREAD REF +;* +THREAD_SETREF: STA THREAD_HOBJL,Y + TXA + STA THREAD_HOBJH,Y + RTS +;* +;* SET THREAD CLASS +;* +THREAD_SETCLASS: STA THREAD_HOBJCLL,Y + TXA + STA THREAD_HOBJCLH,Y + RTS +;* +;* GET THREAD REF +;* +THREAD_GETREF: LDA THREAD_HOBJL,Y + LDX THREAD_HOBJH,Y + RTS +;* +;* GET THREAD CLASS +;* +THREAD_GETCLASS: LDA THREAD_HOBJCLL,Y + LDX THREAD_HOBJCLH,Y + RTS +;* +;* SET THREAD PRIORITY +;* +THREAD_SETPRIORITY: STA THREAD_PRIORITY,Y + JMP (LINK_YIELD) ; RUN SCHEDULER IF THREAD PRIORITY CHANGES +;* +;* GET THREAD PRIORITY +;* +THREAD_GETPRIORITY: LDA THREAD_PRIORITY,Y + RTS +;* +;* SET THREAD TIMEOUT +;* ENTRY: AX = LOW/HIGH 32 BITS OF TIMEOUT +;* Y = THREAD ID +;* +THREAD_SETTIMEOUTL: + SEI + CLC + ADC TIC_COUNT + STA THREAD_TIMEOUT0,Y + TXA + ADC TIC_COUNT+1 + STA THREAD_TIMEOUT1,Y + LDA #$00 + ADC TIC_COUNT+2 + STA THREAD_TIMEOUT2,Y + LDA #$00 + ADC TIC_COUNT+3 + STA THREAD_TIMEOUT3,Y + RTS +THREAD_SETTIMEOUTH: + CLC + ADC THREAD_TIMEOUT2,Y + STA THREAD_TIMEOUT2,Y + TXA + ADC THREAD_TIMEOUT3,Y + STA THREAD_TIMEOUT3,Y + RTS +;* +;* SET THREAD NO TIMEOUT +;* +THREAD_NOTIMEOUT: LDA #$FF + STA THREAD_TIMEOUT0,Y + STA THREAD_TIMEOUT1,Y + STA THREAD_TIMEOUT2,Y + STA THREAD_TIMEOUT3,Y + RTS +;* +;* GET CURRENT THREAD +;* +THREAD_GETCURRENT: LDY CURRENT_THREAD +.IFDEF DEBUG + CPY #MAX_THREADS + BCC :+ + PERR "INVALID CURRENT_THREAD" + JMP THROW_INTERNALERR +: +.ENDIF + LDA THREAD_HOBJL,Y + LDX THREAD_HOBJH,Y + RTS +;* +;* THREAD STARTUP ROUTINE +;* +THREAD_RUN: +.IFDEF DEBUG_THREAD + PERR "THREAD_RUN" + .IMPORT KBWAIT + JSR KBWAIT +.ENDIF + PLA ; RESOLVE CLASS + TAX + PLA + JSR RESOLVE_CLASS + BCS THREAD_ERR + TYA + JSR THREAD_PUSH_TLS ; SAVE CLASS INDEX + PLA + TAX + PLA + JSR CLASS_MATCH_DESC + PLA + TAX + PLA + JSR CLASS_MATCH_NAME + JSR THREAD_POP_TLS ; RETRIEVE CLASS INDEX + TAY + JSR RESOLVE_METHOD ; RESOLVE METHOD + BCS THREAD_NOMETHD + STA $A0 + STX $A1 + STY $A2 + LDA #>(THREAD_EXIT-1) ; SET RETURN ADDRESS TO THREAD_EXIT + LDX #<(THREAD_EXIT-1) + JSR THREAD_PUSH_TLS + LDA #$00 + TAX +; STA HEXECFRAME ; ZERO OUT CURRENT FRAME +; STX HEXECFRAME+1 ; SHOULD BE ZEROD FROM THREAD STATE + JSR THREAD_PUSH_TLS + LDA $A0 + LDX $A1 + LDY $A2 + JSR CLASS_METHODPTR + STA $A3 + STX $A4 + LDY #METHODACCESS ; CHECK FOR STATIC METHOD + LDA ($A3),Y + AND #$08 + BNE :+ + LDA $A0 + LDX $A1 + LDY $A2 + JMP INVOKE_VIRTUAL +: LDA $A0 + LDX $A1 + LDY $A2 + JMP INVOKE_STATIC +THREAD_NOMETHD: LDA #9 ; NO METHOD DEF FOUND + JSR THROW_SYSEXCEPTN + SEC +THREAD_ERR: LDA CURRENTEXCEPTN+3 + PHA + LDA CURRENTEXCEPTN+2 + PHA + LDA CURRENTEXCEPTN+1 + PHA + LDA CURRENTEXCEPTN + PHA +;* +;* THREAD EXIT ROUTINE +;* +THREAD_EXIT: BCC :+ + JSR UNHANDLED_EXCEPTN + JSR UNREF_OBJECT +: +.IFDEF DEBUG_THREAD + PERR "THREAD_EXIT" + .IMPORT KBWAIT + JSR KBWAIT +.ENDIF + LDY CURRENT_THREAD +THREAD_KILL: LDA #S_FREE + STA THREAD_STATE,Y + LDA THREAD_HEXECL,Y + LDX THREAD_HEXECH,Y + JSR HMEM_FREE ; FREE UP SAVED 6502 STACK + LDY CURRENT_THREAD + LDY #MAX_THREADS-1 + LDX #$00 +CHKEXIT: LDA THREAD_STATE,Y + CMP #S_IDLE+1 + BCS :+ + INX +: DEY + BPL CHKEXIT + CPX #MAX_THREADS + BEQ :+ + JMP (LINK_YIELD) +: LDA #$00 + TAX + JMP VM_RESTART ; ALL DONE, EXIT VM +;* +;* INCREMENT SYSTEM TICS +;* ENTRY: AX = TIC INCREMENT +;* +SYSTEM_TIC: +.IFDEF DEBUG_TIMER + BIT $C030 +.ENDIF + CLC + ADC TIC_COUNT + STA TIC_COUNT + TXA + ADC TIC_COUNT+1 + STA TIC_COUNT+1 + LDA #$00 + ADC TIC_COUNT+2 + STA TIC_COUNT+2 + LDA #$00 + ADC TIC_COUNT+3 + STA TIC_COUNT+3 + RTS +;* +;* RETURN CURRENT TIC COUNT +;* EXIT: AX = TIC_COUNT(L/H) +;* +SYSTEM_GETTICL: SEI + LDX TIC_COUNT+1 + LDA TIC_COUNT + RTS +SYSTEM_GETTICH: SEI + LDX TIC_COUNT+3 + LDA TIC_COUNT+2 + RTS +;* +;* YIELD CURRENT THREAD, SCHEDULE NEXT THREAD +;* +THREAD_YIELD: +.IFDEF DEBUG + LDA $0100 ; CHECK FOR STACK OVERFLOW + CMP #$69 + BNE STACKOVERFLOW + LDA $0101 + CMP #$69 + BEQ :+ +STACKOVERFLOW: PERR "STACK OVERFLOWED" + JMP THROW_INTERNALERR +: +.ENDIF +.IFDEF SWAPPING + JSR HMEM_CLRACCESS ; CLEAR HMEM ACCESSED FLAGS IN INCREMENTAL, ROUND-ROBIN FASHION +.ENDIF + SEI ; DISABLE INTERRUPTS + LDY #$FF ; THIS WILL BE THE BEST THREAD PRIORITY + STY BEST_THREAD + INY + LDX CURRENT_THREAD + DEX + BPL FINDBEST + LDX #MAX_THREADS-1 +FINDBEST: LDA THREAD_STATE,X + CMP #S_SUSPEND + BCC CHECKNEXT + CMP #S_RUNNABLE + BCS ISBEST + LDA THREAD_TIMEOUT0,X ; CHECK FOR TIMEOUT + CMP TIC_COUNT + LDA THREAD_TIMEOUT1,X + SBC TIC_COUNT+1 + LDA THREAD_TIMEOUT2,X + SBC TIC_COUNT+2 + LDA THREAD_TIMEOUT3,X + SBC TIC_COUNT+3 + BCS CHECKNEXT + LDA THREAD_STATE,X + CMP #S_SLEEP + BNE :+ + LDA #S_RUNNABLE ; TIMED OUT, SET RUNNABLE + BNE :++ +: LDA #S_INTERRUPTED ; TIMED OUT, SET EXCEPTION +: STA THREAD_STATE,X +ISBEST: TYA + CMP THREAD_PRIORITY,X + BCS CHECKNEXT +SAVEBEST: STX BEST_THREAD + LDY THREAD_PRIORITY,X +CHECKNEXT: CPX CURRENT_THREAD + BEQ FOUNDBEST + DEX + BPL FINDBEST + LDX #MAX_THREADS-1 + BPL FINDBEST +FOUNDBEST: LDX BEST_THREAD + BPL SELECTTHREAD +; +; NOTHING RUNNABLE - CHECK FOR ANY GARBAGE COLLECTION TO DO +; +IDLE: CLI + INC OPCNT +.IFDEF IDLE_GC + BNE IDLELOOP + DEC IDLECNT + BNE IDLELOOP + LDA #IDLE_GC_DELAY + STA IDLECNT + JSR HMEM_GC_IDLE +IDLELOOP: JMP (LINK_YIELD) ; NOTHING RUNNABLE, KEEP WAITING +IDLECNT: .BYTE IDLE_GC_WAIT +.ELSE +IDLELOOP: JMP (LINK_YIELD) ; NOTHING RUNNABLE, KEEP WAITING +.ENDIF +; +; SELECT BEST THREAD +; +SELECTTHREAD: CPX CURRENT_THREAD + BEQ RUNTHREAD ; IN CASE OF INTERRUPTED STATE +; +; SAVE CURRENT THREAD STATE +; + LDY CURRENT_THREAD + LDA THREAD_STATE,Y + BEQ LOADEXECSTATE ; INVALID CURRENT THREAD, SKIP SAVE +SAVEEXECSTATE: LDA THREAD_HEXECL,Y + LDX THREAD_HEXECH,Y + JSR HMEM_PTR + STA TMPTR + STX TMPTR+1 + TSX + TXA + LDX CURRENT_THREAD + STA THREAD_SP,X + TAY + INY + BEQ :+ +SAVESTACK: LDA $0100,Y + STA (TMPTR),Y + INY + BNE SAVESTACK +: INC TMPTR+1 ; POINT TO ZP SAVE AREA + LDY #ZP_THREAD_SIZE-1 +SAVEZP: LDA ZP_THREAD_STATE,Y ; COPY CURRENT THREAD STATE + STA (TMPTR),Y + DEY + BPL SAVEZP + LDA THREAD_STATE,X + CMP #S_RUNNING ; ONLY SET RUNNABLE IF CURRENTLY RUNNING + BNE LOADEXECSTATE + LDA #S_RUNNABLE + STA THREAD_STATE,X +; +; LOAD BEST THREAD STATE +; +LOADEXECSTATE: LDY BEST_THREAD + LDX THREAD_HEXECH,Y + LDA THREAD_HEXECL,Y + JSR HMEM_PTR + STA TMPTR + STX TMPTR+1 + LDY BEST_THREAD + LDA THREAD_SP,Y + TAX + TXS + TAY + INY + BEQ :+ +LOADSTACK: LDA (TMPTR),Y + STA $0100,Y + INY + BNE LOADSTACK +: STY OPCNT ; RESET OPCNT FOR NEW THREAD + INC TMPTR+1 ; POINT TO ZP SAVE AREA + LDY #ZP_THREAD_SIZE-1 +LOADZP: LDA (TMPTR),Y ; COPY BEST THREAD STATE + STA ZP_THREAD_STATE,Y + DEY + BPL LOADZP +RUNTHREAD: LDY BEST_THREAD + LDX THREAD_STATE,Y +.IFDEF IDLE_GC + LDA #IDLE_GC_WAIT + STA IDLECNT +.ENDIF + LDA #S_RUNNING + STA THREAD_STATE,Y + STY CURRENT_THREAD + CLI ; ENABLE INTERRUPTS + CPX #S_INTERRUPTED + BEQ INTERRUPTED + RTS +INTERRUPTED: LDA #14 ; INTERRUPTED EXCEPTION + JMP SYSTHROW +;* +;* GRAB OBJECT LOCK +;* ENTER: AX = OBJECT HANDLE +;* +THREAD_LOCK: +.IFDEF DEBUG_LOCK + .IMPORT KBWAIT + PHA + TXA + PHA +; PERR "LOCKING THREAD" +; JSR KBWAIT + PLA + TAX + PLA +.ENDIF + STA TMP + LDY #MAX_SYNC_QUEUES-1 ; SEARCH FOR LOCKED OBJECT +SRCHLCKQ: CMP SYNCQ_HOBJL,Y + BNE :++ + TXA + CMP SYNCQ_HOBJH,Y + BNE :+ + LDA CURRENT_THREAD + CMP SYNCQ_OWNER,Y + BEQ LOCKINC + TAX ; BLOCK ON THIS OBJECT + TYA + STA THREAD_SYNCQ,X + LDA #$FF + STA THREAD_TIMEOUT0,X + STA THREAD_TIMEOUT1,X + STA THREAD_TIMEOUT2,X + STA THREAD_TIMEOUT3,X + LDA #S_BLOCK + STA THREAD_STATE,X +.IFDEF DEBUG_LOCK + PERR "SYNCING ON OBJECT" +.ENDIF + JMP (LINK_YIELD) +: LDA TMP +: DEY + BPL SRCHLCKQ + LDY #MAX_SYNC_QUEUES-1 ; SEARCH FOR AVAILABLE SYNC Q +SRCHFREEQ: LDA SYNCQ_HOBJH,Y + BEQ :+ + DEY + BPL SRCHFREEQ + PERR "NO AVAILABLE WAIT QS" + LDA #4 ; OUT OF MEMORY + JMP SYSTHROW +: LDA TMP ; INIT WAIT Q + STA SYNCQ_HOBJL,Y + TXA + STA SYNCQ_HOBJH,Y + LDA CURRENT_THREAD + STA SYNCQ_OWNER,Y +LOCKINC: LDA SYNCQ_COUNTL,Y + CLC + ADC #$01 + STA SYNCQ_COUNTL,Y + BCS :+ + RTS + STA SYNCQ_COUNTH,Y + ADC #$00 + STA SYNCQ_COUNTH,Y + BEQ :+ + PERR "THREAD LOCK COUNT OVERFLOW" + LDA #12 ; ILLEGAL MONITOR STATE + JMP SYSTHROW +: RTS +;* +;* RELEASE OBJECT LOCK +;* ENTER: AX = OBJECT HANDLE +;* +THREAD_UNLOCK: +.IFDEF DEBUG_LOCK + .IMPORT KBWAIT + PHA + TXA + PHA +; PERR "UNLOCKING THREAD" +; JSR KBWAIT + PLA + TAX + PLA +.ENDIF + STA TMP + LDY #MAX_SYNC_QUEUES-1 ; SEARCH FOR LOCKED OBJECT +SRCHUNLCKQ: CMP SYNCQ_HOBJL,Y + BNE :++ + TXA + CMP SYNCQ_HOBJH,Y + BNE :+ + LDA SYNCQ_COUNTL,Y + SEC + SBC #$01 + STA SYNCQ_COUNTL,Y + BCC LOCKDECH + BEQ RELEASELOCK + RTS ; COUNT NOT ZERO +: LDA TMP +: DEY + BPL SRCHUNLCKQ + PERR "UNLOCK OBJECT NOT FOUND IN WAIT Q" + LDA #12 ; ILLEGAL MONITOR STATE + JMP SYSTHROW +LOCKDECH: LDA SYNCQ_COUNTH,Y + SBC #$00 + STA SYNCQ_COUNTH,Y + BCS :+ + PERR "UNLOCK OBJECT COUNT UNDERFLOW" + LDA #12 ; ILLEGAL MONITOR STATE + JMP SYSTHROW +: RTS +RELEASELOCK: LDX #MAX_THREADS-1 +SRCHSYNCQ: LDA THREAD_STATE,X + CMP #S_BLOCK + BNE :+ + TYA + CMP THREAD_SYNCQ,X + BNE :+ + LDA #S_RUNNABLE ; TRANSFER Q OWNER TO WAITING THREAD + STA THREAD_STATE,X + TXA + STA SYNCQ_OWNER,Y + LDA #$01 + STA SYNCQ_COUNTL,Y +.IFDEF DEBUG_LOCK + PERR "WAKING UP OBJECT" +.ENDIF + JMP (LINK_YIELD) +; LDA #$FF +; STA OPCNT ; CAUSE SCHEDULER TO RUN SOON +; RTS +: DEX + BPL SRCHSYNCQ + LDA #$00 ; RELINQUISH WAIT Q + STA SYNCQ_HOBJH,Y + RTS +;* +;* THREAD NOTIFY IO +;* ENTRTY: Y = SLOT # +;* +THREAD_NOTIFYIO: LDA SLOT2MASK,Y + STA TMP + LDY #$00 + LDX #MAX_THREADS-1 +SRCHWAITIO: LDA THREAD_STATE,X + CMP #S_WAITIO ; IS THIS THREAD WAITING ON IO? + BNE :+ + LDA THREAD_SLOTIO,X ; WAITING ON THIS SLOT? + AND TMP + BEQ :+ + STA THREAD_SLOTIO,X ; SAVE WHICH SLOT WOKE UP + LDA #S_RUNNABLE ; WAKE IT UP + STA THREAD_STATE,X + LDA #$FF + STA OPCNT ; CAUSE SCHEDULER TO RUN SOON + INY +: DEX + BPL SRCHWAITIO + TYA ; IF NO THREAD WOKEN UP, SET NOTIFY FLAG + BEQ :+ + RTS +: LDA TMP + ORA IO_NOTIFY + STA IO_NOTIFY + RTS +;* +;* THREAD WAIT IO +;* ENTRY: Y = SLOT # +;* +THREAD_WAITIO: LDA SLOT2MASK,Y +;* +;* THREAD SELECT IO +;* ENTRY: A = SLOT SELECT MASK +;* +THREAD_SELECTIO: SEI ; CLEAR INTERRUPTS + LDX CURRENT_THREAD + BIT IO_NOTIFY ; HAS ANY SELECTED SLOT NOTIFIED? + BEQ :+ + AND IO_NOTIFY + STA THREAD_SLOTIO,X ; SAVE WHICH SLOT(S) HAS IO READY + EOR IO_NOTIFY ; CLEAR NOTIFICATION(S) + STA IO_NOTIFY +SELECTIORET: LDX CURRENT_THREAD + LDA THREAD_SLOTIO,X + RTS +: STA THREAD_SLOTIO,X ; SAVE WHICH SLOTS THREAD IS WAITING ON + LDA #S_WAITIO + STA THREAD_STATE,X + LDA #>(SELECTIORET-1) ; RETURN WITH SLOT NOTIFY IN ACCUM + PHA + LDA #<(SELECTIORET-1) + PHA + JMP (LINK_YIELD) + + .DATA +;* +;* THREAD TABLE +;* +CURRENT_THREAD: .BYTE MAX_THREADS-1 +BEST_THREAD: .BYTE $00 +THREAD_STATE: .RES MAX_THREADS ; PROCESS STATE +THREAD_PRIORITY: .RES MAX_THREADS ; EXECUTION PRIORITY +THREAD_HEXECL: .RES MAX_THREADS ; HANDLE TO EXEC STATE (STACK+ZP) +THREAD_HEXECH: .RES MAX_THREADS +THREAD_HOBJL: .RES MAX_THREADS ; HANDLE TO THREAD OBJECT INSTANCE +THREAD_HOBJH: .RES MAX_THREADS +THREAD_HOBJCLL: .RES MAX_THREADS ; OBJECT CLASS +THREAD_HOBJCLH: .RES MAX_THREADS ; OBJECT CLASS +THREAD_SP: .RES MAX_THREADS ; SAVED 6502 STACK +THREAD_TOS: .RES MAX_THREADS ; TOP OF THREAD LOCAL STORAGE +THREAD_SYNCQ: .RES MAX_THREADS ; OBJECT SYNC QUEUE CURRENTLY BLOCKED ON +THREAD_WAIT_HOBJL: .RES MAX_THREADS ; OBJECT WAIT/NOTIFY TABLE +THREAD_WAIT_HOBJH: .RES MAX_THREADS ; MANAGED IN OBJECT CLASS +THREAD_WAITQ: .RES MAX_THREADS ; WAIT ORDER (THREAD ID) +THREAD_SLOTIO: .RES MAX_THREADS ; SLOT IO WAIT MASK +THREAD_TIMEOUT0: .RES MAX_THREADS ; TIMEOUT IN MSECS +THREAD_TIMEOUT1: .RES MAX_THREADS +THREAD_TIMEOUT2: .RES MAX_THREADS +THREAD_TIMEOUT3: .RES MAX_THREADS +;* +;* SYNC QUEUE TABLE. TO AVOID PER INSTANCE DATA FOR SYNCHRONIZED OBJECT, A SMALL NUMBER +;* OF CURRENT SYNC QUEUES ARE MAINTAINED HERE. THEY ARE DYNAMICALLY ALLOCATED +;* AND ARE FREED WHEN COUNT = 0. +;* +SYNCQ_HOBJL: .RES MAX_SYNC_QUEUES +SYNCQ_HOBJH: .RES MAX_SYNC_QUEUES +SYNCQ_COUNTL: .RES MAX_SYNC_QUEUES +SYNCQ_COUNTH: .RES MAX_SYNC_QUEUES +SYNCQ_OWNER: .RES MAX_SYNC_QUEUES +;* +;* PER SLOT I/O NOTIFICATIONS +;* +IO_NOTIFY: ;.BYTE $00 +SLOT2MASK: .BYTE $00,$02,$04,$08,$10,$20,$40,$80 ; SLOT 0 IS UNUSED FOR IO +;* +;* SYSTEM TIC COUNT +;* +TIC_COUNT: .BYTE $00,$00,$00,$00 diff --git a/src/utherdrvr.s b/src/utherdrvr.s new file mode 100755 index 0000000..4706528 --- /dev/null +++ b/src/utherdrvr.s @@ -0,0 +1,491 @@ +;* +;* UTHERNET CARD DEVICE DRIVER +;* +; +; UTHER PROBE AND INIT CODE +; +.IF .DEFINED (UTHERSLOT7) +UTHER_PROBE7: +.SCOPE +UTHERSLOT = 7 +SLOTIO = $70 +SLOTROM = $C700 +.ELSEIF .DEFINED (UTHERSLOT6) +UTHER_PROBE6: +.SCOPE +UTHERSLOT = 6 +SLOTIO = $60 +SLOTROM = $C600 +.ELSEIF .DEFINED (UTHERSLOT5) +UTHER_PROBE5: +.SCOPE +UTHERSLOT = 5 +SLOTIO = $50 +SLOTROM = $C500 +.ELSEIF .DEFINED (UTHERSLOT4) +UTHER_PROBE4: +.SCOPE +UTHERSLOT = 4 +SLOTIO = $40 +SLOTROM = $C400 +.ELSEIF .DEFINED (UTHERSLOT2) +UTHER_PROBE2: +.SCOPE +UTHERSLOT = 2 +SLOTIO = $20 +SLOTROM = $C200 +.ELSEIF .DEFINED (UTHERSLOT1) +UTHER_PROBE1: +.SCOPE +UTHERSLOT = 1 +SLOTIO = $10 +SLOTROM = $C100 +.ENDIF +SRCHUTHR: STA TMPTR +@CHKSIG: LDA SLOTROM+$05 ; NO ROM SIG FOR UTHERNET + CMP #$38 + BNE @CHKAUTOSTRT + LDA SLOTROM+$07 + CMP #$18 + BNE @CHKAUTOSTRT + JMP @SKIPUTHR +@CHKAUTOSTRT: LDA SLOTROM+$01 + CMP #$20 + BNE @CHKGT ; MAKE SURE IT ISN'T AUTOSTART DEVICE + LDA SLOTROM+$05 + CMP #$03 + BNE @CHKGT + JMP @SKIPUTHR +@CHKGT: LDA SLOTROM+$01 ; MAKE SURE IT ISN'T GRAPHICS TABLET + CMP #$B0 + BNE @CHKUTHR + LDA SLOTROM+$09 + CMP #$20 + BNE @CHKUTHR +@SKIPUTHR: SEC + RTS +@CHKUTHR: LDA #$00 ; SET PACKET PAGE POINTER + STA $C08A+SLOTIO + STA $C08B+SLOTIO + LDA $C08C+SLOTIO + CMP #$0E ; LOOK FOR MAGIC VENDOR ID + BNE @SKIPUTHR + LDA $C08D+SLOTIO + CMP #$63 + BNE @SKIPUTHR +@UTHER_INIT: LDA #$00 + STA $07F8+UTHERSLOT ; CLEAR FLAGS + LDA #$14 ; RESET CHIP + STA $C08A+SLOTIO + LDA #$01 + STA $C08B+SLOTIO + LDA #$55 + STA $C08C+SLOTIO + LDA #$00 + STA $C08D+SLOTIO + CLC + RTS +.ENDSCOPE +; +; UTHER DRIVER CODE +; +.IF .DEFINED (UTHERSLOT7) +UTHER_DRIVER7: +.SCOPE +UTHERSLOT = 7 +SLOTIO = $70 +.ELSEIF .DEFINED (UTHERSLOT6) +UTHER_DRIVER6: +.SCOPE +UTHERSLOT = 6 +SLOTIO = $60 +.ELSEIF .DEFINED (UTHERSLOT5) +UTHER_DRIVER5: +.SCOPE +UTHERSLOT = 5 +SLOTIO = $50 +.ELSEIF .DEFINED (UTHERSLOT4) +UTHER_DRIVER4: +.SCOPE +UTHERSLOT = 4 +SLOTIO = $40 +.ELSEIF .DEFINED (UTHERSLOT2) +UTHER_DRIVER2: +.SCOPE +UTHERSLOT = 2 +SLOTIO = $20 +.ELSEIF .DEFINED (UTHERSLOT1) +UTHER_DRIVER1: +.SCOPE +UTHERSLOT = 1 +SLOTIO = $10 +.ENDIF + +@UTHER_DRVR_SZ: .WORD @UTHER_DRVR_END - @UTHER_DRVR_START +@UTHER_READ_OFS: .WORD @UTHER_READ - @UTHER_DRVR_START +@UTHER_WRITE_OFS: .WORD @UTHER_WRITE - @UTHER_DRVR_START +@UTHER_CTRL_OFS: .WORD @UTHER_CTRL - @UTHER_DRVR_START +@UTHER_IRQ_OFS: .WORD @UTHER_IRQ - @UTHER_DRVR_START +@UTHER_DRVR_START: +@UTHER_POLL: PHP ; CHECK FOR PENDING PACKET + SEI + LDA $07F8+UTHERSLOT ; CHECK NOT BUSY + ENABLE BITS + BEQ :+ ; NOT ENABLED, CHECK KEYBOARD + LSR + BNE :+ ; BUSY, CHECK KEYBOARD + LDA #$24 + STA $C08A+SLOTIO + LDA #$01 + STA $C08B+SLOTIO + LDA $C08D+SLOTIO + LSR + BCC :+ + LDA #$05 + STA $07F8+UTHERSLOT + PLP + JMP FAKE_IRQ ; HANDLE IT +: PLP + JMP KEYBD_POLL ; NO, POLL KEYBOARD +@UTHER_READ: PHA ; READ DATA FROM PACKET MEMORY: BYTE COUNT IN AX + LDA $0678+UTHERSLOT ; SET UP BUFFER POINTERS + STA TMPTR + LDA $06F8+UTHERSLOT + STA TMPTR+1 + TXA + TAY + BEQ :+ + LDY #$00 + STA TMPTR+2 +@UTHRRDPAGES: LDA $C080+SLOTIO ; READ 256 BYTE PAGES + STA (TMPTR),Y + INY + LDA $C081+SLOTIO + STA (TMPTR),Y + INY + BNE @UTHRRDPAGES + INC TMPTR+1 + DEC TMPTR+2 + BNE @UTHRRDPAGES +: PLA + LSR + BEQ @UTHRRDBYTE + STA TMPTR+2 +@UTHRRDSHORTS: LDA $C080+SLOTIO ; READ 16 BIT SHORTS + STA (TMPTR),Y + INY + LDA $C081+SLOTIO + STA (TMPTR),Y + INY + DEC TMPTR+2 + BNE @UTHRRDSHORTS +@UTHRRDBYTE: BCC :+ ; CHECK FOR FINAL BYTE TO READ + LDA $C080+SLOTIO + STA (TMPTR),Y + CLC +: RTS +@UTHER_WRITE: PHA ; WRITE DATA TO PACKET MEMORY: BYTECOUNT IN AX + LDA $0578+UTHERSLOT ; SET UP BUFFER POINTERS + STA TMPTR + LDA $05F8+UTHERSLOT + STA TMPTR+1 + TXA + TAY + BEQ :+ + LDY #$00 + STA TMPTR+2 +@UTHRWRPAGES: LDA (TMPTR),Y ; WRITE 256 BYTE PAGES + STA $C080+SLOTIO + INY + LDA (TMPTR),Y + STA $C081+SLOTIO + INY + BNE @UTHRWRPAGES + INC TMPTR+1 + DEC TMPTR+2 + BNE @UTHRWRPAGES +: PLA + LSR + BEQ @UTHRWRBYTE + STA TMPTR+2 +@UTHRWRSHORTS: LDA (TMPTR),Y ; WRITE 16 BIT SHORTS + STA $C080+SLOTIO + INY + LDA (TMPTR),Y + STA $C081+SLOTIO + INY + DEC TMPTR+2 + BNE @UTHRWRSHORTS +@UTHRWRBYTE: BCC :+ ; CHECK FOR FINAL BYTE TO WRITE + LDA (TMPTR),Y + STA $C080+SLOTIO + CLC +: RTS +@UTHER_CTRL: PHA + TYA ; GET IOCTL ENCODED WITH SLOT # + AND #$F8 ; MASK OFF SLOT + CMP #IOCTL_INBUFF + BNE :+ + TXA + STA $06F8+UTHERSLOT + PLA + STA $0678+UTHERSLOT + CLC + RTS +: CMP #IOCTL_OUTBUFF + BNE :+ + TXA + STA $05F8+UTHERSLOT + PLA + STA $0578+UTHERSLOT + CLC + RTS +: CMP #ETHRCTL_RECVPKT + BNE :+ + SEI + LDA $07F8+UTHERSLOT ; CHECK FLAGS + BEQ @UTHRBADSTATE ; NOT ENABLED + LSR +; BCC UTHRBADSTATE ; NOT ENABLED + LSR + BCS @UTHRRCVWAIT ; BUSY, WAIT + LSR + BCS @UTHRRCVLEN ; PENDING PACKET + LDA #$24 ; SET POINTER TO RECEIVE STATUS + STA $C08A+SLOTIO + LDA #$01 + STA $C08B+SLOTIO + LDA $C08D+SLOTIO + LSR + BCS @UTHRRCVNOW ; PACKET ALREADY WAITING +@UTHRRCVWAIT: CLI + LDY CURRENT_THREAD + JSR THREAD_NOTIMEOUT + LDY #UTHERSLOT + JSR THREAD_WAITIO + SEI + LDA $07F8+UTHERSLOT ; CHECK FLAGS + CMP #$05 + BEQ @UTHRRCVLEN + BNE @UTHRBADSTATE +@UTHRRCVNOW: LDA SLOT2MASK+UTHERSLOT ; CLEAR ANY PENDING IRQ NOTIFIES + EOR #$FF + AND IO_NOTIFY ; HAS THIS SLOT NOTIFIED? + STA IO_NOTIFY +@UTHRRCVLEN: PLA ; DISCARD SAVED ACCUM + LDA #$03 ; SET BUSY FLAG + STA $07F8+UTHERSLOT + LDA $C081+SLOTIO ; SKIP STATUS + LDA $C080+SLOTIO + LDX $C081+SLOTIO ; RETURN PACKET LENGTH + LDA $C080+SLOTIO + CLC + RTS +.IFDEF DEBUG +@UTHRBADSTATE: JSR PUTSLN + .ASCIIZ "BAD UTHERNET STATE" + JMP THROW_INTERNALERR +.ELSE +@UTHRBADSTATE: PLA + LDA #$00 + TAX + SEC + RTS +.ENDIF +: CMP #ETHRCTL_XMITPKT + BNE :+ + SEI + LDA $07F8+UTHERSLOT + CMP #$01 + BNE @UTHRBADSTATE ; NOT ENABLED OR BUSY + LDA #$03 + STA $07F8+UTHERSLOT ; SET BUSY FLAG +@UTHRXMTCMD: STX TMP + LDA #$C9 + STA $C084+SLOTIO + LDA #$00 + STA $C085+SLOTIO + PLA + STA $C086+SLOTIO + LDA TMP + STA $C087+SLOTIO +@UTHRXMTRETRY: LDA #$38 ; SET POINTER TO BUS STATUS + STA $C08A+SLOTIO + LDA #$01 + STA $C08B+SLOTIO + LDA $C08D+SLOTIO + LSR + BCC @UTHRXMTNOTRDY + CLC + RTS +@UTHRXMTNOTRDY: TXA + CLI + PHA +.IFDEF DEBUG + JSR KEYBD_POLL +.ELSE + JSR THREAD_YIELD +.ENDIF + PLA + SEI + TAX + BNE @UTHRXMTRETRY ; ALWAYS TAKEN +: CMP #ETHRCTL_DONEPKT + BNE :+ +.IFDEF DEBUG + LDA $07F8+UTHERSLOT ; CHECK FLAGS + CMP #$03 + BNE @UTHRBADSTATE ; NOT ENABLED +.ENDIF + PLA + SEI + LDA #$24 ; SET POINTER TO RECEIVE STATUS + STA $C08A+SLOTIO + LDA #$01 + STA $C08B+SLOTIO + LDA $C08D+SLOTIO + ASL + ASL + ORA #$01 ; CLEAR BUSY AND UPDATE PENDING FLAGS + STA $07F8+UTHERSLOT + LSR + BNE @UTHRDONENOTIFY ; NOTIFY IF PENDING PACKET + RTS +@UTHRDONENOTIFY: LDY #UTHERSLOT + JMP THREAD_NOTIFYIO +: CMP #ETHRCTL_SETMAC01 + BNE :+ + STX TMP + LDA #$58 ; SET POINTER TO MAC 0/1 + STA $C08A+SLOTIO + LDA #$01 + STA $C08B+SLOTIO + PLA + STA $C08C+SLOTIO + LDA TMP + STA $C08D+SLOTIO + CLC + RTS +: CMP #ETHRCTL_SETMAC23 + BNE :+ + STX TMP + LDA #$5A ; SET POINTER TO MAC 2/3 + STA $C08A+SLOTIO + LDA #$01 + STA $C08B+SLOTIO + PLA + STA $C08C+SLOTIO + LDA TMP + STA $C08D+SLOTIO + CLC + RTS +: CMP #ETHRCTL_SETMAC45 + BNE :+ + LDA #$5C ; SET POINTER TO MAC 4/5 + STA $C08A+SLOTIO + LDA #$01 + STA $C08B+SLOTIO + PLA + STA $C08C+SLOTIO + LDA TMP + STA $C08D+SLOTIO + CLC + RTS +: CMP #IOCTL_OPEN + BNE :+ + PLA + LDA #$04 ; ONLY RECEIVE VALID PACKETS + STA $C08A+SLOTIO + LDA #$01 + STA $C08B+SLOTIO + LDA #$05 + STA $C08C+SLOTIO + LDA #$0D + STA $C08D+SLOTIO + LDA #$12 ; ENABLE RX, TX + STA $C08A+SLOTIO + LDA #$01 + STA $C08B+SLOTIO + LDA #$D3 + STA $C08C+SLOTIO + LDA #$00 + STA $C08D+SLOTIO +; LDA #$02 ; ENABLE IRQ +; STA $C08A,X ; IRQ ISN'T CONNECTED BUT MAKES IT +; LDA #$01 ; EASIER TO POLL FOR RECEIVED PACKETS +; STA $C08B,X +; LDA #$03 +; STA $C08C,X +; LDA #$01 +; STA $C08D,X +; LDA #$16 +; STA $C08A,X +; LDA #$01 +; STA $C08B,X +; LDA #$17 +; STA $C08C,X +; LDA #$80 +; STA $C08D,X + LDA #$01 ; SET ENABLE FLAG + STA $07F8+UTHERSLOT + CLC + RTS +: CMP #IOCTL_CLOSE + BNE :+ + LDA #IOCTL_DEACTIVATE +: CMP #IOCTL_DEACTIVATE + BNE :+ + PLA + LDA #$12 ; DISABLE RX, TX, AND IRQ + STA $C08A+SLOTIO + LDA #$01 + STA $C08B+SLOTIO + LDA #$00 + STA $C08C+SLOTIO + LDA #$00 + STA $C08D+SLOTIO + LDA #$16 + STA $C08A+SLOTIO + LDA #$01 + STA $C08B+SLOTIO + LDA #$17 + STA $C08C+SLOTIO + LDA #$00 + STA $C08D+SLOTIO + LDA #$00 ; CLEAR FLAGS + STA $07F8+UTHERSLOT + LDY #UTHERSLOT + JSR THREAD_NOTIFYIO ; WAKE UP ANY WAITING THREADS + CLC + RTS +: CMP #IOCTL_ID + BEQ :+ + PLA + SEC + RTS +: PLA + LDA #$E1 ; UTHER ID + CLC + RTS +@UTHER_IRQ: LDA $07F8+UTHERSLOT + BNE :+ ; SKIP IF NOT ENABLED +@UTHRNOSERV: SEC + RTS +: CMP #$05 ; CHECK PENDING FLAG + BNE :+ + CLC + RTS +: CMP #$01 ; CHECK ENABLED FLAG + BNE @UTHRNOSERV ; BUSY, DON'T SERVICE YET + LDA #$24 ; SET POINTER TO RECEIVE STATUS + STA $C08A+SLOTIO + LDA #$01 + STA $C08B+SLOTIO + LDA $C08D+SLOTIO + LSR + BCC @UTHRNOSERV + LDA #$05 ; SET BUSY AND PENDING FLAG + STA $07F8+UTHERSLOT + CLC + RTS +@UTHER_DRVR_END EQU * +.ENDSCOPE \ No newline at end of file diff --git a/src/utils.s b/src/utils.s new file mode 100755 index 0000000..b8d4f26 --- /dev/null +++ b/src/utils.s @@ -0,0 +1,263 @@ +;* +;* JAVA UTILITIES FOR 6502 +;* + .INCLUDE "global.inc" + .EXPORT UTIL_INIT,MEMSRC,MEMDST,MEMCPY,MEMCLR,MEMSET + .EXPORT MUL5,MUL9,MUL10 + + .SEGMENT "INIT" +UTIL_INIT: LDA #MEMSRC + STA LINK_MEMSRC+1 + LDA #MEMDST + STA LINK_MEMDST+1 + LDA #MEMCPY + STA LINK_MEMCPY+1 + LDA #MEMCLR + STA LINK_MEMCLR+1 + LDA #MEMSET + STA LINK_MEMSET+1 + RTS + + .CODE +;* +;* SET MEMORY SRC OPERAND +;* ENTRY: AX = ADDRESS +;* +MEMSRC: STA SRCADDR + STX SRCADDR+1 + RTS +;* +;* SET MEMORY DST OPERAND +;* ENTRY: AX = ADDRESS +;* +MEMDST: STA DSTADDR + STX DSTADDR+1 + RTS +;* +;* COPY MEMORY +;* +;* ENTRY: SRCADDR = SOURCE ADDRESS +;* DSTADDR = DESTINATION ADDRESS +;* AX = LENGTH IN BYTES +;* +MEMCPY: TAY + LDA SRCADDR+1 + CMP DSTADDR+1 + BCC REVCPY + BNE :+ + LDA SRCADDR + CMP DSTADDR +: BCS FORCPY +REVCPY: TXA ; REVERSE DIRECTION COPY +; CLC + ADC SRCADDR+1 + STA SRCADDR+1 + TXA + CLC + ADC DSTADDR+1 + STA DSTADDR+1 + INX + CPY #$00 + BEQ :++ + DEY + BEQ :+ +REVCPYLOOP: LDA (SRCADDR),Y + STA (DSTADDR),Y + DEY + BNE REVCPYLOOP +: LDA (SRCADDR),Y ; DO ONE MORE COPY, Y = #$00 + STA (DSTADDR),Y ; (THIS MAKES FOR A SLIGHTLY FASTER INNER LOOP) +: DEY ; NOW Y = #$FF + DEX + BEQ :+ + DEC SRCADDR+1 + DEC DSTADDR+1 + BNE REVCPYLOOP +: RTS +FORCPY: TYA ; FORWARD DIRECTION COPY + EOR #$FF + TAY + INY + BNE :+ + DEX +: LDA SRCADDR + STY SRCADDR +; SEC + SBC SRCADDR + STA SRCADDR + LDA SRCADDR+1 + SBC #$00 + STA SRCADDR+1 + LDA DSTADDR + STY DSTADDR + SEC + SBC DSTADDR + STA DSTADDR + LDA DSTADDR+1 + SBC #$00 + STA DSTADDR+1 + INX +FORCPYLOOP: LDA (SRCADDR),Y + STA (DSTADDR),Y + INY + BNE FORCPYLOOP + DEX + BEQ :+ + INC SRCADDR+1 + INC DSTADDR+1 + BNE FORCPYLOOP +: RTS +;* +;* CLEAR MEMORY +;* +;* ENTRY: DSTADDR = DESTINATION ADDRESS TO CLEAR +;* AX = LENGTH IN BYTES +;* +MEMCLR: LDY #$00 +;* +;* SET MEMORY +;* +;* ENTRY: DSTADDR = DESTINATION ADDRESS TO SET +;* AX = LENGTH IN BYTES +;* Y = VALUE TO SET +;* +MEMSET: STY TMP + CPX #$00 + BEQ SMALLSET + STA TMP+1 + LDY #$00 + LDA TMP +: STA (DSTADDR),Y + INY + BNE :- + INC DSTADDR+1 + DEX + BNE :- + LDA TMP+1 +SMALLSET: TAY + BEQ SETDONE + LDA TMP +: DEY + STA (DSTADDR),Y + BNE :- +SETDONE: RTS + +;* +;* MULTIPLY BY 5 - TURN INDEX INTO CONSTANT POOL INTO OFFSET +;* ENTRY: AX = VALUE +;* EXIT: AX = VALUE * 5 +;* C = OVERFLOW +;* +MUL5: STA TMP + STX TMP+1 + ASL + ROL TMP+1 + ASL + ROL TMP+1 + ADC TMP + PHA + TXA + ADC TMP+1 + TAX + PLA + RTS +;* +;* MULTIPLY BY 7 - TURN INDEX INTO FIELD TABLE INTO OFFSET +;* ENTRY: AX = VALUE +;* EXIT: AX = VALUE * 7 +;* C = OVERFLOW +;* +;MUL7: STA TMP +; STX TMP+1 +; ASL TMP +; ROL TMP+1 +; ADC TMP +; PHA +; TXA +; ADC TMP+1 +; TAX +; PLA +; ASL TMP +; ROL TMP+1 +; ADC TMP +; PHA +; TXA +; ADC TMP+1 +; TAX +; PLA +; RTS +;* +;* MULTIPLY BY 9 - TURN INDEX INTO FIELD TABLE INTO OFFSET +;* ENTRY: AX = VALUE +;* EXIT: AX = VALUE * 9 +;* C = OVERFLOW +;* +MUL9: STA TMP + STX TMP+1 + ASL + ROL TMP+1 + ASL + ROL TMP+1 + ASL + ROL TMP+1 + ADC TMP + PHA + TXA + ADC TMP+1 + TAX + PLA + RTS +;* +;* MULTIPLY BY 10 - TURN INDEX INTO METHOD TABLE INTO OFFSET +;* ENTRY: AX = VALUE +;* EXIT: AX = VALUE * 10 +;* C = OVERFLOW +;* +MUL10: STA TMP ; Y = X + 4X = 5X + STX TMP+1 + ASL + ROL TMP+1 + ASL + ROL TMP+1 + ADC TMP + STA TMP + TXA + ADC TMP+1 + ASL TMP ; RETURN Y * 4 = 5X * 2 = 10X + ROL + TAX + LDA TMP + RTS +;* +;* MULTIPLY BY 20 - TURN INDEX INTO METHOD TABLE INTO OFFSET +;* ENTRY: AX = VALUE +;* EXIT: AX = VALUE * 20 +;* C = OVERFLOW +;* +;MUL20: STA TMP ; Y = X + 4X = 5X +; STX TMP+1 +; ASL +; ROL TMP+1 +; ASL +; ROL TMP+1 +; ADC TMP +; STA TMP +; TXA +; ADC TMP+1 +; ASL TMP ; RETURN Y * 4 = 5X * 4 = 20X +; ROL +; ASL TMP +; ROL +; TAX +; LDA TMP +; RTS diff --git a/src/vm02.s b/src/vm02.s new file mode 100755 index 0000000..a490501 --- /dev/null +++ b/src/vm02.s @@ -0,0 +1,373 @@ +;* +;* JAVA VIRTUAL MACHINE FOR APPLE II PRODOS +;* + .INCLUDE "global.inc" + .INCLUDE "class.inc" + .IMPORT UTIL_INIT,HOME,GETLN,PRSTR,PRSTRLN,PRHSTRLN,COUT,CROUT,PUTS,PRBYTE,KBWAIT,MEMSRC,MEMDST,MEMCPY + .IMPORT HMEM_INIT,HMEM_ALLOC,HMEM_FREE + .IMPORT HMEM_PTR,HMEM_REF_INC,HMEM_REF_DEC,HMEM_LOCK,HMEM_GC + .IMPORT HSTR_INIT,STR_HASH,HSTR_HASH,HSTRPL_ADD,HSTRPL_DEL + .IMPORT LOADCLASS_INIT,IO_INIT,IODEV_INIT,VBL_INIT + .IMPORT HCLASS_INIT,HCLASS_NAME,HCLASS_HNDL,CLASS_MATCH_NAME,CLASS_MATCH_DESC + .IMPORT RESOLVE_CLASS,RESOLVE_METHOD,CLASS_METHODPTR + .IMPORT SYSCLASS_INIT,EXCEPT_INIT,SYS_CALL + .IMPORT HMAINNAMESTR,HMAINDESCSTR + .IMPORT THREAD_INIT,THREAD_NEW,THREAD_SETRUN,THREAD_YIELD + .IMPORT ITHREAD_PUSH_SP,ITHREAD_PUSH_TLS,LOADEXECSTATE,BEST_THREAD + .IMPORT INTERP_INIT,INTERP_END,DVM_INIT + .IMPORT CLASSPREFIX,PREFIX_SET,FILE_GETINFO,FILE_OPEN,FILE_CLOSE,FILE_SETBUFFER,FILE_BLOAD +.IFDEF SWAPPING + .IMPORT HMEM_SWAP_CLEANUP +.ENDIF + .EXPORT INIT_START,VM_RESTART,WARM_INIT + +.IFDEF DEBUG + .IMPORT HMEM_DUMP,HSTRPL_DUMP +.ENDIF +PARSELEN EQU $A0 + + .SEGMENT "INIT" + +INIT_START: +VM_WARMINIT: DEC WARM_INIT + LDX #$9E ; DEVICE CTRL CALL FUNC INDEX +: STX DEVSLOT + TXA ; CONVERT TO SLOT # + LSR + AND #$07 + ORA #IOCTL_DEACTIVATE + TAY + SEI ; DISABLE INTERRUPTS + JSR DEVCALL ; DEACTIVATE DEVICES + CLI + LDX DEVSLOT + DEX + DEX + CPX #$90 + BNE :- + PSTRLN "" ; I HAVE NO IDEA WHY THIS IS NEEDED + LDX #$FF ; RESET STACK + TXS + LDA CHAIN_CMD ; NO PASSED IN PARAMS + PHA +.IF 0 + BNE :+ + PSTR "PRESS ESC TO REBOOT, RETURN TO CONTINUE." + JSR KBWAIT + CMP #$9B + BNE :+ + JSR PRODOS + .BYTE $41 ; DE-ALLOC INTERRUPT + .ADDR DEALLOCINTPARMS + BIT ROMIN ; SWAP ROM IN + LDA #$00 + STA $3F4 ; INVALIDATE POWER-UP BYTE + JMP ($FFFC) ; RESET +: JSR CROUT +.ENDIF + JMP SKIPBANNER +; +; INITIALIZE SYSTEM +; +VM_INIT: LDA #$00 + STA $3F4 ; INVALIDATE POWER-UP BYTE + LDX #$F0 ; CLEAR LINK TABLE + LDA #$00 +: DEX + STA LINK_TABLE,X + BNE :- + JSR IO_INIT + JSR HOME +.IFDEF BIGMEM + PSTR "VM02 128K" +.ELSE + PSTR "VM02 64K" +.ENDIF +.IFDEF FLOATING_POINT + PSTR " Floating Point" +.ENDIF + PSTRLN " Version 1.0" + PSTRLN "Copyright 2010, David Schmenk" +; PSTRLN "'EXIT' to reboot" +SKIPBANNER: +.IFDEF DEBUG + PSTRLN "DEBUG ENABLED" + LDA #$69 ; PLACE FENCE AT BOTTOM OF STACK + STA $0100 + STA $0101 +.ENDIF +.IFDEF DEBUG_DUMP + LDA #$00 ; TURN ON DEBUG SLOT + STA CSWL + LDA #$C0|DEBUG_DUMP + STA CSWH +.ENDIF + LDA #$4C ; JMP INSTRUCTION + STA OPJMP + LDA #VM_RESTART + STA LINK_EXIT+1 + LDA #VM_REBOOT + STA LINK_REBOOT+1 + JSR UTIL_INIT + JSR HMEM_INIT + JSR IODEV_INIT + JSR HSTR_INIT + JSR HCLASS_INIT + JSR THREAD_INIT + JSR EXCEPT_INIT + JSR INTERP_INIT + JSR DVM_INIT + JSR LOADCLASS_INIT + SEI ; DISABLE INTERRUPTS + BIT LCBNK2 ; MAKE SURE LCBANK2 SET UP + BIT LCBNK2 + CLI + JSR SYSCLASS_INIT +; +; LOOK FOR STARTUP FILE IN INPUT BUFFER ($01FF = LEN OF STARTUP STRING) +; + PLA + BEQ :+ + TAX + BNE PARSECMD +: LDA #STARTUP + JSR FILE_GETINFO + BCS CMDLINE ; NOPE, INPUT COMMAND LINE + LDA #$00 + PHA + STA PARSELEN + LDA #STARTUP + JMP SETRUNCLASS +; +; PROMPT FOR MAIN CLASS +; +CMDLINE: PSTR "Main class" + LDA #':'|$80 + STA PROMPTCHAR + JSR GETLN + CPX #$00 + BEQ CMDLINE +PARSECMD: STX PARSELEN +: LDA $0200,X ; STRIP OFF HIGH BITS + AND #$7F + STA $0200,X + DEX + BPL :- + LDX #$00 + JSR PARSELINE + TXA + BEQ CMDLINE + PHA ; CLEVERLY PUT STRING LENGTH + LDA #$FF ; IN FRONT OF INPUT BUFFER AT $200 + LDX #$01 +SETRUNCLASS: JSR HSTRPL_ADD + STA RUNCLASS + STX RUNCLASS+1 +.IFDEF DEBUG_PARAMS + JSR PRHSTRLN + JSR KBWAIT +.ENDIF +PARSEARGS: PLA + BEQ :+ + TAX + JSR PARSELINE + TXA + BEQ :+ + PHA + LDA #$FF + LDX #$01 + JSR HSTRPL_ADD + STY TMP + LDY NARGS + STA HARGSL,Y + TXA + STA HARGSH,Y + LDA TMP + STA ARGSHASH,Y + INC NARGS + BNE PARSEARGS +: LDA NARGS ; ALLOCATE ARGS ARRAY + ASL + ASL + CLC + ADC #$02 + LDX #$00 + LDY #$00 + JSR HMEM_ALLOC + STA HARGS + STX HARGS+1 + JSR HMEM_PTR + STA $A0 + STX $A1 + LDY #$00 + LDA NARGS + STA ($A0),Y + TYA + TAX + INY + STA ($A0),Y + LDA NARGS + BEQ RUNMAIN + INY +FILLARGS: LDA HARGSL,X + STA ($A0),Y + INY + LDA HARGSH,X + STA ($A0),Y + INY + LDA #CL_STR + STA ($A0),Y + INY + LDA ARGSHASH,X + STA ($A0),Y + INY + INX + DEC NARGS + BNE FILLARGS +RUNMAIN: JSR VBL_INIT ; TURN VBL IRQS ON IF PRESSENT + LDA #$00 + BIT CLRKBD ; CLEAR KEYBOARD + STA TYPEBUFFLEN ; FLUSH INPUT BUFFER + STA CHAIN_CMD ; CLEAR CHAIN COMMAND + TAX + JSR THREAD_NEW ; NEED TO CREATE THREAD INSTANCE OBJECT + LDA #T_REF + LDX #CL_ARRAY + JSR ITHREAD_PUSH_SP ; PUSH MAIN PARAM ON STACK + LDA HARGS+1 + LDX HARGS + JSR ITHREAD_PUSH_SP + LDA HMAINNAMESTR ; RUN MAIN METHOD + LDX HMAINNAMESTR+1 + JSR ITHREAD_PUSH_SP + LDA HMAINDESCSTR + LDX HMAINDESCSTR+1 + JSR ITHREAD_PUSH_SP + LDA RUNCLASS ; RETRIEVE CLASS NAME + LDX RUNCLASS+1 + JSR ITHREAD_PUSH_SP + JSR THREAD_SETRUN + STY BEST_THREAD + JSR LOADEXECSTATE ; JUMP TO SCHEDULER + PERR "OOPS, RETURN FROM YIELD" + BRK + LDA INTERP_END ; DUMMY READ TO MAKE EXTERN SHOW UP IN MAP FILE +PARSELINE: LDY #$00 ; SKIP PREVIOUS STRING + LDA INQUOTE + BEQ :+ + DEC INQUOTE + INX +: LDA PARSELEN + STX PARSELEN + SEC + SBC PARSELEN + STA PARSELEN + BNE SKIPPREV +PARSEDONE: LDX #$00 + RTS +SKIPPREV: LDA $0200,X + STA $0200,Y + INY + INX + BPL SKIPPREV + LDX #$00 +SKIPSPACE: LDA $0200 + CMP #'"' + BEQ PARSEQUOTE + CMP #' '+1 ; CHECK FOR WHITESPACE + BCS PARSESTR + DEC PARSELEN + BEQ PARSEEXIT +: LDA $0201,X ; SHIFT BUFFER DOWN + STA $0200,X + INX + BPL :- + LDX #$00 + BEQ SKIPSPACE +PARSESTR: INX + CPX PARSELEN + BEQ PARSEEXIT + LDA $0200,X + CMP #' '+1 + BCS PARSESTR +PARSEEXIT: RTS +PARSEQUOTE: DEC PARSELEN +: LDA $0201,X ; SKIP QUOTE CHAR + STA $0200,X + INX + BPL :- + LDX #$FF +FINDQUOTE: INX + CPX PARSELEN + BEQ PARSEEXIT + LDA $0200,X + CMP #'"' + BNE FINDQUOTE + INC INQUOTE + RTS +DEVCALL: .BYTE $6C +DEVSLOT: .BYTE $92,$03 +STARTUP: .BYTE 7,"STARTUP" +RUNCLASS: .WORD $0000 +NARGS: .BYTE $00 +INQUOTE: .BYTE $00 +HARGSL: .RES 10 +HARGSH: .RES 10 +ARGSHASH: .RES 10 +HARGS: .WORD $0000 +WARM_INIT: .BYTE $00 +DEALLOCINTPARMS: .BYTE $01 + .BYTE $00 ; INT NUM + + .CODE +;* +;* MAIN ENTRYPOINT +;* +; ORG $1000 +VM_STARTUP: JMP VM_INIT +;* +;* ALL THREADS ARE DONE, OR AN UNRECOVERABLE ERROR OCCURED +;* EXIT TO PRODOS +;* +VM_RESTART: STA EXIT_STATUS ; SAVE EXIT STATUS + STX EXIT_STATUS+1 + LDX #$05 ; CLOSE ALL OPEN FILES +: LDA LINK_OPENFILES,X + BEQ :+ + STX ACNT + TAY + JSR FILE_CLOSE + LDX ACNT +: DEX + BPL :-- + LDA #CLASSPREFIX + JSR PREFIX_SET + LDA #$00 + LDX #$10 + JSR FILE_SETBUFFER + LDA #VM02FILE + JSR FILE_BLOAD +.IFDEF SWAPPING + JSR HMEM_SWAP_CLEANUP ; CALL CLEANUP IN INIT SECTION - TOO COOL +.ENDIF + JMP VM_WARMINIT ; WARM INIT +VM_REBOOT: SEI + DEC $3F4 ; INVALIDATE POWER-UP BYTE + BIT ROMIN ; SWAP ROM IN + JMP ($FFFC) ; RESET + + .DATA + +.IFDEF BIGMEM +VM02FILE: .BYTE 5,"VM02E" +.ELSE +VM02FILE: .BYTE 4,"VM02" +.ENDIF diff --git a/tools/PRODOS#ff0000 b/tools/PRODOS#ff0000 new file mode 100755 index 0000000..adcbb1c Binary files /dev/null and b/tools/PRODOS#ff0000 differ diff --git a/tools/class2asm.c b/tools/class2asm.c new file mode 100755 index 0000000..6be3b3b --- /dev/null +++ b/tools/class2asm.c @@ -0,0 +1,630 @@ +#include +#include +#include + +char *opcode[256] = { "nop", "aconst_null", "iconst_m1", "iconst_0", + "iconst_1", "iconst_2", "iconst_3", "iconst_4", + "iconst_5", "lconst_0", "lconst_1", "fconst_0", + "fconst_1", "fconst_2", "dconst_0", "dconst_1", + "bipush", "sipush", "ldc", "ldc_w", + "ldc2_w", "iload", "lload", "fload", + "dload", "aload", "iload_0", "iload_1", + "iload_2", "iload_3", "lload_0", "lload_1", + "lload_2", "lload_3", "fload_0", "fload_1", + "fload_2", "fload_3", "dload_0", "dload_1", + "dload_2", "dload_3", "aload_0", "aload_1", + "aload_2", "aload_3", "iaload", "laload", + "faload", "daload", "aaload", "baload", + "caload", "saload", "istore", "lstore", + "fstore", "dstore", "astore", "istore_0", + "istore_1", "istore_2", "istore_3", "lstore_0", + "lstore_1", "lstore_2", "lstore_3", "fstore_0", + "fstore_1", "fstore_2", "fstore_3", "dstore_0", + "dstore_1", "dstore_2", "dstore_3", "astore_0", + "astore_1", "astore_2", "astore_3", "iastore", + "lastore", "fastore", "dastore", "aastore", + "bastore", "castore", "sastore", "pop", + "pop2", "dup", "dup_x1", "dup_x2", + "dup2", "dup2_x1", "dup2_x2", "swap", + "iadd", "ladd", "fadd", "dadd", + "isub", "lsub", "fsub", "dsub", + "imul", "lmul", "fmul", "dmul", + "idiv", "ldiv", "fdiv", "ddiv", + "irem", "lrem", "frem", "drem", + "ineg", "lneg", "fneg", "dneg", + "ishl", "lshl", "ishr", "lshr", + "iushr", "lushr", "iand", "land", + "ior", "lor", "ixor", "lxor", + "iinc", "i2l", "i2f", "i2d", + "l2i", "l2f", "l2d", "f2i", + "f2l", "f2d", "d2i", "d2l", + "d2f", "i2b", "i2c", "i2s", + "lcmp", "fcmpl", "fcmpg", "dcmpl", + "dcmpg", "ifeq", "ifne", "iflt", + "ifge", "ifgt", "ifle", "if_icmpeq", + "if_icmpne", "if_icmplt", "if_icmpge", "if_icmpgt", + "if_icmple", "if_acmpeq", "if_acmpne", "goto", + "jsr", "ret", "tableswitch", "lookupswitch", + "ireturn", "lreturn", "freturn", "dreturn", + "areturn", "return", "getstatic", "putstatic", + "getfield", "putfield", "invokevirtual", "invokespecial", + "invokestatic", "invokeinterface", "xxx_unused_xxx", "new", + "newarray", "anewarray", "arraylength", "athrow", + "checkcast", "instanceof", "monitorenter", "monitorexit", + "wide", "multianewarray", "ifnull", "ifnonnull", + "goto_w", "jsr_w", "breakpoint", "XXX", + "XXX","XXX", "XXX", "XXX", + "XXX","XXX", "XXX", "XXX", "XXX", "XXX", "XXX", "XXX", + "XXX","XXX", "XXX", "XXX", "XXX", "XXX", "XXX", "XXX", + "XXX","XXX", "XXX", "XXX", "XXX", "XXX", "XXX", "XXX", + "XXX","XXX", "XXX", "XXX", "XXX", "XXX", "XXX", "XXX", + "XXX","XXX", "XXX", "XXX", "XXX", "XXX", "XXX", "XXX", + "XXX","XXX", "XXX", "XXX", "XXX", "XXX", "impdep1", "impdep2" + }; +char *atype[] = { "???", "???", "???", "???", + "T_BOOLEAN", "T_CHAR", "T_FLOAT", "T_DOUBLE", + "T_BYTE", "T_SHORT", "T_INT", "T_LONG" + }; +char *as65str[] = { + "\t.BYTE\t", + "\t.ORG\t", + "\t.BYTE\t", + ";*", + ":", + "\t", + "\"", + "(", + ")" + }; +char *merlinstr[] = { + " DFB ", + " ORG ", + " ASC ", + "*", + "", + " ", + "\'", + "", + "" + }; +#define DFB 0 +#define ORG 1 +#define ASC 2 +#define CMNT 3 +#define LABL 4 +#define TAB 5 +#define QUOT 6 +#define OPAREN 7 +#define CPAREN 8 +char **asmstring = NULL; + +#define TO_32(b) ((b[0]<<24)|(b[1]<<16)|(b[2]<<8)|(b[3])) +#define TO_16(b) ((b[0]<<8)|(b[1])) + +int CodeAttrName, ConstantAttrName, ExceptAttrName, InnerClassAttrName, + SyntheticAttrName, SourceAttrName, LineNumAttrName, LocalVarAttrName; +unsigned char buf[256]; + +void DumpAttr(int fd, int name, int len, char blktype, int blknum, int attrnum) +{ + char attrbgn[10], attrend[10]; + sprintf(attrbgn, "%c%dA%dBGN", blktype, blknum, attrnum); + sprintf(attrend, "%c%dA%dEND", blktype, blknum, attrnum); + printf("%s$%02X,$%02X%s; NAME #%d\n", asmstring[DFB], (name >> 8) & 0xFF, name & 0xFF, asmstring[TAB], name); + printf("%s$%02X,$%02X,>%s%s-%s%s,<%s%s-%s%s\n", asmstring[DFB], (len >> 24) & 0xFF,(len >> 16) & 0xFF, asmstring[OPAREN], attrend, attrbgn, asmstring[CPAREN], asmstring[OPAREN], attrend, attrbgn, asmstring[CPAREN]); + printf("%s%s\n", attrbgn, asmstring[LABL]); + if (name == CodeAttrName) + { + unsigned short max_stack, max_locals, cnt, val; + signed short sval; + int ival, defval, lval, hval, pad; + unsigned long code_len, pc; + char opstr[40], codebgn[10], codeend[10]; + + printf("%s CODE:\n", asmstring[CMNT]); + sprintf(codebgn, "%c%dC%dBGN", blktype, blknum, attrnum); + sprintf(codeend, "%c%dC%dEND", blktype, blknum, attrnum); + read(fd, buf, 2); max_stack = TO_16(buf); + printf("%s$%02X,$%02X%s; MAX STACK %d\n", asmstring[DFB], buf[0],buf[1], asmstring[TAB], max_stack); + read(fd, buf, 2); max_locals = TO_16(buf); + printf("%s$%02X,$%02X%s; MAX LOCALS %d\n", asmstring[DFB], buf[0],buf[1], asmstring[TAB], max_locals); + read(fd, buf, 4); code_len = TO_32(buf); + printf("%s$%02X,$%02X,>%s%s-%s%s,<%s%s-%s%s\n", asmstring[DFB], (len >> 24) & 0xFF,(len >> 16) & 0xFF, asmstring[OPAREN], codeend, codebgn, asmstring[CPAREN], asmstring[OPAREN], codeend, codebgn, asmstring[CPAREN]); + printf("%s%s\n", codebgn, asmstring[LABL]); + + for (pc = 0; pc < code_len; pc++) + { + read(fd, buf, 1); + sprintf(opstr, "%05lu: %s", pc, opcode[buf[0]]); + printf("%s$%02X", asmstring[DFB], buf[0]); + switch (buf[0]) + { + case 0x19: // local var index8 + case 0x3A: + case 0x18: + case 0x39: + case 0x17: + case 0x38: + case 0x84: + case 0x15: + case 0x36: + case 0x16: + case 0x37: + case 0xA9: + read(fd, buf+1, 1); + printf(",$%02X", buf[1]); + sprintf(opstr, "%s %u", opstr, buf[1]); + if (buf[0] == 0x84) // , const + { + read(fd, buf, 1); + printf(",$%02X", buf[0]); + sprintf(opstr, "%s %d", opstr, (signed char)buf[0]); + pc++; + } + pc++; + break; + case 0xC4: // wide local var index16 + read(fd, buf, 1); + if (buf[0] == 0x84) + { + read(fd, buf, 2); val = TO_16(buf); + printf(",$%02X,$%02X", buf[0], buf[1]); + sprintf(opstr, "%s iinc %u", opstr, val); + read(fd, buf, 2); val = TO_16(buf); + printf(",$%02X,$%02X", buf[0], buf[1]); + sprintf(opstr, "%s %d", opstr, val); + pc += 5; + } + else + { + sprintf(opstr, "%s %s", opstr, opcode[buf[0]]); + read(fd, buf, 2); val = TO_16(buf); + printf(",$%02X,$%02X", buf[0], buf[1]); + sprintf(opstr, "%s %u", opstr, val); + pc += 3; + } + break; + case 0x12: // class const pool index8 + read(fd, buf+1, 1); + printf(",$%02X", buf[1]); + sprintf(opstr, "%s #%u", opstr, buf[1]); + pc++; + break; + case 0xBD: // class const pool index16 + case 0xC0: + case 0xB4: + case 0xB2: + case 0xC1: + case 0xB7: + case 0xB8: + case 0xB6: + case 0x13: + case 0x14: + case 0xBB: + case 0xB5: + case 0xB3: + case 0xB9: + case 0xC5: + buf[2] = buf[0]; + read(fd, buf, 2); val = TO_16(buf); + printf(",$%02X,$%02X", buf[0], buf[1]); + sprintf(opstr, "%s #%u", opstr, val); + if (buf[2] == 0xC5) // , dimensions + { + read(fd, buf, 1); + printf(",$%02X", buf[0]); + sprintf(opstr, "%s %d", opstr, buf[0]); + pc++; + } + if (buf[2] == 0xB9) // , count, 0 + { + read(fd, buf, 2); + printf(",$%02X,$%02X", buf[0], buf[1]); + sprintf(opstr, "%s %d", opstr, buf[0]); + pc += 2; + } + pc += 2; + break; + case 0x10: // byte + read(fd, buf, 1); + printf(",$%02X", buf[0]); + sprintf(opstr, "%s %d", opstr, buf[0]); + pc++; + break; + case 0xBC: // atype + read(fd, buf, 1); + sprintf(opstr, "%s %d (%s)", opstr, buf[0], atype[buf[0]]); + pc++; + break; + case 0x11: // short + read(fd, buf, 2); val = TO_16(buf); + printf(",$%02X,$%02X", buf[0], buf[1]); + sprintf(opstr, "%s %d", opstr, val); + pc += 2; + break; + case 0xA7: // branch16 + case 0xA5: + case 0xA6: + case 0x9F: + case 0xA0: + case 0xA1: + case 0xA2: + case 0xA3: + case 0xA4: + case 0x99: + case 0x9A: + case 0x9B: + case 0x9C: + case 0x9D: + case 0x9E: + case 0xC7: + case 0xC6: + case 0xA8: + read(fd, buf, 2); sval = TO_16(buf); + printf(",$%02X,$%02X", buf[0], buf[1]); + sprintf(opstr, "%s %+d (%06lu)", opstr, sval, pc + sval); + pc += 2; + break; + case 0xC9: // branch32 + case 0xC8: + read(fd, buf, 4); ival = TO_32(buf); + printf(",$%02X,$%02X,$%02X,$%02X", buf[0], buf[1], buf[2], buf[3]); + sprintf(opstr, "%s %+d (%06lu)", opstr, ival, pc + ival); + pc += 4; + break; + case 0xAB: // lookupswitch + pad = ((pc + 1) & 0x03); + if (pad) + { + pad = 4 - pad; + read(fd, buf, pad); // padding + for (cnt=0; cnt < pad; cnt++) + printf(",$00"); + } + read(fd, buf, 4); defval = TO_32(buf); // default + printf("%s$%02X,$%02X,$%02X,$%02X%s; DEFAULT %+d (%06lu)", asmstring[DFB], buf[0], buf[1], buf[2], buf[3], asmstring[TAB], defval, pc + defval); + read(fd, buf, 4); hval = TO_32(buf); // num pairs + printf("%s$%02X,$%02X,$%02X,$%02X%s; NUM PAIRS %d", asmstring[DFB], buf[0], buf[1], buf[2], buf[3], asmstring[TAB], hval); + for (cnt = 0; cnt < hval; cnt++) + { + read(fd, buf, 4); ival = TO_32(buf); // match + printf("%s$%02X,$%02X,$%02X,$%02X%s; MATCH %d", asmstring[DFB], buf[0], buf[1], buf[2], buf[3], asmstring[TAB], ival); + read(fd, buf, 4); lval = TO_32(buf); // offsets + printf("%s$%02X,$%02X,$%02X,$%02X%s; OFFSET %d: %+d (%06lu)\n", asmstring[DFB], buf[0], buf[1], buf[2], buf[3], asmstring[TAB], ival, lval, pc + lval); + } + pc += pad + 8 + 8 * hval; + opstr[0] = '\0'; + break; + case 0xAA: // tableswitch + pad = ((pc + 1) & 0x03); + if (pad) + { + pad = 4 - pad; + read(fd, buf, pad); // padding + for (cnt=0; cnt < pad; cnt++) + printf(",$00"); + } + printf("%s; %s\n", asmstring[TAB], opstr); + read(fd, buf, 4); defval = TO_32(buf); // default + printf("%s$%02X,$%02X,$%02X,$%02X%s; DEFAULT %+d (%06lu)", asmstring[DFB], buf[0], buf[1], buf[2], buf[3], asmstring[TAB], defval, pc + defval); + read(fd, buf, 4); lval = TO_32(buf); // low value + printf("%s$%02X,$%02X,$%02X,$%02X%s; LO VAL %d", asmstring[DFB], buf[0], buf[1], buf[2], buf[3], asmstring[TAB], lval); + read(fd, buf, 4); hval = TO_32(buf); // high value + printf("%s$%02X,$%02X,$%02X,$%02X%s; HI VAL %d", asmstring[DFB], buf[0], buf[1], buf[2], buf[3], asmstring[TAB], hval); + for (cnt = lval; cnt <= hval; cnt++) + { + read(fd, buf, 4); ival = TO_32(buf); // offsets + printf("%s$%02X,$%02X,$%02X,$%02X%s; %d: %+d (%06u)\n", asmstring[DFB], buf[0], buf[1], buf[2], buf[3], asmstring[TAB], hval, cnt, ival, pc + ival); + } + pc += pad + 12 + 4 * (hval - lval + 1); + opstr[0] = '\0'; + break; + } + if (opstr[0]) + printf("%s; %s\n", asmstring[TAB], opstr); + } + printf("%s%s\n", codeend, asmstring[LABL]); + read(fd, buf, 2); cnt = TO_16(buf); + printf("%s EXCEPTION TABLE\n", asmstring[CMNT]); + printf("%s$%02X,$%02X%s; COUNT %d\n", asmstring[DFB], buf[0], buf[1], asmstring[TAB], cnt); + while (cnt--) + { + read(fd, buf, 2); val = TO_16(buf); + printf("%s$%02X,$%02X%s; FROM %05u\n", asmstring[DFB], buf[0], buf[1], asmstring[TAB], val); + read(fd, buf, 2); val = TO_16(buf); + printf("%s$%02X,$%02X%s; TO %05u\n", asmstring[DFB], buf[0], buf[1], asmstring[TAB], val); + read(fd, buf, 2); val = TO_16(buf); + printf("%s$%02X,$%02X%s; HANDLER %05u\n", asmstring[DFB], buf[0], buf[1], asmstring[TAB], val); + read(fd, buf, 2); val = TO_16(buf); + printf("%s$%02X,$%02X%s; TYPE %d\n", asmstring[DFB], buf[0], buf[1], asmstring[TAB], val); + } + printf("%s CODE ATTRIB\n", asmstring[CMNT]); + read(fd, buf, 2); cnt = TO_16(buf); + printf("%s$%02X,$%02X%s; ATTRIB COUNT %d\n", asmstring[DFB], buf[0], buf[1], asmstring[TAB], cnt); + while (cnt--) + { + read(fd, buf, 2); name = TO_16(buf); + read(fd, buf, 4); len = TO_32(buf); + DumpAttr(fd, name, len, 'C', blknum, cnt); + } + } + else if (name == ConstantAttrName) + { + unsigned short idx; + if (len != 2) + { + fprintf(stderr, "\nError: Bad attribute length for ConstantValue.\n"); + exit(1); + } + read(fd, buf, 2); idx = TO_16(buf); + printf("%s$%02X,$%02X%s; CONST ATTR NAME #%d\n", asmstring[DFB], buf[0], buf[1], asmstring[TAB], idx); + } + else if (name == ExceptAttrName) + { + unsigned short except_cnt, except_idx; + + read(fd, buf, 2); except_cnt = TO_16(buf); + printf("%s$%02X,$%02X%s; EXCEPTIONS COUNT %d\n", asmstring[DFB], buf[0], buf[1], asmstring[TAB], except_cnt); + while (except_cnt--) + { + read(fd, buf, 2); except_idx = TO_16(buf); + printf("%s$%02X,$%02X%s; EXCEPTIONS INDEX %d\n", asmstring[DFB], buf[0], buf[1], asmstring[TAB], except_idx); + } + } + else + { + if (name == InnerClassAttrName) + printf("%s INNER CLASSES: REMOVEABLE\n", asmstring[CMNT]); + else if (name == SyntheticAttrName) + printf("%s SYNTHETIC: REMOVEABLE\n", asmstring[CMNT]); + else if (name == SourceAttrName) + printf("%s SOURCE FILE: REMOVEABLE\n", asmstring[CMNT]); + else if (name == LineNumAttrName) + printf("%s LINE NUMBER TABLE: REMOVEABLE\n", asmstring[CMNT]); + else if (name == LocalVarAttrName) + printf("%s LOCAL VARIABLE TABLE: REMOVEABLE\n", asmstring[CMNT]); + else + while (len > 8) + { + read(fd, buf, 8); + len -= 8; + printf("%s$%02X,$%02X,$%02X,$%02X,$%02X,$%02X,$%02X,$%02X\n", asmstring[DFB], buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7]); + } + if (len) + { + printf("%s", asmstring[DFB]); + while (len--) + { + read(fd, buf, 1); + printf("$%02X", buf[0]); + if (len) + printf(","); + } + printf("\n"); + } + } + printf("%s%s\n", attrend, asmstring[LABL]); +} + +int main(int argc, char **argv) +{ + int cf, fd, cc, ii, cnt, idx; + long long long_val; + float float_val; + double double_val; + unsigned int magic; + unsigned short minor_version; + unsigned short major_version; + unsigned short const_pool_count, iface_count, fields_count, methods_count, attribs_count; + unsigned short access_flags; + unsigned short this_class, super_class; + + if (argc < 3) + { + fprintf(stderr, "Usage: %s [classfile2] ...\n", argv[0]); + return (1); + } + if (*argv[1] == 'p' || *argv[1] == 'P') + asmstring = merlinstr; + if (*argv[1] == 'c' || *argv[1] == 'C') + asmstring = as65str; + if (!asmstring) + { + fprintf(stderr, "Must select

rodos or a65 output format\n"); + return (1); + } + for (cf = 2; cf < argc; cf++) + { + if ((fd = open(argv[cf], O_RDONLY, 0)) > 0) + { + printf("%s\n%s CLASS FILE %s\n%s\n", asmstring[CMNT], asmstring[CMNT], argv[cf], asmstring[CMNT]); + printf("%s$1000%s; DUMMY ADDRESS\n", asmstring[ORG], asmstring[TAB]); + read(fd, buf, 4); // magic = TO_32(buf); + printf("%s$%02X,$%02X,$%02X,$%02X%s; MAGIC\n", asmstring[DFB], buf[0],buf[1],buf[2],buf[3], asmstring[TAB]); + read(fd, buf, 2); minor_version = TO_16(buf); + printf("%s$%02X,$%02X%s; MINOR %d\n", asmstring[DFB], buf[0],buf[1], asmstring[TAB], minor_version); + read(fd, buf, 2); major_version = TO_16(buf); + printf("%s$%02X,$%02X%s; MAJOR %d\n", asmstring[DFB], buf[0],buf[1], asmstring[TAB], major_version); + read(fd, buf, 2); const_pool_count = TO_16(buf); + printf("%s\n%s CONSTANT POOL\n%s\n", asmstring[CMNT], asmstring[CMNT], asmstring[CMNT]); + printf("%s$%02X,$%02X%s; CONST POOL COUNT %d\n", asmstring[DFB], buf[0],buf[1], asmstring[TAB], const_pool_count); + for (cc = 1; cc < const_pool_count; cc++) + { + printf("%s CONST POOL INDEX %d\n", asmstring[CMNT], cc); + read(fd, buf, 1); + switch (buf[0]) + { + case 0: // BAD + printf("Bad tag 0"); + read(fd, buf, 1); + exit(1); + break; + case 1: // CONSTANT_Utf8 + printf("%s$01%s; UTF8\n", asmstring[DFB], asmstring[TAB]); + read(fd, buf, 2); idx = TO_16(buf); + printf("%s$%02X,$%02X%s; STRLEN\n", asmstring[DFB], buf[0],buf[1], asmstring[TAB]); + read(fd, buf, idx); + buf[idx] = '\0'; + printf("%s%s%s%s\n", asmstring[ASC], asmstring[QUOT], buf, asmstring[QUOT]); + if (strcmp(buf, "Code") == 0) + CodeAttrName = cc; + else if (strcmp(buf, "ConstantValue") == 0) + ConstantAttrName = cc; + else if (strcmp(buf, "Exceptions") == 0) + ExceptAttrName = cc; + else if (strcmp(buf, "InnerClasses") == 0) + InnerClassAttrName = cc; + else if (strcmp(buf, "Synthetic") == 0) + SyntheticAttrName = cc; + else if (strcmp(buf, "SourceFile") == 0) + SourceAttrName = cc; + else if (strcmp(buf, "LineNumberTable") == 0) + LineNumAttrName = cc; + else if (strcmp(buf, "LocalVariableTable") == 0) + LocalVarAttrName = cc; + break; + case 3: // CONSTANT_Integer + printf("%s$03%s; INT\n", asmstring[DFB], asmstring[TAB]); + read(fd, buf, 4); idx = TO_32(buf); + printf("%s$%02X,$%02X,$%02X,$%02X%s; %d\n", asmstring[DFB], buf[0],buf[1],buf[2],buf[3], asmstring[TAB], idx); + break; + case 4: // CONSTANT_Float + printf("%s$04%s; FLOAT\n", asmstring[DFB], asmstring[TAB]); + read(fd, buf, 4); idx = TO_32(buf); + float_val = *(float *)(&idx); + printf("%s$%02X,$%02X,$%02X,$%02X%s; %f\n", asmstring[DFB], buf[0],buf[1],buf[2],buf[3], asmstring[TAB], float_val); + break; + case 5: // CONSTANT_Long + printf("%s$05%s; LONG\n", asmstring[DFB], asmstring[TAB]); + read(fd, buf, 8); + printf("%s$%02X,$%02X,$%02X,$%02X,$%02X,$%02X,$%02X,$%02X\n", asmstring[DFB], buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7]); + break; + case 6: // CONSTANT_Double + printf("%s$06%s; DOUBLE\n", asmstring[DFB], asmstring[TAB]); + printf("Double: "); + read(fd, buf, 8); + printf("%s$%02X,$%02X,$%02X,$%02X,$%02X,$%02X,$%02X,$%02Xn", asmstring[DFB], buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7]); + break; + case 7: // CONSTANT_Class + printf("%s07%s; CLASS\n", asmstring[DFB], asmstring[TAB]); + read(fd, buf, 2); idx = TO_16(buf); + printf("%s$%02X,$%02X%s; #%d\n", asmstring[DFB], buf[0],buf[1], asmstring[TAB], idx); + break; + case 8: // CONSTANT_String + printf("%s$08%s; STRING\n", asmstring[DFB], asmstring[TAB]); + read(fd, buf, 2); idx = TO_16(buf); + printf("%s$%02X,$%02X%s; #%d\n", asmstring[DFB], buf[0],buf[1], asmstring[TAB], idx); + break; + case 9: // CONSTANT_Fieldref + printf("%s$09%s; FIELDREF\n", asmstring[DFB], asmstring[TAB]); + read(fd, buf, 2); idx = TO_16(buf); + printf("%s$%02X,$%02X%s; CLASS #%d\n", asmstring[DFB], buf[0],buf[1], asmstring[TAB], idx); + read(fd, buf, 2); idx = TO_16(buf); + printf("%s$%02X,$%02X%s; NAME AND TYPE #%d\n", asmstring[DFB], buf[0],buf[1], asmstring[TAB], idx); + break; + case 10: // CONSTANT_Methodref + printf("%s$0A%s; METHODREF\n", asmstring[DFB], asmstring[TAB]); + read(fd, buf, 2); idx = TO_16(buf); + printf("%s$%02X,$%02X%s; CLASS #%d\n", asmstring[DFB], buf[0],buf[1], asmstring[TAB], idx); + read(fd, buf, 2); idx = TO_16(buf); + printf("%s$%02X,$%02X%s; NAME AND TYPE #%d\n", asmstring[DFB], buf[0],buf[1], asmstring[TAB], idx); + break; + case 11: // CONSTANT_InterfaceMethodref + printf("%s$0B%s; IFACE METHODREF\n", asmstring[DFB], asmstring[TAB]); + read(fd, buf, 2); idx = TO_16(buf); + printf("%s$%02X,$%02X%s; CLASS #%d\n", asmstring[DFB], buf[0],buf[1], asmstring[TAB], idx); + read(fd, buf, 2); idx = TO_16(buf); + printf("%s$%02X,$%02X%s; NAME AND TYPE #%d\n", asmstring[DFB], buf[0],buf[1], asmstring[TAB], idx); + break; + case 12: // CONSTANT_NameAndType + printf("%s$0C%s; NAME AND TYPE\n", asmstring[DFB], asmstring[TAB]); + read(fd, buf, 2); idx = TO_16(buf); + printf("%s$%02X,$%02X%s; NAME #%d\n", asmstring[DFB], buf[0],buf[1], asmstring[TAB], idx); + read(fd, buf, 2); idx = TO_16(buf); + printf("%s$%02X,$%02X%s; DESC #%d\n", asmstring[DFB], buf[0],buf[1], asmstring[TAB], idx); + break; + default: + printf("Bad tag %d", buf[0]); + read(fd, buf, 1); + break; + } + } + read(fd, buf, 2); access_flags = TO_16(buf); + printf("%s\n%s ACCESS FLAGS\n%s\n%s$%02X,$%02X%s; 0x%04X\n", asmstring[CMNT], asmstring[CMNT], asmstring[CMNT], asmstring[DFB], buf[0],buf[1], asmstring[TAB], access_flags); + read(fd, buf, 2); this_class = TO_16(buf); + printf("%s\n%s THIS CLASS\n%s\n%s$%02X,$%02X%s; #%d\n", asmstring[CMNT], asmstring[CMNT], asmstring[CMNT], asmstring[DFB], buf[0],buf[1], asmstring[TAB], this_class); + read(fd, buf, 2); super_class = TO_16(buf); + printf("%s\n%s SUPER CLASS\n%s\n%s$%02X,$%02X%s; #%d\n", asmstring[CMNT], asmstring[CMNT], asmstring[CMNT], asmstring[DFB], buf[0],buf[1], asmstring[TAB], super_class); + read(fd, buf, 2); iface_count = TO_16(buf); + printf("%s\n%s INTERFACES\n%s\n", asmstring[CMNT], asmstring[CMNT], asmstring[CMNT]); + printf("%s$%02X,$%02X%s; IFACE COUNT %d\n", asmstring[DFB], buf[0],buf[1], asmstring[TAB], iface_count); + for (cc = 0; cc < iface_count; cc++) + { + read(fd, buf, 2); idx = TO_16(buf); + printf("%s$%02X,$%02X%s; #%d\n", asmstring[DFB], buf[0],buf[1], asmstring[TAB], idx); + } + read(fd, buf, 2); fields_count = TO_16(buf); + printf("%s\n%s FIELDS\n%s\n", asmstring[CMNT], asmstring[CMNT], asmstring[CMNT]); + printf("%s$%02X,$%02X%s; FIELD COUNT %d\n", asmstring[DFB], buf[0],buf[1], asmstring[TAB], fields_count); + for (cc = 0; cc < fields_count; cc++) + { + printf("%s****** FIELD INDEX %d ********\n", asmstring[CMNT], cc); + read(fd, buf, 2); idx = TO_16(buf); + printf("%s$%02X,$%02X%s; ACCESS FLAGS 0x%04X\n", asmstring[DFB], buf[0],buf[1], asmstring[TAB], idx); + read(fd, buf, 2); idx = TO_16(buf); + printf("%s$%02X,$%02X%s; NAME #%d\n", asmstring[DFB], buf[0],buf[1], asmstring[TAB], idx); + read(fd, buf, 2); idx = TO_16(buf); + printf("%s$%02X,$%02X%s; DESC #%d\n", asmstring[DFB], buf[0],buf[1], asmstring[TAB], idx); + read(fd, buf, 2); cnt = TO_16(buf); + printf("%s$%02X,$%02X%s; ATTRIB COUNT %d\n", asmstring[DFB], buf[0],buf[1], asmstring[TAB], cnt); + for (ii = 0; ii < cnt; ii++) + { + int nm, len; + + printf("%s ATTRIB INDEX %d\n", asmstring[CMNT], ii); + read(fd, buf, 2); nm = TO_16(buf); + read(fd, buf, 4); len = TO_32(buf); + DumpAttr(fd, nm, len, 'F', cc, ii); + } + } + read(fd, buf, 2); methods_count = TO_16(buf); + printf("%s\n%s METHODS\n%s\n", asmstring[CMNT], asmstring[CMNT], asmstring[CMNT]); + printf("%s$%02X,$%02X%s; METHOD COUNT %d\n", asmstring[DFB], buf[0],buf[1], asmstring[TAB], methods_count); + for (cc = 0; cc < methods_count; cc++) + { + printf("%s****** METHOD INDEX %d ********\n", asmstring[CMNT], cc); + read(fd, buf, 2); idx = TO_16(buf); + printf("%s$%02X,$%02X%s; ACCESS FLAGS 0x%04X\n", asmstring[DFB], buf[0],buf[1], asmstring[TAB], idx); + read(fd, buf, 2); idx = TO_16(buf); + printf("%s$%02X,$%02X%s; NAME #%d\n", asmstring[DFB], buf[0],buf[1], asmstring[TAB], idx); + read(fd, buf, 2); idx = TO_16(buf); + printf("%s$%02X,$%02X%s; DESC #%d\n", asmstring[DFB], buf[0],buf[1], asmstring[TAB], idx); + read(fd, buf, 2); cnt = TO_16(buf); + printf("%s$%02X,$%02X%s; ATTRIB COUNT %d\n", asmstring[DFB], buf[0],buf[1], asmstring[TAB], cnt); + for (ii = 0; ii < cnt; ii++) + { + int nm, len; + + printf("%s ATTRIB INDEX %d\n", asmstring[CMNT], ii); + read(fd, buf, 2); nm = TO_16(buf); + read(fd, buf, 4); len = TO_32(buf); + DumpAttr(fd, nm, len, 'M', cc, ii); + } + } + read(fd, buf, 2); attribs_count = TO_16(buf); + printf("%s\n%s GLOBAL ATTRIBUTES\n%s\n", asmstring[CMNT], asmstring[CMNT], asmstring[CMNT]); + printf("%s$%02X,$%02X%s; ATTRIB COUNT %d\n", asmstring[DFB], buf[0],buf[1], asmstring[TAB], attribs_count); + for (cc = 0; cc < attribs_count; cc++) + { + int nm, len; + + printf("%s****** ATTRIB INDEX %d ********\n", asmstring[CMNT], cc); + read(fd, buf, 2); nm = TO_16(buf); + read(fd, buf, 4); len = TO_32(buf); + DumpAttr(fd, nm, len, 'G', cc, ii); + } + close(fd); + } + } + return (0); +} \ No newline at end of file diff --git a/tools/dumpclass.c b/tools/dumpclass.c new file mode 100755 index 0000000..c264eaa --- /dev/null +++ b/tools/dumpclass.c @@ -0,0 +1,533 @@ +#include +#include +#include + +char *opcode[256] = { "nop", "aconst_null", "iconst_m1", "iconst_0", + "iconst_1", "iconst_2", "iconst_3", "iconst_4", + "iconst_5", "lconst_0", "lconst_1", "fconst_0", + "fconst_1", "fconst_2", "dconst_0", "dconst_1", + "bipush", "sipush", "ldc", "ldc_w", + "ldc2_w", "iload", "lload", "fload", + "dload", "aload", "iload_0", "iload_1", + "iload_2", "iload_3", "lload_0", "lload_1", + "lload_2", "lload_3", "fload_0", "fload_1", + "fload_2", "fload_3", "dload_0", "dload_1", + "dload_2", "dload_3", "aload_0", "aload_1", + "aload_2", "aload_3", "iaload", "laload", + "faload", "daload", "aaload", "baload", + "caload", "saload", "istore", "lstore", + "fstore", "dstore", "astore", "istore_0", + "istore_1", "istore_2", "istore_3", "lstore_0", + "lstore_1", "lstore_2", "lstore_3", "fstore_0", + "fstore_1", "fstore_2", "fstore_3", "dstore_0", + "dstore_1", "dstore_2", "dstore_3", "astore_0", + "astore_1", "astore_2", "astore_3", "iastore", + "lastore", "fastore", "dastore", "aastore", + "bastore", "castore", "sastore", "pop", + "pop2", "dup", "dup_x1", "dup_x2", + "dup2", "dup2_x1", "dup2_x2", "swap", + "iadd", "ladd", "fadd", "dadd", + "isub", "lsub", "fsub", "dsub", + "imul", "lmul", "fmul", "dmul", + "idiv", "ldiv", "fdiv", "ddiv", + "irem", "lrem", "frem", "drem", + "ineg", "lneg", "fneg", "dneg", + "ishl", "lshl", "ishr", "lshr", + "iushr", "lushr", "iand", "land", + "ior", "lor", "ixor", "lxor", + "iinc", "i2l", "i2f", "i2d", + "l2i", "l2f", "l2d", "f2i", + "f2l", "f2d", "d2i", "d2l", + "d2f", "i2b", "i2c", "i2s", + "lcmp", "fcmpl", "fcmpg", "dcmpl", + "dcmpg", "ifeq", "ifne", "iflt", + "ifge", "ifgt", "ifle", "if_icmpeq", + "if_icmpne", "if_icmplt", "if_icmpge", "if_icmpgt", + "if_icmple", "if_acmpeq", "if_acmpne", "goto", + "jsr", "ret", "tableswitch", "lookupswitch", + "ireturn", "lreturn", "freturn", "dreturn", + "areturn", "return", "getstatic", "putstatic", + "getfield", "putfield", "invokevirtual", "invokespecial", + "invokestatic", "invokeinterface", "xxx_unused_xxx", "new", + "newarray", "anewarray", "arraylength", "athrow", + "checkcast", "instanceof", "monitorenter", "monitorexit", + "wide", "multianewarray", "ifnull", "ifnonnull", + "goto_w", "jsr_w", "breakpoint", "XXX", + "XXX","XXX", "XXX", "XXX", + "XXX","XXX", "XXX", "XXX", "XXX", "XXX", "XXX", "XXX", + "XXX","XXX", "XXX", "XXX", "XXX", "XXX", "XXX", "XXX", + "XXX","XXX", "XXX", "XXX", "XXX", "XXX", "XXX", "XXX", + "XXX","XXX", "XXX", "XXX", "XXX", "XXX", "XXX", "XXX", + "XXX","XXX", "XXX", "XXX", "XXX", "XXX", "XXX", "XXX", + "XXX","XXX", "XXX", "XXX", "XXX", "XXX", "impdep1", "impdep2" + }; +char *atype[] = { "???", "???", "???", "???", + "T_BOOLEAN", "T_CHAR", "T_FLOAT", "T_DOUBLE", + "T_BYTE", "T_SHORT", "T_INT", "T_LONG" + }; + +#define TO_32(b) ((b[0]<<24)|(b[1]<<16)|(b[2]<<8)|(b[3])) +#define TO_16(b) ((b[0]<<8)|(b[1])) + +int CodeAttrName, ConstantAttrName, ExceptAttrName, InnerClassAttrName, + SyntheticAttrName, SourceAttrName, LineNumAttrName, LocalVarAttrName; +unsigned char buf[256]; + +void DumpAttr(int fd, int name, int len) +{ + if (name == CodeAttrName) + { + unsigned short max_stack, max_locals, cnt, val; + signed short sval; + int ival, defval, lval, hval, pad; + unsigned long code_len, pc; + printf("Code:"); + read(fd, buf, 2); max_stack = TO_16(buf); + printf(" max_stack %d", max_stack); + read(fd, buf, 2); max_locals = TO_16(buf); + printf(" max_locals %d", max_locals); + read(fd, buf, 4); code_len = TO_32(buf); + printf(" code_len %u\n", code_len); + for (pc = 0; pc < code_len; pc++) + { + read(fd, buf, 1); + printf("\t\t\t\t%06u[0x%04X]: %s", pc, pc, opcode[buf[0]]); + switch (buf[0]) + { + case 0x19: // local var index8 + case 0x3A: + case 0x18: + case 0x39: + case 0x17: + case 0x38: + case 0x84: + case 0x15: + case 0x36: + case 0x16: + case 0x37: + case 0xA9: + read(fd, buf+1, 1); + printf(" %u", buf[1]); + if (buf[0] == 0x84) // , const + { + read(fd, buf, 1); + printf(" %d", (signed char)buf[0]); + pc++; + } + pc++; + break; + case 0xC4: // wide local var index16 + read(fd, buf, 1); + if (buf[0] == 0x84) + { + read(fd, buf, 2); val = TO_16(buf); + printf(" iinc %u", val); + read(fd, buf, 2); val = TO_16(buf); + printf(" %d", val); + pc += 5; + } + else + { + printf(" %s", opcode[buf[0]]); + read(fd, buf, 2); val = TO_16(buf); + printf(" %u", val); + pc += 3; + } + break; + case 0x12: // class const pool index8 + read(fd, buf+1, 1); + printf(" #%u", buf[1]); + pc++; + break; + case 0xBD: // class const pool index16 + case 0xC0: + case 0xB4: + case 0xB2: + case 0xC1: + case 0xB7: + case 0xB8: + case 0xB6: + case 0x13: + case 0x14: + case 0xBB: + case 0xB5: + case 0xB3: + case 0xB9: + case 0xC5: + buf[2] = buf[0]; + read(fd, buf, 2); val = TO_16(buf); + printf(" #%u", val); + if (buf[2] == 0xC5) // , dimensions + { + read(fd, buf, 1); + printf(" %d", buf[0]); + pc++; + } + if (buf[2] == 0xB9) // , count, 0 + { + read(fd, buf, 2); + printf(" %d", buf[0]); + pc += 2; + } + pc += 2; + break; + case 0x10: // byte + read(fd, buf, 1); + printf(" %d", buf[0]); + pc++; + break; + case 0xBC: // atype + read(fd, buf, 1); + printf(" %d (%s)", buf[0], atype[buf[0]]); + pc++; + break; + case 0x11: // short + read(fd, buf, 2); val = TO_16(buf); + printf(" %d", val); + pc += 2; + break; + case 0xA7: // branch16 + case 0xA5: + case 0xA6: + case 0x9F: + case 0xA0: + case 0xA1: + case 0xA2: + case 0xA3: + case 0xA4: + case 0x99: + case 0x9A: + case 0x9B: + case 0x9C: + case 0x9D: + case 0x9E: + case 0xC7: + case 0xC6: + case 0xA8: + read(fd, buf, 2); sval = TO_16(buf); + printf(" %+d (%06u)", sval, pc + sval); + pc += 2; + break; + case 0xC9: // branch32 + case 0xC8: + read(fd, buf, 4); ival = TO_32(buf); + printf(" %+d (%06u)", ival, pc + ival); + pc += 4; + break; + case 0xAB: // lookupswitch + pad = ((pc + 1) & 0x03); + if (pad) + { + pad = 4 - pad; + read(fd, buf, pad); // padding + } + read(fd, buf, 4); defval = TO_32(buf); // default + read(fd, buf, 4); hval = TO_32(buf); // num pairs + printf(" %d:\n", hval); + for (cnt = 0; cnt < hval; cnt++) + { + read(fd, buf, 4); ival = TO_32(buf); // match + read(fd, buf, 4); lval = TO_32(buf); // offsets + printf("\t\t\t\t\t%d: %+d (%06u)\n", ival, lval, pc + lval); + } + printf("\t\t\t\t\tdefault: %+d (%06u)", defval, pc + defval); + pc += pad + 8 + 8 * hval; + break; + case 0xAA: // tableswitch + pad = ((pc + 1) & 0x03); + if (pad) + { + pad = 4 - pad; + read(fd, buf, pad); // padding + } + read(fd, buf, 4); defval = TO_32(buf); // default + read(fd, buf, 4); lval = TO_32(buf); // low value + read(fd, buf, 4); hval = TO_32(buf); // high value + printf(" %d to %d:\n", lval, hval); + for (cnt = lval; cnt <= hval; cnt++) + { + read(fd, buf, 4); ival = TO_32(buf); // offsets + printf("\t\t\t\t\t%d: %+d (%06u)\n", cnt, ival, pc + ival); + } + printf("\t\t\t\t\tdefault: %+d (%06u)", defval, pc + defval); + pc += pad + 12 + 4 * (hval - lval + 1); + break; + } + printf("\n"); + } + read(fd, buf, 2); cnt = TO_16(buf); + printf("\t\t\texcept_len: %d\n", cnt); + while (cnt--) + { + read(fd, buf, 2); val = TO_16(buf); + printf("\t\t\t\tfrom %06u", val); + read(fd, buf, 2); val = TO_16(buf); + printf(" to %06u", val); + read(fd, buf, 2); val = TO_16(buf); + printf(" handler %06u", val); + read(fd, buf, 2); val = TO_16(buf); + printf(" type %d\n", val); + } + read(fd, buf, 2); cnt = TO_16(buf); + while (cnt--) + { + read(fd, buf, 2); name = TO_16(buf); + read(fd, buf, 4); len = TO_32(buf); + printf("\t\t\tcode_attr: "); + DumpAttr(fd, name, len); + } + } + else if (name == ConstantAttrName) + { + unsigned short idx; + if (len != 2) + { + fprintf(stderr, "\nError: Bad attribute length for ConstantValue.\n"); + exit(1); + } + read(fd, buf, 2); idx = TO_16(buf); + printf("ConstantValue: #%d\n", idx); + } + else if (name == ExceptAttrName) + { + unsigned short except_cnt, except_idx; + + read(fd, buf, 2); except_cnt = TO_16(buf); + printf("Exceptions count: %d\n", except_cnt); + while (except_cnt--) + { + read(fd, buf, 2); except_idx = TO_16(buf); + printf("\t\t\t\t# %d\n", except_idx); + } + } + else + { + if (name == InnerClassAttrName) + printf("InnerClasses: "); + else if (name == SyntheticAttrName) + printf("Synthetic: "); + else if (name == SourceAttrName) + printf("SourceFile: "); + else if (name == LineNumAttrName) + printf("LineNumberTable: "); + else if (name == LocalVarAttrName) + printf("LocalVariableTable: "); + else + printf("name #%d ", name); + printf("len %d\n", len); + while (len > 256) + { + read(fd, buf, 256); + len -= 256; + } + if (len) + read(fd, buf, len); + } +} + +int main(int argc, char **argv) +{ + int cf, fd, cc, ii, cnt, idx; + long long long_val; + float float_val; + double double_val; + unsigned int magic; + unsigned short minor_version; + unsigned short major_version; + unsigned short const_pool_count, iface_count, fields_count, methods_count, attribs_count; + unsigned short access_flags; + unsigned short this_class, super_class; + + if (argc < 2) + { + printf("Usage: %s [classfile2] ...\n", argv[0]); + return (1); + } + for (cf = 1; cf < argc; cf++) + { + if ((fd = open(argv[cf], O_RDONLY, 0)) > 0) + { + printf("Class file: %s\n", argv[cf]); + read(fd, buf, 4); magic = TO_32(buf); + printf("\tmagic: 0x%08X\n", magic); + read(fd, buf, 2); minor_version = TO_16(buf); + read(fd, buf, 2); major_version = TO_16(buf); + printf("\tmajor.minor: %d.%d\n", major_version, minor_version); + read(fd, buf, 2); const_pool_count = TO_16(buf); + printf("\tconst_pool_count: %d\n", const_pool_count); + for (cc = 1; cc < const_pool_count; cc++) + { + printf("\t\t[%02d] ", cc); + read(fd, buf, 1); + switch (buf[0]) + { + case 0: // BAD + printf("Bad tag 0"); + read(fd, buf, 1); + break; + case 1: // CONSTANT_Utf8 + printf("Utf8: "); + read(fd, buf, 2); idx = TO_16(buf); + read(fd, buf, idx); + buf[idx] = '\0'; + printf("%s", buf); + if (strcmp(buf, "Code") == 0) + CodeAttrName = cc; + else if (strcmp(buf, "ConstantValue") == 0) + ConstantAttrName = cc; + else if (strcmp(buf, "Exceptions") == 0) + ExceptAttrName = cc; + else if (strcmp(buf, "InnerClasses") == 0) + InnerClassAttrName = cc; + else if (strcmp(buf, "Synthetic") == 0) + SyntheticAttrName = cc; + else if (strcmp(buf, "SourceFile") == 0) + SourceAttrName = cc; + else if (strcmp(buf, "LineNumberTable") == 0) + LineNumAttrName = cc; + else if (strcmp(buf, "LocalVariableTable") == 0) + LocalVarAttrName = cc; + break; + case 3: // CONSTANT_Integer + printf("Integer: "); + read(fd, buf, 4); idx = TO_32(buf); + printf("%d", idx); + break; + case 4: // CONSTANT_Float + printf("Float: "); + read(fd, buf, 4); idx = TO_32(buf); + float_val = *(float *)(&idx); + printf("%f", float_val); + break; + case 5: // CONSTANT_Long + printf("Long: "); + read(fd, buf, 8); idx = TO_32((buf+4)); + printf("%d", idx); + cc++; + break; + case 6: // CONSTANT_Double + printf("Double: "); + read(fd, buf, 8); + cc++; + break; + case 7: // CONSTANT_Class + printf("Class: "); + read(fd, buf, 2); idx = TO_16(buf); + printf("#%d", idx); + break; + case 8: // CONSTANT_String + printf("String: "); + read(fd, buf, 2); idx = TO_16(buf); + printf("#%d", idx); + break; + case 9: // CONSTANT_Fieldref + printf("Fieldref: "); + read(fd, buf, 2); idx = TO_16(buf); + printf("class #%d", idx); + read(fd, buf, 2); idx = TO_16(buf); + printf(" name_type #%d", idx); + break; + case 10: // CONSTANT_Methodref + printf("Methodref: "); + read(fd, buf, 2); idx = TO_16(buf); + printf("class #%d", idx); + read(fd, buf, 2); idx = TO_16(buf); + printf(" name_type #%d", idx); + break; + case 11: // CONSTANT_InterfaceMethodref + printf("InterfaceMethodref: "); + read(fd, buf, 2); idx = TO_16(buf); + printf("class #%d", idx); + read(fd, buf, 2); idx = TO_16(buf); + printf(" name_type #%d", idx); + break; + case 12: // CONSTANT_NameAndType + printf("NameAndType: "); + read(fd, buf, 2); idx = TO_16(buf); + printf("name #%d", idx); + read(fd, buf, 2); idx = TO_16(buf); + printf(" desc #%d", idx); + break; + default: + printf("Bad tag %d", buf[0]); + read(fd, buf, 1); + break; + } + printf("\n"); + } + read(fd, buf, 2); access_flags = TO_16(buf); + printf("\taccess_flags: 0x%04X\n", access_flags); + read(fd, buf, 2); this_class = TO_16(buf); + printf("\tthis_class: %d\n", this_class); + read(fd, buf, 2); super_class = TO_16(buf); + printf("\tsuper_class: %d\n", super_class); + read(fd, buf, 2); iface_count = TO_16(buf); + printf("\tinterfaces_count: %d\n", iface_count); + for (cc = 0; cc < iface_count; cc++) + { + printf("\t\t[%02d] ", cc); + read(fd, buf, 2); idx = TO_16(buf); + printf("#%d\n", idx); + } + read(fd, buf, 2); fields_count = TO_16(buf); + printf("\tfields_count: %d\n", fields_count); + for (cc = 0; cc < fields_count; cc++) + { + printf("\t\t[%02d] ", cc); + read(fd, buf, 2); idx = TO_16(buf); + printf("access 0x%02X ", idx); + read(fd, buf, 2); idx = TO_16(buf); + printf("name #%d ", idx); + read(fd, buf, 2); idx = TO_16(buf); + printf("desc #%d ", idx); + read(fd, buf, 2); cnt = TO_16(buf); + printf("attr_cnt %d\n", cnt); + for (ii = 0; ii < cnt; ii++) + { + int nm, len; + + printf("\t\t\t[%02d] ", ii); + read(fd, buf, 2); nm = TO_16(buf); + read(fd, buf, 4); len = TO_32(buf); + DumpAttr(fd, nm, len); + } + } + read(fd, buf, 2); methods_count = TO_16(buf); + printf("\tmethods_count: %d\n", methods_count); + for (cc = 0; cc < methods_count; cc++) + { + printf("\t\t[%02d] ", cc); + read(fd, buf, 2); idx = TO_16(buf); + printf("access 0x%02X ", idx); + read(fd, buf, 2); idx = TO_16(buf); + printf("name #%d ", idx); + read(fd, buf, 2); idx = TO_16(buf); + printf("desc #%d ", idx); + read(fd, buf, 2); cnt = TO_16(buf); + printf("attr_cnt %d\n", cnt); + for (ii = 0; ii < cnt; ii++) + { + int nm, len; + + printf("\t\t\t[%02d] ", ii); + read(fd, buf, 2); nm = TO_16(buf); + read(fd, buf, 4); len = TO_32(buf); + DumpAttr(fd, nm, len); + } + } + read(fd, buf, 2); attribs_count = TO_16(buf); + printf("\tattributes_count: %d\n", attribs_count); + for (cc = 0; cc < attribs_count; cc++) + { + int nm, len; + + printf("\t\t[%02d] ", cc); + read(fd, buf, 2); nm = TO_16(buf); + read(fd, buf, 4); len = TO_32(buf); + DumpAttr(fd, nm, len); + } + close(fd); + } + } + return (0); +}