View unanswered posts | View active topics It is currently Thu Mar 28, 2024 11:24 pm



Reply to topic  [ 52 posts ]  Go to page 1, 2, 3, 4  Next
 PLASMA virtual machine on the OPC6 
Author Message

Joined: Sat Aug 05, 2017 6:57 pm
Posts: 26
BigEd pointed me at the OPC project (https://revaldinho.github.io/opc/) and I thought it might be interesting to try porting the PLASMA virtual machine (https://github.com/dschmenk/PLASMA).

I've also ported PLASMA to the Acorn BBC Micro (and continue to tinker with that port); there's a thread about that over on stardot. I'm going to write about PLASMA as though I'm talking about the Apple version here, even though I'm more familiar with the Acorn port, and I hope I won't make any egregious mistakes as a result.

BigEd and I thought it would be best if I created a new thread for this so as not to mix it in too closely with that "Notes on the OPC5" thread; I hope this is OK.

The port is currently extremely primitive but I have a virtual machine which is capable of executing a trivial PLASMA program:
Code:
const addr1 = $4000
const addr2 = $4003
*addr1 = $1234
*addr2 = $6789
done

That compiles into the following PLASMA bytecodes:
Code:
        ; !BYTE $2C,$34,$12             ; CW    4660
        ; !BYTE $7A,$00,$40             ; SAW   16384
        ; !BYTE $2C,$89,$67             ; CW    26505
        ; !BYTE $7A,$03,$40             ; SAW   16387
        ; !BYTE $00                     ; ZERO
        ; !BYTE $5C                     ; RET

Those bytecodes are simply hand-coded into the virtual machine at this point.

The code is on github at https://github.com/ZornsLemma/PLASMA-OPC6 and can be executed as follows:
Code:
~/src/PLASMA-opc6$ python opc6asm.py plasma.s plasma.o > /dev/null
~/src/PLASMA-opc6$ python opc6emu.py plasma.o mem > /dev/null
~/src/PLASMA-opc6$ python annotate.py mem | grep ^a000
a000: 1234 8900 0067 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000


Even this basic port has already raised some issues so I'd be interested in thoughts on this.

The OPC6 is a word-addressed architecture, whereas PLASMA is designed for the 6502 and assumes byte addressing. It's expected in PLASMA code that you can take the address of a variable, store it in a 16-bit word and read/write through it as either a byte or word pointer. Reading through the address of a word as a byte pointer gives the low byte, if you add one to the pointer you get the high byte.

PLASMA effectively has a split code and data space model (simplifying slightly); this allows the 128K Apple II version to execute bytecodes from one 64K bank while using the other 64K bank for user program data (and the OS, screen, etc).

Given these two observations, it seems natural to me to implement PLASMA for the OPC6 like this:
  • PLASMA bytecode is packed two bytes to a word; this is slightly inconvenient but not terrible, and it avoids doubling the code size.
  • We use (up to) 32Kwords (=64Kbytes) of the OPC6 address space starting at 0x8000 as the PLASMA data space; PLASMA just doesn't allow a larger data space given the "pointers are 16-bit" assumption already noted. Each OPC6 word holds two bytes of PLASMA data space; this is why the above sample execution shows the contents of words starting at 0xa000 - PLASMA data space address $4000 corresponds to the low byte of word 0x8000+(0x4000>>1)=0xa000, data space address $4001 corresponds to the high byte of word 0xa000, etc. When the VM reads and writes PLASMA's data space, it has to translate the byte address into a word address, masking and shifting as appropriate.
  • The rest of the OPC6 address space is used for the PLASMA VM itself and bytecodes. Because PLASMA already has a split code and data space model, it isn't a problem that the program running on the VM can't read and write to the bytecode area. Loading a PLASMA module would have to be done at least in part using OPC6 code, of course - perhaps involving nothing more than a suitable implementation of the memxcpy() function.
This gives a "big" PLASMA (64Kbytes of data and probably 50-60Kbytes of bytecodes simultaneously, assuming a full 64Kword OPC6 machine) at the cost of performance. However, it's not clear to me that a model where we say "let's pretend OPC6 is byte-addressed and just use the low half of each word" would be much of an improvement - a lot of PLASMA opcodes are word-oriented and we'd still end up assembling PLASMA words out of pairs of adjacent OPC words-treated-as-bytes.

I am not sure how OPC6 native code in a user's program (PLASMA "asm" functions) would work. In 6502 PLASMA such functions have to be relocatable (no absolute addresses) and are loaded into and executed from the data space; the relocatable requirement isn't too onerous as it only prevents the use of JMP and JSR (except to fixed addresses like OS entry points). My very limited experience with the OPC6 suggests that it's probably possible to write relocatable code by using PC-relative addressing, but I am not sure. On the 128K Apple II, "asm" functions are loaded into the data space - it may be that this restriction is unnecessary on the OPC6, given that the address space is actually flat and the OPC6 can execute native code from any of the 64Kwords of memory, although it might be that it simplifies the port to retain this behaviour. I am probably overlooking a lot of things here and if the port progresses that far it will probably be clearer nearer the time what's possible and/or easy.

Thoughts on OPC6 so far:
  • I half wish the assembler allowed writing things like 'add r1, #1' instead of 'add r1, r0, 1' but I'm already getting used to it and I guess it's not a big deal/keeps you closer to the hardware.
  • It's really nice to have so many registers!
  • I was never a very good ARM programmer but there is a nice ARM flavour about it.
  • Working on a word-oriented architecture feels no different to byte-oriented 90% of the time, then it's a bit of a jolt the other 10% of the time. (I've only really had experience with assembly language on the 6502 and ARM before.)
  • It would be really handy if the assembler had a directive which allowed you to assemble byte data packed into words. As it is, I've had to translate PLASMA bytecode in the form '!BYTE $2C,$34,$12, $7A,$00,$40' by hand to 'WORD 0x342c, 0x7a12, 0x4000' which is tedious and error prone. I guess I could write a preprocessor to do this for me, though, and having it in the actual assembler might go against the "one page" concept.
  • At this early stage of development it's quite refreshing to be debugging against an emulator which shows every single instruction executed and all the register values. I'm sure this will not be so pleasant with a bigger program and a lurking bug though. :-)

