Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.sys.apple2.programmer > #4109 > unrolled thread

PLASMA Developer Preview 1.0 Available:

Started byDavid Schmenk <dschmenk@gmail.com>
First post2018-01-17 06:57 -0800
Last post2018-01-26 14:49 -0800
Articles 20 on this page of 31 — 9 participants

Back to article view | Back to comp.sys.apple2.programmer


Contents

  PLASMA Developer Preview 1.0 Available: David Schmenk <dschmenk@gmail.com> - 2018-01-17 06:57 -0800
    Re: PLASMA Developer Preview 1.0 Available: D Finnigan <dog_cow@macgui.com> - 2018-01-17 20:27 +0000
      Re: PLASMA Developer Preview 1.0 Available: Anthony Ortiz <anthonypaulo@gmail.com> - 2018-01-17 12:33 -0800
        Re: PLASMA Developer Preview 1.0 Available: Anthony Ortiz <anthonypaulo@gmail.com> - 2018-01-17 12:38 -0800
          Re: PLASMA Developer Preview 1.0 Available: David Schmenk <dschmenk@gmail.com> - 2018-01-17 14:33 -0800
    Re: PLASMA Developer Preview 1.0 Available: cbmeeks <cbmeeks@gmail.com> - 2018-01-17 13:14 -0800
      Re: PLASMA Developer Preview 1.0 Available: ol.sc@web.de (Oliver Schmidt) - 2018-01-17 22:29 +0000
    Re: PLASMA Developer Preview 1.0 Available: John Brooks <jbrooks@blueshiftinc.com> - 2018-01-18 02:57 -0800
      Re: PLASMA Developer Preview 1.0 Available: David Schmenk <dschmenk@gmail.com> - 2018-01-18 11:12 -0800
        Re: PLASMA Developer Preview 1.0 Available: John Brooks <jbrooks@blueshiftinc.com> - 2018-01-18 12:02 -0800
          Re: PLASMA Developer Preview 1.0 Available: David Schmenk <dschmenk@gmail.com> - 2018-01-18 13:07 -0800
            Re: PLASMA Developer Preview 1.0 Available: John Brooks <jbrooks@blueshiftinc.com> - 2018-01-18 14:21 -0800
              Re: PLASMA Developer Preview 1.0 Available: David Schmenk <dschmenk@gmail.com> - 2018-01-18 16:49 -0800
                Re: PLASMA Developer Preview 1.0 Available: John Brooks <jbrooks@blueshiftinc.com> - 2018-01-18 21:40 -0800
                  Re: PLASMA Developer Preview 1.0 Available: David Schmenk <dschmenk@gmail.com> - 2018-01-19 09:06 -0800
                    Re: PLASMA Developer Preview 1.0 Available: John Brooks <jbrooks@blueshiftinc.com> - 2018-01-19 10:03 -0800
                      Re: PLASMA Developer Preview 1.0 Available: David Schmenk <dschmenk@gmail.com> - 2018-01-19 13:24 -0800
                Re: PLASMA Developer Preview 1.0 Available: martin_haye <martin.haye@gmail.com> - 2018-01-21 11:24 -0800
                  Re: PLASMA Developer Preview 1.0 Available: David Schmenk <dschmenk@gmail.com> - 2018-01-21 11:44 -0800
                    Re: PLASMA Developer Preview 1.0 Available: David Schmenk <dschmenk@gmail.com> - 2018-01-21 11:47 -0800
                      Re: PLASMA Developer Preview 1.0 Available: John Brooks <jbrooks@blueshiftinc.com> - 2018-01-21 23:00 -0800
                        Re: PLASMA Developer Preview 1.0 Available: Steve Nickolas <usotsuki@buric.co> - 2018-01-22 05:06 -0500
                        Re: PLASMA Developer Preview 1.0 Available: David Schmenk <dschmenk@gmail.com> - 2018-01-22 06:48 -0800
          Re: PLASMA Developer Preview 1.0 Available: Anthony Ortiz <anthonypaulo@gmail.com> - 2018-01-18 14:05 -0800
    Re: PLASMA Developer Preview 1.0 Available: mmphosis <mmphosis@macgui.com> - 2018-01-18 18:21 +0000
    Re: PLASMA Developer Preview 1.0 Available: David Schmenk <dschmenk@gmail.com> - 2018-01-20 17:02 -0800
      Re: PLASMA Developer Preview 1.0 Available: John Brooks <jbrooks@blueshiftinc.com> - 2018-01-20 19:03 -0800
        Re: PLASMA Developer Preview 1.0 Available: David Schmenk <dschmenk@gmail.com> - 2018-01-21 11:04 -0800
        Re: PLASMA Developer Preview 1.0 Available: David Schmenk <dschmenk@gmail.com> - 2018-01-21 11:06 -0800
    Re: PLASMA Developer Preview 1.0 Available: David Schmenk <dschmenk@gmail.com> - 2018-01-24 20:48 -0800
    Re: PLASMA Developer Preview 1.0 Available: David Schmenk <dschmenk@gmail.com> - 2018-01-26 14:49 -0800

Page 1 of 2  [1] 2  Next page →


#4109 — PLASMA Developer Preview 1.0 Available:

FromDavid Schmenk <dschmenk@gmail.com>
Date2018-01-17 06:57 -0800
SubjectPLASMA Developer Preview 1.0 Available:
Message-ID<cca37d02-a9d5-43eb-bfe9-012d6b0e1ad9@googlegroups.com>
Modern Retroprogramming on the Apple II. When was the last time you programmed a modern language on a 40 year old computer? Now is your chance. PLASMA is a combination of operating environment, virtual machine, and assembler/compiler matched closely to the 6502 architecture. Check out the Release Notes for details: https://github.com/dschmenk/PLASMA/blob/master/doc/Preview%20Version%201.0.md

[toc] | [next] | [standalone]


#4110

FromD Finnigan <dog_cow@macgui.com>
Date2018-01-17 20:27 +0000
Message-ID<dog_cow-1516220861@macgui.com>
In reply to#4109
David Schmenk wrote:
> Modern Retroprogramming on the Apple II. When was the last time you
> programmed a modern language on a 40 year old computer?

About 5 years ago when someone named Dave Schmenk made a Java VM for the
Apple II. ;-P


-- 
]DF$
Apple II 40th Anniversary User's Guide:
http://macgui.com/newa2guide/

[toc] | [prev] | [next] | [standalone]


#4111

FromAnthony Ortiz <anthonypaulo@gmail.com>
Date2018-01-17 12:33 -0800
Message-ID<78551657-895f-4cb2-aca0-7bd353e09291@googlegroups.com>
In reply to#4110
On Wednesday, January 17, 2018 at 3:27:45 PM UTC-5, D Finnigan wrote:
> David Schmenk wrote:
> > Modern Retroprogramming on the Apple II. When was the last time you
> > programmed a modern language on a 40 year old computer?
> 
> About 5 years ago when someone named Dave Schmenk made a Java VM for the
> Apple II. ;-P
> 
> 
> -- 
> ]DF$
> Apple II 40th Anniversary User's Guide:
> http://macgui.com/newa2guide/

There's a Java VM for the Apple II?

[toc] | [prev] | [next] | [standalone]


#4112

FromAnthony Ortiz <anthonypaulo@gmail.com>
Date2018-01-17 12:38 -0800
Message-ID<b78e20d8-5579-4b5f-9701-e3fc82dc011c@googlegroups.com>
In reply to#4111
On Wednesday, January 17, 2018 at 3:33:55 PM UTC-5, Anthony Ortiz wrote:
> On Wednesday, January 17, 2018 at 3:27:45 PM UTC-5, D Finnigan wrote:
> > David Schmenk wrote:
> > > Modern Retroprogramming on the Apple II. When was the last time you
> > > programmed a modern language on a 40 year old computer?
> > 
> > About 5 years ago when someone named Dave Schmenk made a Java VM for the
> > Apple II. ;-P
> > 
> > 
> > -- 
> > ]DF$
> > Apple II 40th Anniversary User's Guide:
> > http://macgui.com/newa2guide/
> 
> There's a Java VM for the Apple II?

