Each of those longs in the table executes as an instruction, in place of the NOP in the interpreter loop. For most bytecodes, more needs to be accomplished than what can happen in one instruction, so a CALL is placed in the LUT table. The return address is the 'jmp #inst' in the main loop.

Most operations wind up being just one in-lined instruction. The more complex stuff CALLs to routines.

This '_RET_' is an implied return that uses code %0000 of the conditional field. This means NOP cannot be $00000000, anymore, as it would become a RET instruction. Having implied RET's saves lots of instructions, especially in a situation like this where you have lots of snippets of code that get CALL'd. Each _RET_ saves two clocks and a long.

If the _RET_ is used on a branch instruction, the branch instruction takes precedence, unless the branch doesn't occur. Then, the _RET_ happens. Here are two routines from one of the VGA demos:

The %0000 code was not very useful. Any instruction that had that would never execute. There might have been some utility in it, but it's way more useful being used as an 'always' condition, like %1111, but with some special behavior.

The %0000 code was not very useful. Any instruction that had that would never execute. There might have been some utility in it, but it's way more useful being used as an 'always' condition, like %1111, but with some special behavior.

The %0000 code was not very useful. Any instruction that had that would never execute. There might have been some utility in it, but it's way more useful being used as an 'always' condition, like %1111, but with some special behavior.

The %0000 code was not very useful. Any instruction that had that would never execute. There might have been some utility in it, but it's way more useful being used as an 'always' condition, like %1111, but with some special behavior.

The %0000 code was not very useful. Any instruction that had that would never execute. There might have been some utility in it, but it's way more useful being used as an 'always' condition, like %1111, but with some special behavior.

True but what is the instruction encoding for NOP now?

I was thinking 'WAITX #0'.

What about making blank Flash a NOP, which means 0xffffffff ?

That would be 'AUGD #all_ones'. This NOP thing is the biggest problem now.

The %0000 code was not very useful. Any instruction that had that would never execute. There might have been some utility in it, but it's way more useful being used as an 'always' condition, like %1111, but with some special behavior.

That would be 'AUGD #all_ones'. This NOP thing is the biggest problem now.

There are likely plenty of opcodes that can alias to a NOP, but it is nice to have blank memory behave in a predictable manner too.
What happens now, if an errant branch lands on a whole chain of 'AUGD #all_ones' ?

That would be 'AUGD #all_ones'. This NOP thing is the biggest problem now.

There are likely plenty of opcodes that can alias to a NOP, but it is nice to have blank memory behave in a predictable manner too.
What happens now, if an errant branch lands on a whole chain of 'AUGD #all_ones' ?

They pretty much are NOPs. The next instruction afterward, though, with a literal D would get the top 27 bits as highs. May or may not be a problem.

Another option would be to swap the _ret_ prefix and the ALWAYS prefix, so that 0 is ALWAYS, and then re-arrange the opcodes so that instruction field 0 is something like AND or OR; that way 00000000 would be AND 0,0, which would work fine as a nop.

Or, don't bother re-arranging anything and just define NOP to be an alias for OR 0,0.

Wouldn't it actually be better if zero was something like "software reset"? Do you really want code that wanders off into uninitialized memory to just keep running? Wouldn't it be better for an embedded system if it reset to a known state?

Wouldn't it actually be better if zero was something like "software reset"? Do you really want code that wanders off into uninitialized memory to just keep running? Wouldn't it be better for an embedded system if it reset to a known state?

That's an excellent point. Possibly better would be to trigger a debug interrupt. Instead of a debugger, startup code could set the debug interrupt to call cogstop or whatever other behavior is desirable (cogatn a watchdog cog, for instance).

At which point, yeah, just make NOP an alias for an existing instruction.

Isn't 0x00 an ADD on x86 and a NEG on the 6809? Seem like NOP is all over the place on different architectures. It's invisible to people like me, because I have no idea what object code is being generated by the assembler. That's my $.002 (two tens of 1 cent)

It's not clear to me that having zero defined as software reset or debugger interrupt, etc helps much.

If your program is buggy and runs off into the weeds, those weeds are quite likely to be some other part of your code or your data somewhere, which it will then try to execute.

Yeah, it would only really help if you wandered off into memory that the boot up code had zeroed. On the other hand, I suspect zero is probably a pretty likely value in the weeds so you might not stop immediately but probably wouldn't get too far.

Well, changing NOP will break the code I'm working on and also garryj's USB code.
Could be fixed, but inconvenient...

One thing garryj did is load the top of his cog code with variables initialized to 0. As such, they are just NOPs and skipped over. Can't do this if NOP changes:

I did that once a couple of times, myself.

We just can't do that anymore.

My intent was to have a block of cog registers that were in a known fixed location to allow multiple USB host cogs to use the same register names. If this itself is a no-no (I never tested it), things can easily be changed. Or, wouldn't this fix the issue too? :

_ret_ only works if the internal call-stackpointer is not at bottom, otherwise it's ignored and therfore a NOP.
So as long as you not have done a CALL in your code, the %0000 condition works as a NOP and only inside subroutines it is a _ret_.