Edited to add: feedback on my OPC6 coding style welcome, especially before I write more code! Performance tips also appreciated, but if they're "tricky" I may temporarily ignore them until I have a working-but-slow VM, at which point optimising it becomes a bit more interesting.


Sat Aug 05, 2017 8:04 pm
Profile

Joined: Tue Feb 10, 2015 7:07 am
Posts: 52
Hi Steve,

I've very pleased to see you taking an interest in OPC. I've been meaning to learn more about Plasma, and this seems like an excellent opportunity.

Thanks also for the feedback on the assembler (which is Rev's department).

We do have an 64K-word OPC6 Beeb Co Processor (in a GOP FPGA Module), and a PiTubeDirect version of the older OPC5LS which will be update to OPC6 soon. So if you fancy moving from the Emulator to "real" hardware just give us a shout.

Dave


Sat Aug 05, 2017 9:09 pm
Profile

Joined: Tue Apr 25, 2017 7:33 pm
Posts: 32
Hi Steve

Welcome to the OPC project!

As a welcome present I can grant one of your wishes: I just pushed a new version of the assembler with the BYTE directive.

- each BYTE directive starts a new data word
- multiple fields allowed, ordered low byte, high byte
- providing odd numbers of fields results in high byte of the last word being zeroed.
- as usual each field can be a python expression and can reference any symbols/labels defined in the assembler source

Probably easiest to see some examples:
Code:
009a                                ORG 0x1234
                         L0:
1234  00aa                          BYTE 0xAA
1235  2211                          BYTE 0x11, 0x22
1236  4433 0055                     BYTE 0x33, 0x44, 0x55
1238  7766 9988                     BYTE 0x66, 0x77, 0x88, 0x99
123a  001f 1234                     BYTE int(3.14 * 10),0x00, L0&0xff,(L0>>8)&0xFF

Hopefully that's what you were after. If not I can tweak it a bit. And no worries, it didn't break the one page limit. :)