Oh man... David, you're a manimal! This VM02... any chance you'll host it on GitHub instead of SourceForge?

[toc] | [prev] | [next] | [standalone]


#4115

FromDavid Schmenk <dschmenk@gmail.com>
Date2018-01-17 14:33 -0800
Message-ID<9eae85a0-da1b-4782-91c1-1ef405404e99@googlegroups.com>
In reply to#4112
On Wednesday, January 17, 2018 at 12:38:32 PM UTC-8, Anthony Ortiz wrote:
> On Wednesday, January 17, 2018 at 3:33:55 PM UTC-5, Anthony Ortiz wrote:
> > On Wednesday, January 17, 2018 at 3:27:45 PM UTC-5, D Finnigan wrote:
> > > David Schmenk wrote:
> > > > Modern Retroprogramming on the Apple II. When was the last time you
> > > > programmed a modern language on a 40 year old computer?
> > > 
> > > About 5 years ago when someone named Dave Schmenk made a Java VM for the
> > > Apple II. ;-P
> > > 
> > > 
> > > -- 
> > > ]DF$
> > > Apple II 40th Anniversary User's Guide:
> > > http://macgui.com/newa2guide/
> > 
> > There's a Java VM for the Apple II?
> 
> Oh man... David, you're a manimal! This VM02... any chance you'll host it on GitHub instead of SourceForge?

Anthony- VM02 hasn't been actively worked on in over 10 years, and I don't plan on spending any more time on it. Sourceforge is basically archival storage as far as I'm concerned. Although it was an interesting exercise, it really didn't make any sense for an Apple II because the Java compiler built too big of a binary. PLASMA is the right answer for a small, 1 MHz, 8 bit computer.

[toc] | [prev] | [next] | [standalone]


#4113

Fromcbmeeks <cbmeeks@gmail.com>
Date2018-01-17 13:14 -0800
Message-ID<3d439570-6482-44eb-8822-6cd359a52f79@googlegroups.com>
In reply to#4109
On Wednesday, January 17, 2018 at 9:57:55 AM UTC-5, David Schmenk wrote:
> Modern Retroprogramming on the Apple II. When was the last time you programmed a modern language on a 40 year old computer? Now is your chance. PLASMA is a combination of operating environment, virtual machine, and assembler/compiler matched closely to the 6502 architecture. Check out the Release Notes for details: https://github.com/dschmenk/PLASMA/blob/master/doc/Preview%20Version%201.0.md


I'm a Java developer by trade (among a few other languages) and the notion of running Java on my Apple II makes me cringe.  Sure, it *can* be done...but why??  OMG WHY???   lol

[toc] | [prev] | [next] | [standalone]


#4114

Fromol.sc@web.de (Oliver Schmidt)
Date2018-01-17 22:29 +0000
Message-ID<p3oip1$8us$2@news.albasani.net>
In reply to#4113
>I'm a Java developer by trade (among a few other languages) and the notion =
>of running Java on my Apple II makes me cringe.  Sure, it *can* be done...b=
>ut why??  OMG WHY???   lol

When VM02 was new I was thinking about viable use cases. You see: That
it's actually Java asks for reuse: Reuse of knowhow and reuse of code.
But what type of Java code is small enough to run on VM02 and fits at
least somehow to the Apple II I/O capabilities? I found that
https://processing.org/ might work. Sketches can already do
interesting things with very little code - which actually is Java
code.

Creating a Processing (of course execution-only) environment based on
VM02 is one of those projects put on the back burner. But maybe
someone else is more active than I am...

Regards,
Oliver

[toc] | [prev] | [next] | [standalone]


#4116

FromJohn Brooks <jbrooks@blueshiftinc.com>
Date2018-01-18 02:57 -0800
Message-ID<44ee6849-2f07-4e66-ab94-0258aa704bfb@googlegroups.com>
In reply to#4109
On Wednesday, January 17, 2018 at 6:57:55 AM UTC-8, David Schmenk wrote:
> Modern Retroprogramming on the Apple II. When was the last time you programmed a modern language on a 40 year old computer? Now is your chance. PLASMA is a combination of operating environment, virtual machine, and assembler/compiler matched closely to the 6502 architecture. Check out the Release Notes for details: https://github.com/dschmenk/PLASMA/blob/master/doc/Preview%20Version%201.0.md

Some VM optimization ideas if you want to squeeze bytes or cycles:

1) Can save about 200 bytes from Plasma VM code by changing INC_IP to just INY with lazy update of IPH.

2) Can reduce compiled code size and speed up common operations by assigning the unused 128 opcodes to constants.

3) Can speed up short, heavily-used opcode handlers via threaded-dispatch instead of central-dispatch.

4) Can save 4 bytes of ZP by moving NEXTOPH down to $0100

5) Can save code size in multi-byte opcode handlers by having NEXTOP inc IP (via INY with lazy update) before calling handler, saving the first INC_IP in the handlers.

6) Can save 20-40 bytes by putting STA ESTKH+1,X before DROP and calling it from various opcode handlers. Similarly, can make a thunk with LDY IPY, STA ESTKH,X, JMP NEXTOP and calling from several handlers to make them smaller (but also 3c slower).  

7) Can reduce VM code size via 65c02 opcodes (PHY/PLY, STZ).

For my Apple Pascal VM refactor, I also put the heap in aux mem with pcode in main mem. This allows the pcode VM to coexist with ProDOS and gives the heap access to aux LC memory.

-JB
@JBrooksBSI

[toc] | [prev] | [next] | [standalone]


#4118

FromDavid Schmenk <dschmenk@gmail.com>
Date2018-01-18 11:12 -0800
Message-ID<3bb4debd-429f-424a-b456-fee40f43770f@googlegroups.com>
In reply to#4116
Hi John-

Thanks so much for your time looking at the PLASM VM! Sorry for not posting sooner, but I wanted to make sure I took time for a quality response.

On Thursday, 18 January 2018 02:57:42 UTC-8, John Brooks  wrote:
> On Wednesday, January 17, 2018 at 6:57:55 AM UTC-8, David Schmenk wrote:
> > Modern Retroprogramming on the Apple II. When was the last time you programmed a modern language on a 40 year old computer? Now is your chance. PLASMA is a combination of operating environment, virtual machine, and assembler/compiler matched closely to the 6502 architecture. Check out the Release Notes for details: https://github.com/dschmenk/PLASMA/blob/master/doc/Preview%20Version%201.0.md
> 
> Some VM optimization ideas if you want to squeeze bytes or cycles:
> 
> 1) Can save about 200 bytes from Plasma VM code by changing INC_IP to just INY with lazy update of IPH.

One of the fundamental architectural decisions makde for PLASMA was an optimal of a NEXTOP routine as I could come up with. As such, the Instruction Pointer is combined with the Y register for opcode/operand fetches. It is rarely re-normalized, that is, setting the Y register to a known value. This allows the instruction pointer to be incremented with just an INY instructions. However, it does require checking every time for carry into the MSB (IPH). This is why I made a macro for incrementing IP. It is still a win vs. incrementing a ZP value, then checking for carry out of that. I have only seen one NEXTOP routine faster than PLASMA's: PETTIL Forth, and that put requirements on the compiler for even addresses and page crossings (and still 15 clocks vs 17 for PLASMA).

> 
> 2) Can reduce compiled code size and speed up common operations by assigning the unused 128 opcodes to constants.

I looked at this early on, but decided against it. First, I made concessions for small constants with ZERO (used a lot) and ConstantByte. Later, ConstantFFByte improved density for negative numbers (even pcode doesn't address that). I also didn't want to commit a large chunk of opcodes just to constants (for reasons described below). Lastly, I kept opcodes to even numbers so there wasn't any bit twiddlig in the NEXTOP routine, making only 64 unused opcodes actually available. 
> 
> 3) Can speed up short, heavily-used opcode handlers via threaded-dispatch instead of central-dispatch.
So this is where having control of the VM *and* compiler reap big benefits. I started the PLASMA VM with a simple set of opcodes. If a sequence of opcodes could be replaced with more efficient opcode implementation, then I added the opcode to the VM and updated the compiler. This process has continued and is still on-going. When I refactored the compiler for a backend optimizer, it became even easier to identify and replace oft-used sequences with more optimized code and implement new opcodes. It is important to put the impetus on the compiler and VM design and not the NEXTOP routine to identify code for efficient execution.