Oh, just one thing - oversized fields get silently truncated to 8 bits .. error checking not the strongest suite of the assembler right now but I have added more checks recently and maybe can squeeze in a warning for this too.

Rich


Sat Aug 05, 2017 10:43 pm
Profile

Joined: Sat Aug 05, 2017 6:57 pm
Posts: 26
Thanks Revaldinho!

That looks like nearly what I want. Is it possible to not "pad" up to word sizes straight away? In your example you have:
Code:
1234  00aa                          BYTE 0xAA

What I would like to do would be able to write:
Code:
1234    aa                          BYTE 0xAA
1234  bbaa                          BYTE 0xBB

The reason I say this is that the PLASMA compiler outputs bytes in "logical" groupings, not necessarily word groupings:
Code:
        !BYTE   $64,$02                 ; LLB   [2]
        !BYTE   $2C,$00,$20             ; CW    8192
        !BYTE   $5E,$FF                 ; CFFB  65535

I appreciate this might be difficult, and it might be made worse by the fact that there can be WORD directives which need to be packed tightly with adjacent BYTE directives:
Code:
        !BYTE   $6C,$02                 ; DLB   [2]
        !BYTE   $4C                     ; BRFLS _B137
        !WORD   _B137-*
        !BYTE   $64,$02                 ; LLB   [2]

(The '*' means 'PC'; that !WORD is inlining a 16-bit relative offset for the branch target.)

My plan for this project is not to modify the PLASMA compiler itself if I can help it, and to lightly post-process its output to turn the bytecode assembler (which is just a stream of labels, !BYTE and !WORD directives to the acme assembler) into OPC6 assembler.

If you can handle this, that would be great. If you can't, I am thinking it may actually make more sense to "assemble" the bytecode with the standard PLASMA assembler (acme) and then just merge that data into the output of the OPC6 assembler.

Even if you can't do this more involved stuff, I think what you've done already is useful, provided it doesn't bloat the assembler too much. It will certainly be useful for hand-inlining bytecode during early development of the PLASMA VM (no more manual byte-swapping!), and I could imagine it might be useful for other programs too, whereas this "packed" byte stuff might not be so generally useful.


Sat Aug 05, 2017 10:55 pm
Profile

Joined: Wed Jan 09, 2013 6:54 pm
Posts: 1780
Great to see you here Steve and a cracking start! I'll try and address some of your questions when I feel up to the challenge. Very glad you like the look and feel of the machine.


Sun Aug 06, 2017 8:48 am
Profile

Joined: Sat Aug 05, 2017 6:57 pm
Posts: 26
Thanks hoglet and BigEd.

hoglet - it would be lovely to see this on real hardware, but I guess there's a long way to go yet and (fortunately) a lot of mileage left in the emulator. Perhaps my personal end goal would be to be able to get the firmware on my matchbox co-pro updated and see PLASMA running on it under the OPC6. :-)


Sun Aug 06, 2017 12:22 pm
Profile

Joined: Tue Apr 25, 2017 7:33 pm
Posts: 32
Steve,

I think that what you're after for BYTE and WORD sounds a bit tricky to fit in the one-page assembler. Basically it looks like you're asking for both the BYTE and WORD directives to assume no word alignment at all. and in a word oriented machine that's one of the short cuts I've taken in order to fit the assembler in the self-imposed 66 line 'one-page' limit. Let me have a quick think about this, but probably what's needed here is to breakout a custom version of the assembler without the lines of code limit. It is beginning to look a bit daft that you are putting in a lot of effort on the PLASMA VM and elsewhere Rob is bringing up a C compiler yet both might be hamstrung a bit by the tiny assembler. :o

Rich

EDIT - hang on, do labels need to be byte addresses rather than word addresses too ?


Sun Aug 06, 2017 12:41 pm
Profile

Joined: Wed Jan 09, 2013 6:54 pm
Posts: 1780
(Does PLASMA bytecode have a NOP? Could that be zero? It would be a computationally cheap way of aligning these BYTE sequences, at the cost of some code density.)


Sun Aug 06, 2017 12:51 pm
Profile

Joined: Sat Aug 05, 2017 6:57 pm
Posts: 26
Thanks guys.

Revaldinho - yes, the labels (in the PLASMA bytecode) need to be byte-aligned too, because they're used to mark branch destinations and you can branch to any opcode whether it's on a word boundary or not. I appreciate this is a big ask in a minimal assembler for a word-oriented machine, so please do have a think but I can work round it if it's going to cause you problems. I'm happy to use an alternate assembler if you wish to create one, of course!

Edited to add: I think I see what you're getting at. The labels would have "fractional" values as far as the OPC6 assembler is concerned, as it numbers consecutive words with consecutive integers. I can see that getting messy, but if you think it can be done it would be appreciated. If not, this may mean I need to continue to use the acme assembler to assemble bytecode rather than convert it to OPC6 assembler, which could also get messy where OPC6 assembly code and PLASMA bytecode are mixed in the same module. Hmm. For the moment let me hope you feel you can do an assembler which is able to allow labels to have values 1, 1.5, 2, ... and provides a "byte difference" function (take the difference between two word labels, and multiply by two) for use with them. :-)

BigEd - there's no explicit NOP, and having had a look over the opcode list I can't see any one-byte opcode which could be pressed into service (probably not too surprising). I could of course add a custom one-byte NOP solely for this implementation (if I used an odd-valued opcode for it it could never clash with a real 6502 PLASMA opcode, or I could just assign an unused value for the moment) and that might be an option.

A halfway house would be to add a custom one-byte NOP opcode and allow the postprocessor taking the PLASMA compiler output and turning it into OPC6 assembler to introduce the one byte NOP where necessary. I'd hope that the postprocessor wouldn't ever need to do that though; it could just introduce a byte of junk after RET/LEAVE at the end of a function to ensure the following function starts at a word address.

My inclination for the moment is to wait and see if Revaldinho can come up with anything after a think. I'm probably going to have to write a minimal postprocessor for the PLASMA compiler output anyway but exactly what it does will depend on what capabilities can be added to the OPC6 assembler. I don't think this is going to be a show-stopper one way or another.

In the meantime I can always continue to add a few of the missing opcodes here and there to the VM implementation, so it's not like this is going to be a blocker - what Revaldinho has already done will make it way more convenient to manually tweak the opcodes hardcoded into the prototype VM.


Sun Aug 06, 2017 1:06 pm
Profile

Joined: Tue Feb 10, 2015 7:07 am
Posts: 52
SteveF wrote:
hoglet - it would be lovely to see this on real hardware, but I guess there's a long way to go yet and (fortunately) a lot of mileage left in the emulator. Perhaps my personal end goal would be to be able to get the firmware on my matchbox co-pro updated and see PLASMA running on it under the OPC6. :-)

This afternoon I added OPC6 support to PiTibeDirect (in a branch for now):
https://github.com/hoglet67/PiTubeDirect/commits/opc6

The advantage of this over the matchbox (or our dedicated GOP implementation) is that it had an integrated debugger. So you can single step, set breakpoints or watchpoints, disassemble, dump registers, etc. The debugger is modelled on the debugger in B-Em, and in fact shares a common interface.