Just an aside from my work on the Java VM (VM02): This was really what led me down the path of PLASMA - the Java compiler (at least up until 2006) was brain dead in its code generation. Basically no more intelligent than the Pascal compiler that ran on the Apple II! Java expected the VM and the JIT to make up for a lame compiler. The Java binaries were big and innefficient, killing any hope of decent performance on a 6502, and I had no control over the compiler.
> 
> 4) Can save 4 bytes of ZP by moving NEXTOPH down to $0100
>
Yeah, that could be a byte savings. I've reserved $C0-$FF for PLASMA and still have a few bytes available. If it gets full, that will be a great move.
 
> 5) Can save code size in multi-byte opcode handlers by having NEXTOP inc IP (via INY with lazy update) before calling handler, saving the first INC_IP in the handlers.
See #1 and #3 above
> 
> 6) Can save 20-40 bytes by putting STA ESTKH+1,X before DROP and calling it from various opcode handlers. Similarly, can make a thunk with LDY IPY, STA ESTKH,X, JMP NEXTOP and calling from several handlers to make them smaller (but also 3c slower).
This could be a great savings, especially on the Apple /// where every byte is sacred (to paraphrase Monty Python). I'll try to get this in for the Apple I and /// versions before 1.0 release.
> 
> 7) Can reduce VM code size via 65c02 opcodes (PHY/PLY, STZ).
I kept the VM standard 6502 for now. It would be worth looking into improvements that could be made with 65C02 code. There were places where 65C02-isms helped out the 65802 VM. More interested in speed than size reduction.
> 
> For my Apple Pascal VM refactor, I also put the heap in aux mem with pcode in main mem. This allows the pcode VM to coexist with ProDOS and gives the heap access to aux LC memory.
Does this mean the actual pcode existed in MAIN or AUX mem? How would you pass AUX heap memory to ProDOS for reading files, for instance? I believe Apple Pascal's 1.2 and later pcode interpreter would put pcode in AUX mem. That's what I did for PLASMA (and VM02), too. But, I don't get easy access to AUX LC memory except that is where SANE gets loaded.

> 
> -JB
> @JBrooksBSI

Thanks again for all your insights. Looking forward to more thoughts and discussions,

Dave...

[toc] | [prev] | [next] | [standalone]


#4119

FromJohn Brooks <jbrooks@blueshiftinc.com>
Date2018-01-18 12:02 -0800
Message-ID<5ed1dd00-a70c-4ff3-9a06-833374f5da06@googlegroups.com>
In reply to#4118
On Thursday, January 18, 2018 at 11:12:40 AM UTC-8, David Schmenk wrote:
> Hi John-
> 
> Thanks so much for your time looking at the PLASM VM! Sorry for not posting sooner, but I wanted to make sure I took time for a quality response.
> 
> On Thursday, 18 January 2018 02:57:42 UTC-8, John Brooks  wrote:
> > On Wednesday, January 17, 2018 at 6:57:55 AM UTC-8, David Schmenk wrote:
> > > Modern Retroprogramming on the Apple II. When was the last time you programmed a modern language on a 40 year old computer? Now is your chance. PLASMA is a combination of operating environment, virtual machine, and assembler/compiler matched closely to the 6502 architecture. Check out the Release Notes for details: https://github.com/dschmenk/PLASMA/blob/master/doc/Preview%20Version%201.0.md
> > 
> > Some VM optimization ideas if you want to squeeze bytes or cycles:
> > 
> > 1) Can save about 200 bytes from Plasma VM code by changing INC_IP to just INY with lazy update of IPH.
> 
> One of the fundamental architectural decisions makde for PLASMA was an optimal of a NEXTOP routine as I could come up with. As such, the Instruction Pointer is combined with the Y register for opcode/operand fetches. It is rarely re-normalized, that is, setting the Y register to a known value. This allows the instruction pointer to be incremented with just an INY instructions. However, it does require checking every time for carry into the MSB (IPH). This is why I made a macro for incrementing IP. It is still a win vs. incrementing a ZP value, then checking for carry out of that. I have only seen one NEXTOP routine faster than PLASMA's: PETTIL Forth, and that put requirements on the compiler for even addresses and page crossings (and still 15 clocks vs 17 for PLASMA).
> 
> > 
> > 2) Can reduce compiled code size and speed up common operations by assigning the unused 128 opcodes to constants.
> 
> I looked at this early on, but decided against it. First, I made concessions for small constants with ZERO (used a lot) and ConstantByte. Later, ConstantFFByte improved density for negative numbers (even pcode doesn't address that). I also didn't want to commit a large chunk of opcodes just to constants (for reasons described below). Lastly, I kept opcodes to even numbers so there wasn't any bit twiddlig in the NEXTOP routine, making only 64 unused opcodes actually available. 
> > 
> > 3) Can speed up short, heavily-used opcode handlers via threaded-dispatch instead of central-dispatch.
> So this is where having control of the VM *and* compiler reap big benefits. I started the PLASMA VM with a simple set of opcodes. If a sequence of opcodes could be replaced with more efficient opcode implementation, then I added the opcode to the VM and updated the compiler. This process has continued and is still on-going. When I refactored the compiler for a backend optimizer, it became even easier to identify and replace oft-used sequences with more optimized code and implement new opcodes. It is important to put the impetus on the compiler and VM design and not the NEXTOP routine to identify code for efficient execution.
> 
> Just an aside from my work on the Java VM (VM02): This was really what led me down the path of PLASMA - the Java compiler (at least up until 2006) was brain dead in its code generation. Basically no more intelligent than the Pascal compiler that ran on the Apple II! Java expected the VM and the JIT to make up for a lame compiler. The Java binaries were big and innefficient, killing any hope of decent performance on a 6502, and I had no control over the compiler.
> > 
> > 4) Can save 4 bytes of ZP by moving NEXTOPH down to $0100
> >
> Yeah, that could be a byte savings. I've reserved $C0-$FF for PLASMA and still have a few bytes available. If it gets full, that will be a great move.
>  
> > 5) Can save code size in multi-byte opcode handlers by having NEXTOP inc IP (via INY with lazy update) before calling handler, saving the first INC_IP in the handlers.
> See #1 and #3 above
> > 
> > 6) Can save 20-40 bytes by putting STA ESTKH+1,X before DROP and calling it from various opcode handlers. Similarly, can make a thunk with LDY IPY, STA ESTKH,X, JMP NEXTOP and calling from several handlers to make them smaller (but also 3c slower).
> This could be a great savings, especially on the Apple /// where every byte is sacred (to paraphrase Monty Python). I'll try to get this in for the Apple I and /// versions before 1.0 release.
> > 
> > 7) Can reduce VM code size via 65c02 opcodes (PHY/PLY, STZ).
> I kept the VM standard 6502 for now. It would be worth looking into improvements that could be made with 65C02 code. There were places where 65C02-isms helped out the 65802 VM. More interested in speed than size reduction.
> > 
> > For my Apple Pascal VM refactor, I also put the heap in aux mem with pcode in main mem. This allows the pcode VM to coexist with ProDOS and gives the heap access to aux LC memory.
> Does this mean the actual pcode existed in MAIN or AUX mem? How would you pass AUX heap memory to ProDOS for reading files, for instance? I believe Apple Pascal's 1.2 and later pcode interpreter would put pcode in AUX mem. That's what I did for PLASMA (and VM02), too. But, I don't get easy access to AUX LC memory except that is where SANE gets loaded.
> 
> > 
> > -JB
> > @JBrooksBSI
> 
> Thanks again for all your insights. Looking forward to more thoughts and discussions,
> 
> Dave...

The optimization I recommend is avoiding the BNE & INC IPH every time an INY is done.

The lazy update optimization is to allow most of the handlers to just INY without the BNE & INC IPH. Then in the central dispatch or a few other targeted handlers, do a BMI after the INY to a normalize func which adds Y to IPL & updates IPH if needed.