This is the OPC6 CPU emulation code:
https://github.com/hoglet67/PiTubeDirec ... pc6/opc6.c

A tad more than a page, but quite quick to read.

Do you have a PiTubeDirect?

Dave

P.S. Here's a sample debug session:
Code:
Raspberry Pi Direct 11 OPC6 Client
             cycle counter = 29461332800
              I_CACHE_MISS = 84770758
              D_CACHE_MISS = 134263
tube reset - copro 11
>>
>> help
PiTubeDirect debugger
    cpu = OPC6
Commands:
    help
    continue
    step
    next
    regs
    traps
    dis
    fill
    crc
    mem
    rd
    wr
    trace
    clear
    list
    breakx
    watchx
    breakr
    watchr
    breakw
    watchw
    in
    out
    breaki
    watchi
    breako
    watcho
>> break 1000
Exec breakpoint set at 1000
cpu: OPC6 debug enable = 1
Exec breakpoint hit at 1000
1000 10ee ffff : mov r14, r14, 0xffff
>> s
Stepping 1 instructions
1002 16ed 0001 : sto r13, r14, 0x0001
>> s
Stepping 1 instructions
1004 1001 004f : mov r1, r0, 0x004f
>> r
      R0 = 0000
      R1 = 0080
      R2 = 0030
      R3 = 0008
      R4 = 0000
      R5 = 0000
      R6 = 0000
      R7 = 0000
      R8 = 0000
      R9 = 0000
     R10 = 0000
     R11 = 0000
     R12 = 0040
     R13 = f9fd
     R14 = f7fb
      PC = 1004
     PSR = SWI:0 EI:1 S:1 C:1 Z:0
  PC_int = ff2e
 PSR_int = 000b
>> s
Stepping 1 instructions
1006 10fd 0002 : mov r13, r15, 0x0002
>> r
      R0 = 0000
      R1 = 004f
      R2 = 0030
      R3 = 0008
      R4 = 0000
      R5 = 0000
      R6 = 0000
      R7 = 0000
      R8 = 0000
      R9 = 0000
     R10 = 0000
     R11 = 0000
     R12 = 0040
     R13 = f9fd
     R14 = f7fb
      PC = 1006
     PSR = SWI:0 EI:1 S:0 C:1 Z:0
  PC_int = ff2e
 PSR_int = 000b
>> watcho fef9
IO Wr watchpoint set at fef9
>> c
Running
IO Wr watchpoint hit at fb06 : fef9 = 4f
IO Wr watchpoint hit at fb06 : fef9 = 6b
IO Wr watchpoint hit at fb06 : fef9 = 20
IO Wr watchpoint hit at fb06 : fef9 = 33
IO Wr watchpoint hit at fb06 : fef9 = 2e
IO Wr watchpoint hit at fb06 : fef9 = 31
IO Wr watchpoint hit at fb06 : fef9 = 34
IO Wr watchpoint hit at fb06 : fef9 = 31
IO Wr watchpoint hit at fb06 : fef9 = 35
IO Wr watchpoint hit at fb06 : fef9 = 39
IO Wr watchpoint hit at fb06 : fef9 = 2a
>> s10
Stepping 10 instructions
ff2c 1101 0080 : and r1, r0, 0x0080
ff2e 500f ff2a : z.mov r15, r0, 0xff2a
ff2a 3701 fefa : in r1, r0, 0xfefa
ff2c 1101 0080 : and r1, r0, 0x0080
ff2e 500f ff2a : z.mov r15, r0, 0xff2a
ff2a 3701 fefa : in r1, r0, 0xfefa
ff2c 1101 0080 : and r1, r0, 0x0080
ff2e 500f ff2a : z.mov r15, r0, 0xff2a
ff2a 3701 fefa : in r1, r0, 0xfefa
ff2c 1101 0080 : and r1, r0, 0x0080


Sun Aug 06, 2017 7:10 pm
Profile

Joined: Sat Aug 05, 2017 6:57 pm
Posts: 26
Cheers Dave, that looks pretty cool. Unfortunately I don't have the space for any of my Acorn stuff in my flat, so I have to stick with emulators on a day to day basis. It sounds like this work might in principle be re-usable to add an OPC6 co-processor to b-em though, right? (Just to be clear - that would be nice to have, but I don't need anything like that to progress with this port. I think there's still a lot of mileage in the basic Python emulator for this port, especially with a bit of judicious hacking to do a simple OSFILE emulation to allow loading a file into the OPC6 memory at run time.)


Sun Aug 06, 2017 9:28 pm
Profile

Joined: Tue Feb 10, 2015 7:07 am
Posts: 52
SteveF wrote:
Cheers Dave, that looks pretty cool. Unfortunately I don't have the space for any of my Acorn stuff in my flat, so I have to stick with emulators on a day to day basis. It sounds like this work might in principle be re-usable to add an OPC6 co-processor to b-em though, right? (Just to be clear - that would be nice to have, but I don't need anything like that to progress with this port. I think there's still a lot of mileage in the basic Python emulator for this port, especially with a bit of judicious hacking to do a simple OSFILE emulation to allow loading a file into the OPC6 memory at run time.)

Yes, it could be added to B-Em at some point.

Give me a shout if that becomes necessary.

Dave


Sun Aug 06, 2017 9:34 pm
Profile

Joined: Tue Apr 25, 2017 7:33 pm
Posts: 32
Steve

Quote:
Yes, the labels (in the PLASMA bytecode) need to be byte-aligned too, because they're used to mark branch destinations and you can branch to any opcode whether it's on a word boundary or not. I appreciate this is a big ask in a minimal assembler for a word-oriented machine, so please do have a think but I can work round it if it's going to cause you problems. I'm happy to use an alternate assembler if you wish to create one, of course!

Edited to add: I think I see what you're getting at. The labels would have "fractional" values as far as the OPC6 assembler is concerned, as it numbers consecutive words with consecutive integers. I can see that getting messy, but if you think it can be done it would be appreciated. If not, this may mean I need to continue to use the acme assembler to assemble bytecode rather than convert it to OPC6 assembler, which could also get messy where OPC6 assembly code and PLASMA bytecode are mixed in the same module. Hmm. For the moment let me hope you feel you can do an assembler which is able to allow labels to have values 1, 1.5, 2, ... and provides a "byte difference" function (take the difference between two word labels, and multiply by two) for use with them. :-)

[snip]
I'm probably going to have to write a minimal postprocessor for the PLASMA compiler output anyway but exactly what it does will depend on what capabilities can be added to the OPC6 assembler. I don't think this is going to be a show-stopper one way or another.

In the meantime I can always continue to add a few of the missing opcodes here and there to the VM implementation, so it's not like this is going to be a blocker - what Revaldinho has already done will make it way more convenient to manually tweak the opcodes hardcoded into the prototype VM.


After a little bit of hacking about with the assembler code I think that probably the alternate assembler is the best approach. Fundamentally OPC-6 is a word oriented machine and the existing code is the simple assembler to go with it. So, rather that try and make that deal with lots of unaligned data and labels, it's probably better to do a rewrite from the ground up in a byte oriented fashion where the bytes of all sorts are only assembled into words at the very end of the process when writing out the hex file. I think that would work except I'm still a little confused on the labels. Byte labels are needed only for the VM bytecode but make no sense for the OPC instructions where they would always need to be word addresses. Would it be the case that the OPC instructions never need to refer to unaligned VM byte labels (i.e. can always assume that they are aligned to word boundaries) ? It might be easiest to just dive in and get a byte oriented assembler up and running and then deal with the VM/OPC labels later... I think that would be my approach. So, if you're good to continue for a while with your workarounds that would be great. I will have a go at making a second version of the assembler, but I'm away for a bit from the end of this week and unlikely to have got it done before then.