This way, most of the time INY is done without a branch check saving 3 cycles & 4 bytes. The central dispatch will catch when Y is > 127 and only then do the IPH update, saving many cycles & bytes on average.

> I looked at this early on, but decided against it. First, I made concessions for small constants with ZERO (used a lot) and ConstantByte. 

Okay, but this is such a big win in my experience that I'm surprised. The cycle and byte cost for explicit constant opcodes is high given how often they occur.

Constants can be 6-bit unsigned in 1 byte or 14-bit signed in 2 bytes (similar to pcode bigparam) and should free up some of the current Plasma opcodes. I nice speed-up opcode to add would be jbnz and inc+loop.


> Lastly, I kept opcodes to even numbers so there wasn't any bit twiddlig in the NEXTOP routine, making only 64 unused opcodes actually available.

True, but the saving is only a 2 cycle ASL and that optimization costs 1/2 of the opcode space, increasing the size of generated bytecode and preventing more optimal specialized opcode handlers like jbnz, etc.


> It is important to put the impetus on the compiler and VM design and not the NEXTOP routine to identify code for efficient execution.

Agreed, but improving VM efficiency is a win too. Plasma currently uses a central dispatch at NEXTOP which all handlers jump to.

A tail-dispatch or threaded-dispatch optimization has high-use handlers (ZERO, CB, CW, INC, DEC, etc) dispatch directly to the next handler from their handler. This was a nice win for me with the UCSD pcode VM.


> > Does this mean the actual pcode existed in MAIN or AUX mem? How would you pass AUX heap memory to ProDOS for reading files, for instance? I believe Apple Pascal's 1.2 and later pcode interpreter would put pcode in AUX mem. That's what I did for PLASMA (and VM02), too. But, I don't get easy access to AUX LC memory except that is where SANE gets loaded.

Pascal 1.2 & 1.3 load pcode into aux with the heap in main. However SYSCOM at the top of the heap conflicted with the ProDOS $BF00 page. It also means that all pcode segs get copied to aux mem and go through bank switch juggling. The block xfer buffer and global directory cache were also eating up heap space. Moving the block buffer & gdir to pcode (main) bank frees up heap space.

My 1.4a version (128k 65c02 required) launches as a ProDOS .system file (replacing SYSTEM.APPLE), and has faster pcode loads/swaps to main instead of aux. BIOS routines which read/write the heap need to swap in the aux bank or copy to/from main, but it was better to get a larger heap by moving it away from ProDOS, $BF00, keybuf, $3xx vectors, & video buffers.

> Thanks again for all your insights. Looking forward to more thoughts and discussions, 

Sure thing. This is part of the fun of playing with the Apple II!

I'm not sure how many of these you'll want to try as some are pretty big changes, but I thought I'd throw ideas at the wall and you could sort them out to see what is interesting.

-JB
@JBrooksBSI

[toc] | [prev] | [next] | [standalone]


#4120

FromDavid Schmenk <dschmenk@gmail.com>
Date2018-01-18 13:07 -0800
Message-ID<504013c8-2b68-4984-a5ab-1f72a9385a01@googlegroups.com>
In reply to#4119
On Thursday, 18 January 2018 12:02:01 UTC-8, John Brooks  wrote:

SNIP

> 
> The optimization I recommend is avoiding the BNE & INC IPH every time an INY is done.
> 
> The lazy update optimization is to allow most of the handlers to just INY without the BNE & INC IPH. Then in the central dispatch or a few other targeted handlers, do a BMI after the INY to a normalize func which adds Y to IPL & updates IPH if needed.
> 
> This way, most of the time INY is done without a branch check saving 3 cycles & 4 bytes. The central dispatch will catch when Y is > 127 and only then do the IPH update, saving many cycles & bytes on average.

Ok, I see what you're saying. NEXTOP would update IPH twice as often, but the rest of the opcodes could forgo checking for carry out. Interesting. Now I'm going to be up all night thinking this through...

> 
> > I looked at this early on, but decided against it. First, I made concessions for small constants with ZERO (used a lot) and ConstantByte. 
> 
> Okay, but this is such a big win in my experience that I'm surprised. The cycle and byte cost for explicit constant opcodes is high given how often they occur.

What I notoced is that most constants were for offsetting addresses. The first additional opcodes I added to PLASMA were to load and store to absolute addresses with offsets that are fixed up by the loader dynamically. PLASMA doesn't have nested frames like Pascal. Other constant like 1 and -1 usually get subsumed into the INCR and DECR ops. It's pretty easy to grep through the generated code and evaluate how many times other constant values are explicitly loaded. I'm not against adding opcodes for constants, it just has to be justified.
> 
> Constants can be 6-bit unsigned in 1 byte or 14-bit signed in 2 bytes (similar to pcode bigparam) and should free up some of the current Plasma opcodes. I nice speed-up opcode to add would be jbnz and inc+loop.
Specialized loops and branches are good candidates for new opcodes. I created some for improving the FOR/NEXT loops.
> 
> 
> > Lastly, I kept opcodes to even numbers so there wasn't any bit twiddlig in the NEXTOP routine, making only 64 unused opcodes actually available.
> 
> True, but the saving is only a 2 cycle ASL and that optimization costs 1/2 of the opcode space, increasing the size of generated bytecode and preventing more optimal specialized opcode handlers like jbnz, etc.
Yeah, but that's still 2 cycles ;-) And since there are still less than 64 opcodes defined, I don't feel too constrained, yet. 
> 
> 
> > It is important to put the impetus on the compiler and VM design and not the NEXTOP routine to identify code for efficient execution.
> 
> Agreed, but improving VM efficiency is a win too. Plasma currently uses a central dispatch at NEXTOP which all handlers jump to.
> 
> A tail-dispatch or threaded-dispatch optimization has high-use handlers (ZERO, CB, CW, INC, DEC, etc) dispatch directly to the next handler from their handler. This was a nice win for me with the UCSD pcode VM.
> 