R


Sun Aug 06, 2017 9:55 pm
Profile

Joined: Sat Aug 05, 2017 6:57 pm
Posts: 26
Revaldinho wrote:
After a little bit of hacking about with the assembler code I think that probably the alternate assembler is the best approach. Fundamentally OPC-6 is a word oriented machine and the existing code is the simple assembler to go with it. So, rather that try and make that deal with lots of unaligned data and labels, it's probably better to do a rewrite from the ground up in a byte oriented fashion where the bytes of all sorts are only assembled into words at the very end of the process when writing out the hex file. I think that would work except I'm still a little confused on the labels. Byte labels are needed only for the VM bytecode but make no sense for the OPC instructions where they would always need to be word addresses. Would it be the case that the OPC instructions never need to refer to unaligned VM byte labels (i.e. can always assume that they are aligned to word boundaries) ? It might be easiest to just dive in and get a byte oriented assembler up and running and then deal with the VM/OPC labels later... I think that would be my approach. So, if you're good to continue for a while with your workarounds that would be great. I will have a go at making a second version of the assembler, but I'm away for a bit from the end of this week and unlikely to have got it done before then.

Thanks for giving this some thought. I think you're right that the OPC instructions would never need to refer to unaligned labels in the VM bytecode - after all, the OPC instructions are word-oriented. Those labels are just needed for calculating offsets between two points in the byte stream, which is just data as far as the assembler is concerned. What I'd ideally like to be able to do is write something like this:
Code:
    BYTE 0x01
foo: # unaligned label
    BYTE 0x02
    BYTE 0x03
    WORD bytediff(foo-*) # effectively bytediff(foo-*) is -2 or 0xfffe, so this is equivalent to BYTE 0xfe, 0xff
    BYTE 0x04
    BYTE 0x05

and have it be equivalent to writing:
Code:
    BYTE 0x01, 0x02, 0x03, 0xfe, 0xff, 0x04, 0x05

The bytediff() function is just an example, I wouldn't mind if it was 2*(foo-*) because non-word-aligned labels have values of the form n.5 or something completely different.

I've added a few more opcode implementations to the VM today but I don't expect progress to be rapid, especially now the weekend is over, so please don't rush to do anything about this. Just having the BYTE directive is already helping a lot, and I think I can happily use that plus a few other workarounds to get quite a lot further.

Thanks again!

Steve


Sun Aug 06, 2017 10:30 pm
Profile

Joined: Sat Aug 05, 2017 6:57 pm
Posts: 26
I appreciate this might be a stupid question, but I know this can be subtle on the 6502 at least so I'm going to ask rather than guess and get it subtly wrong on the OPC6...

How do I do signed and unsigned word comparisons? In other words, how would the following C-ish snippets be translated into OPC6 assembler?
Code:
int r0, r1, r2
if (r0 < r1) { r2 = 1; } else { r2 = 0; }

Code:
unsigned int r0, r1, r2
if (r0 < r1) { r2 = 1; } else { r2 = 0; }

Thanks!

Steve

PS Gradual progress on the PLASMA VM, doing a few VM opcodes here and there. Having to resist the temptation to optimise a bit - I want to keep it as close in spirit to the 6502 version as I can for now so as to reduce the scope for subtle bugs, it can always be tweaked once it's capable of running big programs and is easier to test. I suspect the VM implementation itself is going to be no big deal from here, but that the loadmod() implementation is going to be a bit of a mind-bender with the way I've decided to split the address space up. I'm sure it can be made to work, it just might not work first time. :-) But I've got a fair few VM opcodes to do before I have to worry about that anyway...


Tue Aug 08, 2017 9:35 pm
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 52 posts ]  Go to page 1, 2, 3, 4  Next

Who is online

Users browsing this forum: AhrefsBot and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software