This was due to a requirement that byte codes could be in either MAIN or AUX (extended on the ///) memory. The entry into the interpreter fixes up the jump table depending on where the routine resides. Otherwise all the places where the jump table is referenced would have to be fixed up. I can see this being a big win, though. Perhaps one of those design decisions that is worth revisiting...

> 
> > > Does this mean the actual pcode existed in MAIN or AUX mem? How would you pass AUX heap memory to ProDOS for reading files, for instance? I believe Apple Pascal's 1.2 and later pcode interpreter would put pcode in AUX mem. That's what I did for PLASMA (and VM02), too. But, I don't get easy access to AUX LC memory except that is where SANE gets loaded.
> 
> Pascal 1.2 & 1.3 load pcode into aux with the heap in main. However SYSCOM at the top of the heap conflicted with the ProDOS $BF00 page. It also means that all pcode segs get copied to aux mem and go through bank switch juggling. The block xfer buffer and global directory cache were also eating up heap space. Moving the block buffer & gdir to pcode (main) bank frees up heap space.
> 
> My 1.4a version (128k 65c02 required) launches as a ProDOS .system file (replacing SYSTEM.APPLE), and has faster pcode loads/swaps to main instead of aux. BIOS routines which read/write the heap need to swap in the aux bank or copy to/from main, but it was better to get a larger heap by moving it away from ProDOS, $BF00, keybuf, $3xx vectors, & video buffers.
The 128K memory architecure sure requires a great deal of gymnastics. Is there a place to find your 1.4a version? Apple Pascal was the first HLL I learned and still has a place in my heart.
> 
> > Thanks again for all your insights. Looking forward to more thoughts and discussions, 
> 
> Sure thing. This is part of the fun of playing with the Apple II!
> 
> I'm not sure how many of these you'll want to try as some are pretty big changes, but I thought I'd throw ideas at the wall and you could sort them out to see what is interesting.
All your ideas have merit, as you've got real-world experience improving a byte-code interpreter. Not many people can say that!
> 
> -JB
> @JBrooksBSI
Dave...

[toc] | [prev] | [next] | [standalone]


#4122

FromJohn Brooks <jbrooks@blueshiftinc.com>
Date2018-01-18 14:21 -0800
Message-ID<64774381-9381-4624-b4eb-21375f3a6990@googlegroups.com>
In reply to#4120
On Thursday, January 18, 2018 at 1:07:17 PM UTC-8, David Schmenk wrote:
> On Thursday, 18 January 2018 12:02:01 UTC-8, John Brooks  wrote:
> 
> SNIP
> 
> > 
> > The optimization I recommend is avoiding the BNE & INC IPH every time an INY is done.
> > 
> > The lazy update optimization is to allow most of the handlers to just INY without the BNE & INC IPH. Then in the central dispatch or a few other targeted handlers, do a BMI after the INY to a normalize func which adds Y to IPL & updates IPH if needed.
> > 
> > This way, most of the time INY is done without a branch check saving 3 cycles & 4 bytes. The central dispatch will catch when Y is > 127 and only then do the IPH update, saving many cycles & bytes on average.
> 
> Ok, I see what you're saying. NEXTOP would update IPH twice as often, but the rest of the opcodes could forgo checking for carry out. Interesting. Now I'm going to be up all night thinking this through...
> 
> > 
> > > I looked at this early on, but decided against it. First, I made concessions for small constants with ZERO (used a lot) and ConstantByte. 
> > 
> > Okay, but this is such a big win in my experience that I'm surprised. The cycle and byte cost for explicit constant opcodes is high given how often they occur.
> 
> What I notoced is that most constants were for offsetting addresses. The first additional opcodes I added to PLASMA were to load and store to absolute addresses with offsets that are fixed up by the loader dynamically. PLASMA doesn't have nested frames like Pascal. Other constant like 1 and -1 usually get subsumed into the INCR and DECR ops. It's pretty easy to grep through the generated code and evaluate how many times other constant values are explicitly loaded. I'm not against adding opcodes for constants, it just has to be justified.
> > 
> > Constants can be 6-bit unsigned in 1 byte or 14-bit signed in 2 bytes (similar to pcode bigparam) and should free up some of the current Plasma opcodes. I nice speed-up opcode to add would be jbnz and inc+loop.
> Specialized loops and branches are good candidates for new opcodes. I created some for improving the FOR/NEXT loops.
> > 
> > 
> > > Lastly, I kept opcodes to even numbers so there wasn't any bit twiddlig in the NEXTOP routine, making only 64 unused opcodes actually available.
> > 
> > True, but the saving is only a 2 cycle ASL and that optimization costs 1/2 of the opcode space, increasing the size of generated bytecode and preventing more optimal specialized opcode handlers like jbnz, etc.
> Yeah, but that's still 2 cycles ;-) And since there are still less than 64 opcodes defined, I don't feel too constrained, yet. 
> > 
> > 
> > > It is important to put the impetus on the compiler and VM design and not the NEXTOP routine to identify code for efficient execution.
> > 
> > Agreed, but improving VM efficiency is a win too. Plasma currently uses a central dispatch at NEXTOP which all handlers jump to.
> > 
> > A tail-dispatch or threaded-dispatch optimization has high-use handlers (ZERO, CB, CW, INC, DEC, etc) dispatch directly to the next handler from their handler. This was a nice win for me with the UCSD pcode VM.
> > 
> 
> This was due to a requirement that byte codes could be in either MAIN or AUX (extended on the ///) memory. The entry into the interpreter fixes up the jump table depending on where the routine resides. Otherwise all the places where the jump table is referenced would have to be fixed up. I can see this being a big win, though. Perhaps one of those design decisions that is worth revisiting...
> 
> > 
> > > > Does this mean the actual pcode existed in MAIN or AUX mem? How would you pass AUX heap memory to ProDOS for reading files, for instance? I believe Apple Pascal's 1.2 and later pcode interpreter would put pcode in AUX mem. That's what I did for PLASMA (and VM02), too. But, I don't get easy access to AUX LC memory except that is where SANE gets loaded.
> > 
> > Pascal 1.2 & 1.3 load pcode into aux with the heap in main. However SYSCOM at the top of the heap conflicted with the ProDOS $BF00 page. It also means that all pcode segs get copied to aux mem and go through bank switch juggling. The block xfer buffer and global directory cache were also eating up heap space. Moving the block buffer & gdir to pcode (main) bank frees up heap space.
> > 
> > My 1.4a version (128k 65c02 required) launches as a ProDOS .system file (replacing SYSTEM.APPLE), and has faster pcode loads/swaps to main instead of aux. BIOS routines which read/write the heap need to swap in the aux bank or copy to/from main, but it was better to get a larger heap by moving it away from ProDOS, $BF00, keybuf, $3xx vectors, & video buffers.
> The 128K memory architecure sure requires a great deal of gymnastics. Is there a place to find your 1.4a version? Apple Pascal was the first HLL I learned and still has a place in my heart.
> > 
> > > Thanks again for all your insights. Looking forward to more thoughts and discussions, 
> > 
> > Sure thing. This is part of the fun of playing with the Apple II!
> > 
> > I'm not sure how many of these you'll want to try as some are pretty big changes, but I thought I'd throw ideas at the wall and you could sort them out to see what is interesting.
> All your ideas have merit, as you've got real-world experience improving a byte-code interpreter. Not many people can say that!
> > 
> > -JB
> > @JBrooksBSI
> Dave...

.

> Ok, I see what you're saying. NEXTOP would update IPH twice as often, but the rest of the opcodes could forgo checking for carry out. Interesting. Now I'm going to be up all night thinking this through...

Yes, although for max win, it's great to have NEXTOP do only the INY and leave the BMI check for less-frequent branch (not taken path) & load ops. If the compiler can generate > 127 op bytes without a branch or load, then the compiler could emit an explicit branch to next opcode after 128 bytes.

>  What I notoced is that most constants were for offsetting addresses. I'm not against adding opcodes for constants, it just has to be justified. 

Totally. Being able to generate:
 $00-$3F in one byte instead of two, and
 $C000-$FFFF & $0000-$3FFF in two bytes instead of three is a big space savings

Also constant dispatch bypasses the jump table, so constants are faster to execute than with CB/CW and make up a large percentage of the executed opcodes.


> Otherwise all the places where the jump table is referenced would have to be fixed up. I can see this being a big win, though.

Yeah, I'd just have the tables at all the threaded dispatch points patched as it is outside the VM loop.


> The 128K memory architecure sure requires a great deal of gymnastics.

Agreed. I keep the code bank swapped in by default and only bank over to the heap bank or those opcodes that need it. This was a very large performance win over Pascal 1.2 & 1.3 which keep the heap banked in all the time and constantly toggle to aux for every opcode byte fetch.


> Is there a place to find your 1.4a version? Apple Pascal was the first HLL I learned and still has a place in my heart. 

I sent my 2017 1.4a1 preview version to you by email. It launches from ProDOS and quits back to ProDOS and uses the Profile HD drivers to mount multiple disk images from a 32MB hard drive.

Testing & feedback welcome!

-JB
@JBrooksBSI

[toc] | [prev] | [next] | [standalone]


#4123

FromDavid Schmenk <dschmenk@gmail.com>
Date2018-01-18 16:49 -0800
Message-ID<1976c838-9932-45d0-b534-46dcd72843d1@googlegroups.com>
In reply to#4122
On Thursday, January 18, 2018 at 2:21:11 PM UTC-8, John Brooks wrote:
> 
> > Ok, I see what you're saying. NEXTOP would update IPH twice as often, but the rest of the opcodes could forgo checking for carry out. Interesting. Now I'm going to be up all night thinking this through...
> 
> Yes, although for max win, it's great to have NEXTOP do only the INY and leave the BMI check for less-frequent branch (not taken path) & load ops. If the compiler can generate > 127 op bytes without a branch or load, then the compiler could emit an explicit branch to next opcode after 128 bytes.

So this is pretty brilliant and almost trivial to implement (15 minutes worth of editing, worked the first time). Using Sieve of Eratosthenes (never can spell that right) as a benchmark gave me these results:

Preview 1, ave of 5 runs: 19.94 seconds
JB special, ave of 5 runs: 18.44 seconds

7.5% improvement!

Simply remove the BNE NEXTOPH from FETCHOP, then rewrite INC_IP as:
        !MACRO  INC_IP  {
        INY
        BPL     +
        INC    IPH
        TYA
        AND     #$7F
        TAY
+
        }

In the opcode definitions, any that have two INC_IPs, just replace the first with INY. The only opcode that required a minor rewrite was BRANCH, to flatten the IP before calling NEXTOP.

So that was a pretty productive day.

Thanks John!

Dave...
> 
> -JB
> @JBrooksBSI

[toc] | [prev] | [next] | [standalone]


#4124

FromJohn Brooks <jbrooks@blueshiftinc.com>
Date2018-01-18 21:40 -0800
Message-ID<d128e0dc-c1d9-41f2-bfb0-c099b5e25b1f@googlegroups.com>
In reply to#4123
On Thursday, January 18, 2018 at 4:49:23 PM UTC-8, David Schmenk wrote:
> On Thursday, January 18, 2018 at 2:21:11 PM UTC-8, John Brooks wrote:
> > 
> > > Ok, I see what you're saying. NEXTOP would update IPH twice as often, but the rest of the opcodes could forgo checking for carry out. Interesting. Now I'm going to be up all night thinking this through...
> > 
> > Yes, although for max win, it's great to have NEXTOP do only the INY and leave the BMI check for less-frequent branch (not taken path) & load ops. If the compiler can generate > 127 op bytes without a branch or load, then the compiler could emit an explicit branch to next opcode after 128 bytes.
> 
> So this is pretty brilliant and almost trivial to implement (15 minutes worth of editing, worked the first time). Using Sieve of Eratosthenes (never can spell that right) as a benchmark gave me these results:
> 
> Preview 1, ave of 5 runs: 19.94 seconds
> JB special, ave of 5 runs: 18.44 seconds
> 
> 7.5% improvement!
> 
> Simply remove the BNE NEXTOPH from FETCHOP, then rewrite INC_IP as:
>         !MACRO  INC_IP  {
>         INY
>         BPL     +
>         INC    IPH
>         TYA
>         AND     #$7F
>         TAY
> +
>         }
> 
> In the opcode definitions, any that have two INC_IPs, just replace the first with INY. The only opcode that required a minor rewrite was BRANCH, to flatten the IP before calling NEXTOP.
> 
> So that was a pretty productive day.
> 
> Thanks John!
> 
> Dave...
> > 
> > -JB
> > @JBrooksBSI

Great!

A few other things I forgot to mention:

1) The use of the INC_IP macro costs 1 extra cycle every use because of the BNE/BPL over the INC IPH code. Instead, I'd use INY,BMI to the INC IPH code at the end of each handler so the INY BMI can fall through for 2c instead of branching around all the time for 3c.

2) INC & DEC are branching around high byte inc code too, so you can save 1 cycle there pretty much every time.

3) SHL would be faster using acc in inner loop instead of zp,x

4) SHR (and SHL) may be worth unrolling and jumping into instead of looping. SHR can have one code path for signed & another for unsigned so unsigned path can be faster with LSR.

5) The mul code can be sped up by using the carry to end the loop instead of Y, like in this code:
https://groups.google.com/d/msg/comp.sys.apple2.programmer/NpfRXsf2T0s/iD6wEIpNBQAJ

Using carry avoids the need for STY/LDY, or move one of the inner-loop vars into a reg.

-JB
@JBrooksBSI

[toc] | [prev] | [next] | [standalone]


#4125

FromDavid Schmenk <dschmenk@gmail.com>
Date2018-01-19 09:06 -0800
Message-ID<ce105269-c183-4f51-84b5-6f960dc617c7@googlegroups.com>
In reply to#4124
On Thursday, 18 January 2018 21:40:14 UTC-8, John Brooks  wrote:
> On Thursday, January 18, 2018 at 4:49:23 PM UTC-8, David Schmenk wrote:
> > On Thursday, January 18, 2018 at 2:21:11 PM UTC-8, John Brooks wrote:
> > > 
> > > > Ok, I see what you're saying. NEXTOP would update IPH twice as often, but the rest of the opcodes could forgo checking for carry out. Interesting. Now I'm going to be up all night thinking this through...
> > > 
> > > Yes, although for max win, it's great to have NEXTOP do only the INY and leave the BMI check for less-frequent branch (not taken path) & load ops. If the compiler can generate > 127 op bytes without a branch or load, then the compiler could emit an explicit branch to next opcode after 128 bytes.
> > 
> > So this is pretty brilliant and almost trivial to implement (15 minutes worth of editing, worked the first time). Using Sieve of Eratosthenes (never can spell that right) as a benchmark gave me these results:
> > 
> > Preview 1, ave of 5 runs: 19.94 seconds
> > JB special, ave of 5 runs: 18.44 seconds
> > 
> > 7.5% improvement!
> > 
> > Simply remove the BNE NEXTOPH from FETCHOP, then rewrite INC_IP as:
> >         !MACRO  INC_IP  {
> >         INY
> >         BPL     +
> >         INC    IPH
> >         TYA
> >         AND     #$7F
> >         TAY
> > +
> >         }
> > 
> > In the opcode definitions, any that have two INC_IPs, just replace the first with INY. The only opcode that required a minor rewrite was BRANCH, to flatten the IP before calling NEXTOP.
> > 
> > So that was a pretty productive day.
> > 
> > Thanks John!
> > 
> > Dave...
> > > 
> > > -JB
> > > @JBrooksBSI
> 
> Great!
> 
> A few other things I forgot to mention:
> 
> 1) The use of the INC_IP macro costs 1 extra cycle every use because of the BNE/BPL over the INC IPH code. Instead, I'd use INY,BMI to the INC IPH code at the end of each handler so the INY BMI can fall through for 2c instead of branching around all the time for 3c.
> 
> 2) INC & DEC are branching around high byte inc code too, so you can save 1 cycle there pretty much every time.
> 

By only having to check for IP fix-up once per opcode certainly allows many more opportunities for improving the branch taken logic. I will revisit this soon.

> 3) SHL would be faster using acc in inner loop instead of zp,x
> 
Yeah, not sure why I didn't do that.

> 4) SHR (and SHL) may be worth unrolling and jumping into instead of looping. SHR can have one code path for signed & another for unsigned so unsigned path can be faster with LSR.
> 
It was definitely a tradeoff - I do check for shift counts of 8 or greater and move the whole byte first so there is never a shift count greater than 7.


> 5) The mul code can be sped up by using the carry to end the loop instead of Y, like in this code:
> https://groups.google.com/d/msg/comp.sys.apple2.programmer/NpfRXsf2T0s/iD6wEIpNBQAJ
> 
> Using carry avoids the need for STY/LDY, or move one of the inner-loop vars into a reg.
??  Was that the link you intended? The MUL code could use a little work, but I didn't want to copy a bunch of values around and opted to keep most things on the eval stack. But it does chew up X.

qkumba has a list of updates for me as well. You guys are going to keep me busy, but I'm pretty excited at what the final 1.0 release is going to be. Thanks for all your efforts and insights!

Dave...

> 
> -JB
> @JBrooksBSI

[toc] | [prev] | [next] | [standalone]


#4126

FromJohn Brooks <jbrooks@blueshiftinc.com>
Date2018-01-19 10:03 -0800
Message-ID<acdf8145-c4ae-459d-ad38-4a354ae647a1@googlegroups.com>
In reply to#4125
On Friday, January 19, 2018 at 9:06:09 AM UTC-8, David Schmenk wrote:
> On Thursday, 18 January 2018 21:40:14 UTC-8, John Brooks  wrote:
> > On Thursday, January 18, 2018 at 4:49:23 PM UTC-8, David Schmenk wrote:
> > > On Thursday, January 18, 2018 at 2:21:11 PM UTC-8, John Brooks wrote:
> > > > 
> > > > > Ok, I see what you're saying. NEXTOP would update IPH twice as often, but the rest of the opcodes could forgo checking for carry out. Interesting. Now I'm going to be up all night thinking this through...
> > > > 
> > > > Yes, although for max win, it's great to have NEXTOP do only the INY and leave the BMI check for less-frequent branch (not taken path) & load ops. If the compiler can generate > 127 op bytes without a branch or load, then the compiler could emit an explicit branch to next opcode after 128 bytes.
> > > 
> > > So this is pretty brilliant and almost trivial to implement (15 minutes worth of editing, worked the first time). Using Sieve of Eratosthenes (never can spell that right) as a benchmark gave me these results:
> > > 
> > > Preview 1, ave of 5 runs: 19.94 seconds
> > > JB special, ave of 5 runs: 18.44 seconds
> > > 
> > > 7.5% improvement!
> > > 
> > > Simply remove the BNE NEXTOPH from FETCHOP, then rewrite INC_IP as:
> > >         !MACRO  INC_IP  {
> > >         INY
> > >         BPL     +
> > >         INC    IPH
> > >         TYA
> > >         AND     #$7F
> > >         TAY
> > > +
> > >         }
> > > 
> > > In the opcode definitions, any that have two INC_IPs, just replace the first with INY. The only opcode that required a minor rewrite was BRANCH, to flatten the IP before calling NEXTOP.
> > > 
> > > So that was a pretty productive day.
> > > 
> > > Thanks John!
> > > 
> > > Dave...
> > > > 
> > > > -JB
> > > > @JBrooksBSI
> > 
> > Great!
> > 
> > A few other things I forgot to mention:
> > 
> > 1) The use of the INC_IP macro costs 1 extra cycle every use because of the BNE/BPL over the INC IPH code. Instead, I'd use INY,BMI to the INC IPH code at the end of each handler so the INY BMI can fall through for 2c instead of branching around all the time for 3c.
> > 
> > 2) INC & DEC are branching around high byte inc code too, so you can save 1 cycle there pretty much every time.
> > 
> 
> By only having to check for IP fix-up once per opcode certainly allows many more opportunities for improving the branch taken logic. I will revisit this soon.
> 
> > 3) SHL would be faster using acc in inner loop instead of zp,x
> > 
> Yeah, not sure why I didn't do that.
> 
> > 4) SHR (and SHL) may be worth unrolling and jumping into instead of looping. SHR can have one code path for signed & another for unsigned so unsigned path can be faster with LSR.
> > 
> It was definitely a tradeoff - I do check for shift counts of 8 or greater and move the whole byte first so there is never a shift count greater than 7.
> 
> 
> > 5) The mul code can be sped up by using the carry to end the loop instead of Y, like in this code:
> > https://groups.google.com/d/msg/comp.sys.apple2.programmer/NpfRXsf2T0s/iD6wEIpNBQAJ
> > 
> > Using carry avoids the need for STY/LDY, or move one of the inner-loop vars into a reg.
> ??  Was that the link you intended? The MUL code could use a little work, but I didn't want to copy a bunch of values around and opted to keep most things on the eval stack. But it does chew up X.
> 
> qkumba has a list of updates for me as well. You guys are going to keep me busy, but I'm pretty excited at what the final 1.0 release is going to be. Thanks for all your efforts and insights!
> 
> Dave...
> 
> > 
> > -JB
> > @JBrooksBSI

.

> By only having to check for IP fix-up once per opcode certainly allows many more opportunities for improving the branch taken logic. I will revisit this soon.

Yes, although it would be best to remove the IP fix-up check for most of the opcode handlers, especially high-use ones like ZERO, CFFB, NEG, INC, DEC, DUP, DROP, ISxx. It should be enough to do lazy update only on branch-not-taken, loads, and stores which should save a bunch of VM bytes and cycles.


> It was definitely a tradeoff - I do check for shift counts of 8 or greater and move the whole byte first so there is never a shift count greater than 7. 

I'm assuming there are a lot of shift-by-2 since this is a word interp. It may be worth dedicating an opcode for SHL2.



Oh, another idea to pass along:

It would be cool to be able to embed asm source in a Plasma file and have the Plasma compiler generate a text output file where all the Plasma source was compiled to DB/DW bytecode constants interspersed with the asm source.

Then this output source file could be assembled with Merlin8/16/32 to generate a unified runtime blob that contains bytecode for higher-level logic and assembly-code for performance-critical code.


> qkumba has a list of updates for me as well. You guys are going to keep me busy, but I'm pretty excited at what the final 1.0 release is going to be. Thanks for all your efforts and insights! 

LOL, I'm not surprised. Our tag-team optimization of Bitsy Bye in 2016 was epic. 

I look forward to the next rev of Plasma. Please let me know when it is up.

-JB
@JBrooksBSI

[toc] | [prev] | [next] | [standalone]


#4127

FromDavid Schmenk <dschmenk@gmail.com>
Date2018-01-19 13:24 -0800
Message-ID<d3564cc2-97c8-4475-8494-a865ed5ee180@googlegroups.com>
In reply to#4126
On Friday, 19 January 2018 10:03:30 UTC-8, John Brooks  wrote:
> On Friday, January 19, 2018 at 9:06:09 AM UTC-8, David Schmenk wrote:
> > On Thursday, 18 January 2018 21:40:14 UTC-8, John Brooks  wrote:
> > > On Thursday, January 18, 2018 at 4:49:23 PM UTC-8, David Schmenk wrote:
> > > > On Thursday, January 18, 2018 at 2:21:11 PM UTC-8, John Brooks wrote:
> > > > > 
> > > > > > Ok, I see what you're saying. NEXTOP would update IPH twice as often, but the rest of the opcodes could forgo checking for carry out. Interesting. Now I'm going to be up all night thinking this through...
> > > > > 
> > > > > Yes, although for max win, it's great to have NEXTOP do only the INY and leave the BMI check for less-frequent branch (not taken path) & load ops. If the compiler can generate > 127 op bytes without a branch or load, then the compiler could emit an explicit branch to next opcode after 128 bytes.
> > > > 
> > > > So this is pretty brilliant and almost trivial to implement (15 minutes worth of editing, worked the first time). Using Sieve of Eratosthenes (never can spell that right) as a benchmark gave me these results:
> > > > 
> > > > Preview 1, ave of 5 runs: 19.94 seconds
> > > > JB special, ave of 5 runs: 18.44 seconds
> > > > 
> > > > 7.5% improvement!
> > > > 
> > > > Simply remove the BNE NEXTOPH from FETCHOP, then rewrite INC_IP as:
> > > >         !MACRO  INC_IP  {
> > > >         INY
> > > >         BPL     +
> > > >         INC    IPH
> > > >         TYA
> > > >         AND     #$7F
> > > >         TAY
> > > > +
> > > >         }
> > > > 
> > > > In the opcode definitions, any that have two INC_IPs, just replace the first with INY. The only opcode that required a minor rewrite was BRANCH, to flatten the IP before calling NEXTOP.
> > > > 
> > > > So that was a pretty productive day.
> > > > 
> > > > Thanks John!
> > > > 
> > > > Dave...
> > > > > 
> > > > > -JB
> > > > > @JBrooksBSI
> > > 
> > > Great!
> > > 
> > > A few other things I forgot to mention:
> > > 
> > > 1) The use of the INC_IP macro costs 1 extra cycle every use because of the BNE/BPL over the INC IPH code. Instead, I'd use INY,BMI to the INC IPH code at the end of each handler so the INY BMI can fall through for 2c instead of branching around all the time for 3c.
> > > 
> > > 2) INC & DEC are branching around high byte inc code too, so you can save 1 cycle there pretty much every time.
> > > 
> > 
> > By only having to check for IP fix-up once per opcode certainly allows many more opportunities for improving the branch taken logic. I will revisit this soon.
> > 
> > > 3) SHL would be faster using acc in inner loop instead of zp,x
> > > 
> > Yeah, not sure why I didn't do that.
> > 
> > > 4) SHR (and SHL) may be worth unrolling and jumping into instead of looping. SHR can have one code path for signed & another for unsigned so unsigned path can be faster with LSR.
> > > 
> > It was definitely a tradeoff - I do check for shift counts of 8 or greater and move the whole byte first so there is never a shift count greater than 7.
> > 
> > 
> > > 5) The mul code can be sped up by using the carry to end the loop instead of Y, like in this code:
> > > https://groups.google.com/d/msg/comp.sys.apple2.programmer/NpfRXsf2T0s/iD6wEIpNBQAJ
> > > 
> > > Using carry avoids the need for STY/LDY, or move one of the inner-loop vars into a reg.
> > ??  Was that the link you intended? The MUL code could use a little work, but I didn't want to copy a bunch of values around and opted to keep most things on the eval stack. But it does chew up X.
> > 
> > qkumba has a list of updates for me as well. You guys are going to keep me busy, but I'm pretty excited at what the final 1.0 release is going to be. Thanks for all your efforts and insights!
> > 
> > Dave...
> > 
> > > 
> > > -JB
> > > @JBrooksBSI
> 
> .
> 
> > By only having to check for IP fix-up once per opcode certainly allows many more opportunities for improving the branch taken logic. I will revisit this soon.
> 
> Yes, although it would be best to remove the IP fix-up check for most of the opcode handlers, especially high-use ones like ZERO, CFFB, NEG, INC, DEC, DUP, DROP, ISxx. It should be enough to do lazy update only on branch-not-taken, loads, and stores which should save a bunch of VM bytes and cycles.
> 

I'll check the code sequences to make sure there aren't any that exceed the maximum count.  Of course none of the stack operand opcodes ever have to check for IP fix-up, just some of the ones that have in in-line operands.

> 
> > It was definitely a tradeoff - I do check for shift counts of 8 or greater and move the whole byte first so there is never a shift count greater than 7. 
> 
> I'm assuming there are a lot of shift-by-2 since this is a word interp. It may be worth dedicating an opcode for SHL2.

Yep, IDXW (index word) - been there since the beginning. 

> 
> 
> 
> Oh, another idea to pass along:
> 
> It would be cool to be able to embed asm source in a Plasma file and have the Plasma compiler generate a text output file where all the Plasma source was compiled to DB/DW bytecode constants interspersed with the asm source.
> 
> Then this output source file could be assembled with Merlin8/16/32 to generate a unified runtime blob that contains bytecode for higher-level logic and assembly-code for performance-critical code.
> 

This is precisely how the cross compiler works. Pass through asm functions and ca65 or acme compatible output files.  Merlin32 didn't exist at the time I started PLASMA.

> 
> > qkumba has a list of updates for me as well. You guys are going to keep me busy, but I'm pretty excited at what the final 1.0 release is going to be. Thanks for all your efforts and insights! 
> 
> LOL, I'm not surprised. Our tag-team optimization of Bitsy Bye in 2016 was epic. 
> 
> I look forward to the next rev of Plasma. Please let me know when it is up.
> 
> -JB
> @JBrooksBSI
 
Will do. I still have to return to the Apple /// and Apple 1 VMs and test those out.

Dave...

[toc] | [prev] | [next] | [standalone]


#4132

Frommartin_haye <martin.haye@gmail.com>
Date2018-01-21 11:24 -0800
Message-ID<de1a0d15-69aa-44e0-93bc-a080fd2bc61f@googlegroups.com>
In reply to#4123
Loving this thread and very much looking forward to the speedup to Lawless Legends' PLASMA code (and there's a lot of it). I'm late to the party and probably won't stay long but the following stuck out:

> Simply remove the BNE NEXTOPH from FETCHOP, then rewrite INC_IP as:
>         !MACRO  INC_IP  {
>         INY
>         BPL     +
>         INC    IPH
>         TYA
>         AND     #$7F
>         TAY
> +
>         }

This can't be right, can it? If there's a sequence of boring instructions say 130 bytes long, this will incorrectly jump to the next page and miss the last two instructions. Or am I reading it wrong?

Something like the following would do the trick I think:

 INY
 BPL +
 TYA
 AND #$7F
 TAY
 LDA IPL
 EOR #$80
 STA IPL
 BMI +
 INC IPH
+

--Martin

[toc] | [prev] | [next] | [standalone]


#4133

FromDavid Schmenk <dschmenk@gmail.com>
Date2018-01-21 11:44 -0800
Message-ID<bae7d13c-fba9-4f74-b926-1386524e69f9@googlegroups.com>
In reply to#4132
On Sunday, 21 January 2018 11:24:12 UTC-8, martin_haye  wrote:
> Loving this thread and very much looking forward to the speedup to Lawless Legends' PLASMA code (and there's a lot of it). I'm late to the party and probably won't stay long but the following stuck out:
> 
> > Simply remove the BNE NEXTOPH from FETCHOP, then rewrite INC_IP as:
> >         !MACRO  INC_IP  {
> >         INY
> >         BPL     +
> >         INC    IPH
> >         TYA
> >         AND     #$7F
> >         TAY
> > +
> >         }
> 
> This can't be right, can it? If there's a sequence of boring instructions say 130 bytes long, this will incorrectly jump to the next page and miss the last two instructions. Or am I reading it wrong?
> 
> Something like the following would do the trick I think:
> 
>  INY
>  BPL +
>  TYA
>  AND #$7F
>  TAY
>  LDA IPL
>  EOR #$80
>  STA IPL
>  BMI +
>  INC IPH
> +
> 
> --Martin

No, I had it wrong. I fixed it to be (flattens IP+Y):

!MACRO  FIXJMP_IP   .TARGET {
        BMI     +
        JMP     .TARGET
+       TYA
        CLC
        ADC     IPL
        STA     IPL
        BCC     +
        INC     IPH
+       LDY     #$00
        JMP     .TARGET
        }

It is preceded by INY and goes at the end of the opcode, which is why there is a target to jump to (NEXTOP or DROP for now). Good eye as always, Martin. I was originally going to say that LL wouldn't need an update of the VM, but it's going to be *really* good when 1.0 arrives.

Dave...

[toc] | [prev] | [next] | [standalone]


#4134

FromDavid Schmenk <dschmenk@gmail.com>
Date2018-01-21 11:47 -0800
Message-ID<f9ff9b68-19d4-4e17-acd3-8f4178417be4@googlegroups.com>
In reply to#4133
On Sunday, 21 January 2018 11:44:17 UTC-8, David Schmenk  wrote:
> On Sunday, 21 January 2018 11:24:12 UTC-8, martin_haye  wrote:
> > Loving this thread and very much looking forward to the speedup to Lawless Legends' PLASMA code (and there's a lot of it). I'm late to the party and probably won't stay long but the following stuck out:
> > 
> > > Simply remove the BNE NEXTOPH from FETCHOP, then rewrite INC_IP as:
> > >         !MACRO  INC_IP  {
> > >         INY
> > >         BPL     +
> > >         INC    IPH
> > >         TYA
> > >         AND     #$7F
> > >         TAY
> > > +
> > >         }
> > 
> > This can't be right, can it? If there's a sequence of boring instructions say 130 bytes long, this will incorrectly jump to the next page and miss the last two instructions. Or am I reading it wrong?
> > 
> > Something like the following would do the trick I think:
> > 
> >  INY
> >  BPL +
> >  TYA
> >  AND #$7F
> >  TAY
> >  LDA IPL
> >  EOR #$80
> >  STA IPL
> >  BMI +
> >  INC IPH
> > +
> > 
> > --Martin
> 
> No, I had it wrong. I fixed it to be (flattens IP+Y):
> 
> !MACRO  FIXJMP_IP   .TARGET {
>         BMI     +
>         JMP     .TARGET
> +       TYA
>         CLC
>         ADC     IPL
>         STA     IPL
>         BCC     +
>         INC     IPH
> +       LDY     #$00
>         JMP     .TARGET
>         }
> 
> It is preceded by INY and goes at the end of the opcode, which is why there is a target to jump to (NEXTOP or DROP for now). Good eye as always, Martin. I was originally going to say that LL wouldn't need an update of the VM, but it's going to be *really* good when 1.0 arrives.
> 
> Dave...

Oh, one other thing. I didn't catch it originally - I was a little excited to get it in to the VM, but the code never ran because no sequence of opcodes was long enough without a branch or call (which re-normalize the IP).

Dave...

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.sys.apple2.programmer


csiph-web