JohnPCAE Posted December 29, 2021 Author Share Posted December 29, 2021 (edited) Okay, I added a LOOP RD instruction, where RD can be in the range R0 ... R5. It decrements RD, and if RD is nonzero afterwards, acts as a branch (a displacement is added to R7). So far today's additions are: Unsigned multiplication (sets sign, zero, and overflow flags based on the result) MUL ADDR, RD ; RD = low word of [ADDR] * RD MUL@ RS, RD ; RD = low word of [RS] * RD MULI DATA, RD ; RD = low word of DATA * RD Signed multiplication (sets sign, zero, and overflow flags based on the result) IMUL ADDR, RD ; RD = low word of [ADDR] * RD IMUL@ RS, RD ; RD = low word of [RS] * RD IMULI DATA, RD ; RD = low word of DATA * RD ; Vector copy VMOV@ ADDR, RMD ; Copies a 3-vector consisting of three DWORDS from [ADDR] to [RMD] VMOV@@ RMS, RMD ; Copies a 3-vector consisting of three DWORDS from [RMS] to [RMD] VMOVI@ DATA, RMD ; Copies an immediate 3-vector consisting of three DWORDS to [RMD] ; Vector add VADD@ ADDR, RMD ; Adds a 3-vector consisting of three DWORDS from [ADDR] to [RMD] VADD@@ RMS, RMD ; Adds a 3-vector consisting of three DWORDS from [RMS] to [RMD] VADDI@ DATA, RMD ; Adds an immediate 3-vector consisting of three DWORDS to [RMD] ; Vector subtract VSUB@ ADDR, RMD ; Subtracts a 3-vector consisting of three DWORDS in [ADDR] from [RMD] VSUB@@ RMS, RMD ; Subtracts a 3-vector consisting of three DWORDS in [RMS] from [RMD] VSUBI@ DATA, RMD ; Subtracts an immediate 3-vector consisting of three DWORDS from [RMD] ; Loop LOOP RD ; Decements RD. If RD is nonzero afterward, branches (R7 += displacement). RD can be in the range R0 to R5. ; Conditional branches BA label ; Branch if above ((C or Z) = 0) BNA label ; Branch if not above ((C or Z) = 1) ; Add with carry ADCR RS, RD ; RD = RD + RS + C Edited December 29, 2021 by JohnPCAE 1 Quote Link to comment Share on other sites More sharing options...
JohnPCAE Posted December 30, 2021 Author Share Posted December 30, 2021 (edited) Here's what I've added so far. Opcode values are still subject to change. I have no idea if every one of these instructions can run in the time allotted to the Pi Pico, though. That will require testing. Now what would be REALLY awesome would be some enterprising individual making an FPGA-based CPU replacement that supported these extensions. You'll note some simple division instructions here. Since the Pico only has a multiply instruction and not a divide instruction, I can't put in a generic division instruction because there is no way it will complete in time. However, I can use the Pico's multiplication ability to implement some simple division instructions where the divisor is fixed. They're mainly useful for converting binary to decimal, and I threw in the divide-by-three instruction since it might be useful for other things. The SUBGER0 instruction, however, is very useful for a generic division routine written in CP-1600 assembly (see the FastDivide routine in my raycasting demo source for an example of the algorithm). 000001 0000 ... ddd ORx Src, RD ; RD |= Src 000001 0000 000 ddd OR RD, ADDR 000001 0000 sss ddd OR@ RS, RD ; RS = R1..R6 000001 0000 111 ddd ORI DATA, RD 000001 0001 ... ddd ADCx Src, RD ; RD += Src + C 000001 0001 000 ddd ADC RD, ADDR 000001 0001 sss ddd ADC@ RS, RD ; RS = R1..R6 000001 0001 111 ddd ADCI DATA, RD 000001 0010 ... ddd SBBx Src, RD ; RD -= (Src + C) 000001 0010 000 ddd SBB RD, ADDR 000001 0010 sss ddd SBB@ RS, RD ; RS = R1..R6 000001 0010 111 ddd SBBI DATA, RD 000001 0011 ... ddd TSTx Src, RD ; Sets the S and Z flags based on RS & Src 000001 0011 000 ddd TST RS, ADDR 000001 0011 sss ddd TST@ RS, RD ; RS = R1..R6 000001 0011 111 ddd TSTI DATA, RS 000001 0100 ... ddd SLLx Src, RD ; RD <<= Src 000001 0100 000 ddd SLL RD, ADDR 000001 0100 sss ddd SLL@ RS, RD ; RS = R1..R6 000001 0100 111 ddd SLL RD, DATA 000001 0101 ... ddd SLRx Src, RD ; RD >>= Src 000001 0101 000 ddd SLR RD, ADDR 000001 0101 sss ddd SLR@ RS, RD ; RS = R1..R6 000001 0101 111 ddd SLR RD, DATA 000001 0110 ... ddd SARx Src, RD ; RD = RD sar Src (arithmetic shift right) 000001 0110 000 ddd SAR RD, ADDR 000001 0110 sss ddd SAR@ RS, RD ; RS = R1..R6 000001 0110 111 ddd SAR RD, DATA 000001 0111 ... ddd ROLx Src, RD ; RD = RD rol Src 000001 0111 000 ddd ROL RD, ADDR 000001 0111 sss ddd ROL@ RS, RD ; RS = R1..R6 000001 0111 111 ddd ROL RD, DATA 000001 1000 ... ddd RORx Src, RD ; RD = RD ror Src 000001 1000 000 ddd ROR RD, ADDR 000001 1000 sss ddd ROR@ RS, RD ; RS = R1..R6 000001 1000 111 ddd ROR RD, DATA 000001 1001 ... ddd MULx Src, RD ; RD *= Src (unsigned multiply) 000001 1001 000 ddd MUL ADDR, RD 000001 1001 sss ddd MUL@ RS, RD ; RS = R1..R6 000001 1001 111 ddd MULI DATA, RD 000001 1010 ... ddd IMULx Src, RD ; RD *= Src (signed multiply) 000001 1010 000 ddd IMUL ADDR, RD 000001 1010 sss ddd IMUL@ RS, RD ; RS = R1..R6 000001 1010 111 ddd IMULI DATA, RD 000001 1011 sss ddd ORR RS, RD ; RD |= RS 000001 1100 sss ddd ADCR RS, RD ; RD += RS + C 000001 1101 sss ddd SBBR RS, RD ; RD -= (RS + C) 000001 1110 ddd ddd INCLR RD ; Increments only the low byte of RD. If RD was 255, it rolls ; over to 0 without affecting the high byte and sets the carry flag. 000001 1110 aaa bbb TSTR RA, RB ; aaa<>bbb. Sets the S and Z flags based on RA & RB 000001 1111 ddd aaa SLLR RD, RA ; RD <<= RA 000010 0000 ddd aaa SLRR RD, RA ; RD >>= RA 000010 0001 ddd aaa SARR RD, RA ; RD = RD sar RA 000010 0010 ddd aaa ROLR RD, RA ; RD = RD rol RA 000010 0011 ddd aaa RORR RD, RA ; RD = RD ror RA 000010 0100 sss ddd MULR RS, RD ; RD *= RS (RD gets only the low word of the result) 000010 0101 aaa bbb MULRW RA, RB ; R0:R1 = RA * RB (R0 = low word, R1 = high word) 000010 0110 sss ddd IMULR RS, RD ; RD *= RS (RD gets only the low word of the result) 000010 0111 aaa bbb IMULRW RA, RB ; R0:R1 = RA * RB (R0 = low word, R1 = high word) 000010 1000 ... ddd VMOVx Src, RDM ; sss <> ddd. v3d[RMD] = v3d[Src] ; Copies a 3-vector from [Src] to [RMD]. ; Each vector component is 32 bits. 000010 1000 000 ddd PPPP VMOV@ ADDR, RD ; ddd <> 0. alternate: VPSH ADDR if ddd = 6 000010 1000 sss ddd VMOV@@ RMS, RMD ; sss <> ddd. alternate: VPSH@ RS if ddd = 6 ; alternate: VPUL@ RD if sss = 6 000010 1000 111 ddd VMVOI@ DATA, RD ; ddd < 7. alternate: VPSH@ DATA if ddd = 6 000010 1000 ddd ddd LOOP RD ; ddd < 6. RD--, if RD is nonzero afterwards, R7 += disp 000010 1000 110 110 PPPP BA disp ; Branch if above (unsigned compare): branch if ((C or Z) = 0) ; alternate: BNBE (branch if not below or equal) ; Equivalent to x86 JA/JNBE 000010 1000 111 111 PPPP BNA disp ; Branch if not above (unsigned compare): branch if ((C or Z) = 1) ; alternate: BBE (branch if below or equal) ; Equivalent to x86 JNA/JBE 000010 1001 ... ddd VADDx Src, RMD ; v3d[RMD] += v3d[Src] ; Adds a 3-vector from [Src] to [RMD]. ; Each vector component is 32 bits. 000010 1001 000 ddd VADD@ ADDR, RMD 000010 1001 sss ddd VADD@@ RS, RMD 000010 1001 111 ddd VADDI@ DATA, RMD 000010 1010 ... ddd VSUBx Src, RMD ; v3d[RMD] += v3d[Src] ; Subtracts a 3-vector in [Src] from [RMD]. ; Each vector component is 32 bits. 000010 1010 000 ddd VSUB@ ADDR, RMD 000010 1010 sss ddd VSUB@@ R1, RMD 000010 1010 111 ddd VSUBI@ DATA, RMD 000010 1011 00b baa UNPR RB, RA ; RB = RA >> 8, RA &= 0xFF aa, bb = 0..3 ; Unpacks RA into RB:RA 000010 1011 01b baa PCKR RS, RD ; RA = (RA & 0xFF) | (RB >> 8) aa, bb = 0..3 ; Packs the low bytes of RB:RA into RA 000010 1011 100 ddd LOOPE RD ; RD--, ddd < 6, if RD is nonzero afterwards and if Z=1, R7 += disp 000010 1011 100 110 BREVR R0 ; R0 = bit-reversed R0 000010 1011 100 111 BREVR R1 ; R1 = bit-reversed R1 000010 1011 101 ddd LOOPNE RD ; RD--, ddd < 6, if RD is nonzero afterwards and if Z=0, R7 += disp 000010 1011 101 110 BREVR R2 ; R2 = bit-reversed R2 000010 1011 101 111 BREVR R3 ; R3 = bit-reversed R3 000010 1011 110 ddd LOOPS RD ; RD--, ddd < 6, if RD is nonzero afterwards and if S=1, R7 += disp 000010 1011 110 110 BREVR R4 ; R4 = bit-reversed R4 000010 1011 110 111 BREVR R5 ; R5 = bit-reversed R5 000010 1011 111 ddd LOOPNS RD ; RD--, ddd < 6, if RD is nonzero afterwards and if S=0, R7 += disp 000010 1011 111 110 COMC ; C = !C 000010 1011 111 111 STCP ; if R0 contains an odd number of 1 bits, C = 1, else C = 0 ; (sets carry as R0 parity) 000010 1100 00s sdd MAXR RS, RD ; RD = unsigned maximum of RS and RD. ss, dd = 0..3 000010 1100 01s sdd MINR RS, RD ; RD = unsigned minimum of RS and RD. ss, dd = 0..3 000010 1100 10s sdd IMAXR RS, RD ; RD = signed maximum of RS and RD. ss, dd = 0..3 000010 1100 11s sdd IMINR RS, RD ; RD = signed minimum of RS and RD. ss, dd = 0..3 000010 1101 000 ddd SBBR RD ; RD -= C 000010 1101 001 ddd B2AH RD ; RD = hexadecimal ASCII representation of the low byte of RD ; (e.g. 0x0A --> 3041 "0A") 000010 1101 dd aaaa SHLD RD, IMM4 ; RD = high word of RD:R0 shifted left by 0 .. 15. ; C = high bit of RD shifted out if amount > 0. dd=1..3 ; Equivalent to x86 SHLD using 16-bit operands 000010 1110 000 ddd AH2B RD ; RD = binary value (0..255) of hexadecimal ASCII characters ; stored in RD. Invalid characters in a byte result in that ; byte being interpreted as 0 (e.g. 3041 --> 0x0A, ; 2F41 --> 0x0A) 000010 1110 001 ddd DIV5 RD ; RD /= 5 (unsigned divide) 000010 1110 ss aaaa SHRD RS, IMM4 ; R0 = low word of RS:R0 shifted right by 0 .. 15. ; C = low bit of R0 shifted out if amount > 0. ss=1..3 ; Equivalent to x86 SHRD using 16-bit operands 000010 1111 000 ddd CL0R RD ; RD = number of consecutive 0 bits in RD starting at the MSB 000010 1111 001 ddd CL1R RD ; RD = number of consecutive 1 bits in RD starting at the MSB 000010 1111 010 ddd CT0R RD ; RD = number of consecutive 0 bits in RD starting at the LSB 000010 1111 011 ddd CT1R RD ; RD = number of consecutive 1 bits in RD starting at the LSB 000010 1111 100 ddd SUBGER0 RD ; if RD >= R0 (unsigned compare), RD -= R0. ; Useful for speeding up division algorithms. 000010 1111 101 ddd DIV3 RD ; RD /= 3 (unsigned divide) 000010 1111 110 ddd DIV100 RD ; RD /= 100 (unsigned divide) 000010 1111 110 ddd DUPLR RD ; RD = (RD & 0xFF) | (RD << 8) Duplicates the low byte in RD. 000011 0000 ddd ddd DECLR RD ; Decrements only the low byte of RD. If RD was 0, it rolls ; over to 255 without affecting the high byte and sets the carry flag. 000011 0000 aaa bbb XCHGR RA, RB ; aaa<>bbb. Swaps the contents of RA and RB 000011 0001 mmm ddd PPPP MVID@ RM, RD, disp ; RD = [RM + disp] ; Does ***not*** change R4 .. R6 if mmm=4..6. Supports SDBD. 000011 0010 mmm ddd PPPP MVOD@ RM, RD, disp ; [RM + disp] = RD ; Does ***not*** change R4 .. R6 if mmm=4..6. Supports SDBD. 000011 0011 000 ddd ABSR RD ; RD = |RD| 000011 0011 001 ddd POW2R RD ; RD = 1 << RD If RD > 15, result is 0 Edited December 30, 2021 by JohnPCAE Quote Link to comment Share on other sites More sharing options...
JohnPCAE Posted December 31, 2021 Author Share Posted December 31, 2021 (edited) There's a little typo in my description of PCKR. It should read: RA = (RA & 0xFF) | (RB << 8) Also: MVOD@ should be described as: MVOD@ RM, RS, disp ; [RM + disp] = RS Edited December 31, 2021 by JohnPCAE Quote Link to comment Share on other sites More sharing options...
+Lathe26 Posted December 31, 2021 Share Posted December 31, 2021 You should coordinate your instructions with Joe Zbiciak since the LTO has its own set of extended opcodes. Quote Link to comment Share on other sites More sharing options...
JohnPCAE Posted December 31, 2021 Author Share Posted December 31, 2021 Hmm. I'll have to remember to look at his opcodes to see if I can work around them. It might be tricky depending on what I find. On another note, I've had a breakthrough in optimizing my output code for size and I've managed to make some of it drastically smaller while still keeping it efficient enough to get the scanlines out in time. This freed up a lot of RAM and now I have a full 64k words (128k bytes) available for the shared video buffer/character RAM/emulator address space. Now I'm going through the emulator code trying to optimize it for speed. Quote Link to comment Share on other sites More sharing options...
JohnPCAE Posted January 1, 2022 Author Share Posted January 1, 2022 (edited) Happy New Year, everyone! I finished assembling rev. 1.1 of my board tonight. It's working, but it had a couple of minor errors that thankfully were easy to fix. The next board revision will correct them. This is the version that attempts a bidirectional parallel port. I got the nice purple one from a cheapo single-chip PCI parallel port card I picked up on ebay. I'm waiting for a breakout box that will make testing easy, but I did a preliminary test and I can get the Inty to at least read the status pins I'm only working on an NTSC version, since I don't have any PAL equipment. I can say, though, that a PAL version would require significant changes to the hardware. For NTSC I can get away with an 8-bit scan line counter, since the Inty only displays 192 scan lines. On PAL, however, an 8-bit counter isn't enough for all of the scan lines so the circuitry would have to change significantly. I also have no idea if the Pi Pico can keep up with PAL timing. It can barely get scan line data out for NTSC, so if PAL requires it to run any faster then it definitely won't work. Edited January 1, 2022 by JohnPCAE 2 Quote Link to comment Share on other sites More sharing options...
JohnPCAE Posted January 2, 2022 Author Share Posted January 2, 2022 (edited) Today's software update: now that I have 128k of RAM for the video buffer, it can support 640x191x256 graphics mode. Also, I've added some more screen modes, so this is the new list: #define SCREEN_MODE_40_COLS 0 #define SCREEN_MODE_80_COLS 1 #define SCREEN_MODE_160_96_2 2 #define SCREEN_MODE_160_96_16 3 #define SCREEN_MODE_160_96_256 4 #define SCREEN_MODE_160_96_TRUE16 5 #define SCREEN_MODE_160_96_TRUE32 6 #define SCREEN_MODE_160_191_2 7 #define SCREEN_MODE_160_191_16 8 #define SCREEN_MODE_160_191_256 9 #define SCREEN_MODE_160_191_TRUE16 10 #define SCREEN_MODE_160_191_TRUE32 11 #define SCREEN_MODE_320_96_2 12 #define SCREEN_MODE_320_96_16 13 #define SCREEN_MODE_320_96_256 14 #define SCREEN_MODE_320_96_TRUE16 15 #define SCREEN_MODE_320_96_TRUE32 16 #define SCREEN_MODE_320_191_2 17 #define SCREEN_MODE_320_191_16 18 #define SCREEN_MODE_320_191_256 19 #define SCREEN_MODE_320_191_TRUE16 20 #define SCREEN_MODE_640_96_2 21 #define SCREEN_MODE_640_96_16 22 #define SCREEN_MODE_640_96_256 23 #define SCREEN_MODE_640_96_TRUE16 24 #define SCREEN_MODE_640_191_2 25 #define SCREEN_MODE_640_191_16 26 #define SCREEN_MODE_640_191_256 27 #define SCREEN_MODE_MAX 27 There are some caveats to the new true-color modes. There are only a total of 640 NTSC timeslices per scan line, so when the screen width is 320 pixels, only two timeslice values are written per pixel. This will cause some blending of colors, though that would be the case regardless of the bit depth. Likewise, when the screen width is 640 pixels, only one timeslice value is written per pixel, which makes a true-color mode kind of pointless. It's also why 80-column text is so hard to read on a TV. The screen mode is there, regardless. Edited January 2, 2022 by JohnPCAE Quote Link to comment Share on other sites More sharing options...
JohnPCAE Posted January 3, 2022 Author Share Posted January 3, 2022 (edited) I'm honestly surprised that this works. For most of the bitmap graphics modes (not the text modes), you have the *option* of enabling sprite-exclusion. When you enable it, what the software does is quite involved and memory intensive: - allocates a block in the video buffer for a shadow copy of your display data. This will always be at a set location based on your screen mode. - copies your display raster data to the shadow area, doubling scan line data if necessary (if you're in a 96-scan-line mode, it line-doubles it to 192 scan lines of data) - Scans through sprite data that is *always* located at 0x1FFE0 in the video buffer and glyph data that is *always* located at 0x1F7E0 in the video buffer - If the sprite and glyph data tell it that sprite pixels are located at a particular location on the screen, it replaces that pixel data in its shadowed copy with zero (i.e. prevents overlaying anything there). How is this useful? It lets you tell the overlay video to NOT overlay anything where the Inty is displaying its sprites. In the sprite data, you can tell it the location and scaling of a sprite similarly to how you would tell the STIC, and the glyph data supplies the dot patterns. To go into more detail: Starting at 0x1FFE0, there are 8 four-byte records, one record for each sprite. Each record contains the following: - X position - Y position - glyph index - attributes The X and Y values contain the location of the sprite's upper-left pixel, plus an offset. Adding an offset lets my software support sprites that are partially displayed along the top or left edges. The glyph index is a number from 0-255 and the attributes byte has bit fields that supply visibility, scaling, etc. information. Their meanings correspond one-to-one with the bits that the STIC uses, though the bit positions are necessarily different. The glyph data at 0x1F7E0 is simply raw dot patterns for 256 glyphs. I use this many to support Inty's that have 256 GRAM cards. The idea is that you would shadow what you write to the Inty's GRAM here. Note that it does NOT support sprites that use GROM glyphs, though you can always use some of these 256 available glyphs to represent glyphs that the Inty has in its GROM. And finally, a test screenshot. This is excluding 8 sprites at maximum size with various flip settings. It's something of a stress test. If I tried this with a text mode it would require massive changes so I don't know if it's possible. It's also not lost on me that this functionality could pretty easily be extended to allow you to supply your own extra sprites, as long as it can all run in the allotted time. Edited January 3, 2022 by JohnPCAE Quote Link to comment Share on other sites More sharing options...
JohnPCAE Posted January 3, 2022 Author Share Posted January 3, 2022 *sigh* Text mode in general is proper hard. I've managed to implement sprite exclusion in 40-column text mode, but there are some caveats. If you don't use any 4-color characters, it can exclude up to 5 maximum-size sprites (double-width, height x 8, double-glyphs) if none of them are clipped along the left and right edges of the screen. Going above 5 causes the Pico to run out of time and you get screen corruption. It can, however, exclude more sprites if they're only quad height and if none of them are clipped along the left and right screen edges. 4-color characters take longer to convert to pixels, so the more of them you use the less time budget you have for compositing a shadowed screen and excluding sprites. Likewise, if a sprite is clipped along the left or right edges of the screen, the code can't optimize the sprite pixel loop and it takes longer to process. Basically, while you can do some sprite exclusion in text mode, there are limitations. If all of the sprites are small, there should be no problems excluding them all. It comes down to how many screen pixels have to be blanked out. The larger a sprite, the more pixels the code has to process. That's why the test above with all 8 sprites at maximum size was a stress test. Sprite exclusion in 80-column text mode is a total non-starter. It takes way too long to shadow the text as pixels. Quote Link to comment Share on other sites More sharing options...
JohnPCAE Posted January 5, 2022 Author Share Posted January 5, 2022 (edited) Hmm. For some reason I can't add to the thread from Firefox anymore. I had to switch to IE. In Firefox it immediately demands that I drag an attachment to the thread, but even if I do so it won't let me type in any text. Anyway, I've gotten really tired of inconsistent compliation results from gcc. Sometimes it gives me decent performance, and then I'll make a code change and a completely unrelated part of code will suddenly have performance issues. So I've started converting all of my output code to assembler. I'm getting much better at Arm Thumb assembly, as limited as it is. I've run into perhaps the weirdest thing I've ever seen while testing. I'm testing with a StarTech USB video capture device, and for some inexplicable reason it sometimes wants to interpret my overlaid video as grayscale. The video coming from the Inty will still be in color, but the overlaid video will be in black-and-white. Sometimes closing my video capture software and unplugging the USB device fixes it. Sometimes resetting the Inty does it as well, but resetting the Inty can also cause it to go from color to black-and-white. I've verified that it has nothing to do with my software as resetting the Inty doesn't reset the Pico. As long as the Inty has power, the software on the Pico will run uninterrupted. I do trigger an interrupt on the Pico if I detect an MSYNC pulse, but only to reset some internal state variables to a consistent state. It has no effect on how my test patterns are being output. I think what's happening is that the USB capture device is trying to be smart and make high-resolution text legible. I almost wonder if I need a tiny color CRT or something similarly dumb to test with. EDIT: Hah. I knew this would come in handy someday... Edited January 5, 2022 by JohnPCAE Quote Link to comment Share on other sites More sharing options...
JohnPCAE Posted January 7, 2022 Author Share Posted January 7, 2022 (edited) I have a question for some Inty gurus. I'm looking closely at the bus traffic to try to catch any glitches in my setup, and in the process of doing that I'm seeing something else that's strange. When the Inty starts up, something is accessing my code and (I think) writing to GRAM. Does the EXEC do some sort of GRAM initialization on startup? Also, is anyone else having problems posting from Firefox? The forums aren't letting me type in any text. I have to switch to IE to post. It only started happening within the past week or so. Edited January 7, 2022 by JohnPCAE Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted January 7, 2022 Share Posted January 7, 2022 40 minutes ago, JohnPCAE said: I have a question for some Inty gurus. I'm looking closely at the bus traffic to try to catch any glitches in my setup, and in the process of doing that I'm seeing something else that's strange. When the Inty starts up, something is accessing my code and (I think) writing to GRAM. Does the EXEC do some sort of GRAM initialization on startup? I believe the EXEC clears all RAM, including GRAM during it's initialization stage. -dZ. Quote Link to comment Share on other sites More sharing options...
+Lathe26 Posted January 8, 2022 Share Posted January 8, 2022 9 hours ago, JohnPCAE said: Also, is anyone else having problems posting from Firefox? The forums aren't letting me type in any text. I have to switch to IE to post. It only started happening within the past week or so. Regarding Firefox, I am posting this using Firefox on Windows 10. Quote Link to comment Share on other sites More sharing options...
JohnPCAE Posted January 8, 2022 Author Share Posted January 8, 2022 (edited) This is what I get when using Firefox on Windows 7. It doesn't give me any place to type text. This bug started happening somewhere between January 3 and January 5. Edited January 8, 2022 by JohnPCAE Quote Link to comment Share on other sites More sharing options...
mr_me Posted January 8, 2022 Share Posted January 8, 2022 50 minutes ago, JohnPCAE said: This is what I get when using Firefox on Windows 7. It doesn't give me any place to type text. This bug started happening somewhere between January 3 and January 5. Try disabling adblocker as a test. Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted January 8, 2022 Share Posted January 8, 2022 (edited) 1 hour ago, JohnPCAE said: This is what I get when using Firefox on Windows 7. It doesn't give me any place to type text. This bug started happening somewhere between January 3 and January 5. I get that with older versions of Firefox (the ones my ancient Mac could support). I think it's a JavaScript/Stylesheet compatibility issue. I switched to Firefox Legacy and Interweb (special builds of later Firefox code for older machines) and the problem is sorted. On an old 2009 Mac Pro running Mac OS X 10.5.8 (Mountain Lion), I use Interweb for AtariAge and it works a treat. dZ. Edited January 8, 2022 by DZ-Jay Quote Link to comment Share on other sites More sharing options...
JohnPCAE Posted January 8, 2022 Author Share Posted January 8, 2022 48 minutes ago, mr_me said: Try disabling adblocker as a test. Nope, that didn't help. I use uBlock Origin by the way. Quote Link to comment Share on other sites More sharing options...
JohnPCAE Posted January 8, 2022 Author Share Posted January 8, 2022 I also just tried restarting Firefox in troubleshooting mode, which turns off all themes and extensions. That didn't help either. Quote Link to comment Share on other sites More sharing options...
JohnPCAE Posted January 9, 2022 Author Share Posted January 9, 2022 (edited) I posted about the problem on the Firefox forums, and they pointed me to a solution. I had to go into my Firefox settings and clear the cache. All fixed now! In other news, I've been going on a major optimization spree in my Pico code, rewriting all kinds of stuff in assembly. It can now *barely* exclude a single sprite if every character on the screen is a four-color narrow-pixel character (meaning: characters that are 8 pixels across and each pixel is represented by 2 bits). Those are very CPU-intensive to composite into a separate 320x192x256 buffer and it's a real stress test. By contrast, if you're using only standard two-color characters, it can exclude four maximum-size sprites (double-width, quadruple height, two glyphs per sprite). And if you're using any of the bitmap graphics screen modes instead, it can exclude all eight Intellivision sprites at maximum size. To recap, sprite exclusion allows you to tell it to not render anything where an Intellivision sprite would be. It's an optional feature that you don't have to enable. When enabled, instead of directly displaying whatever is in your video buffer, it reserves a portion of it for a full 320x191x256 frame buffer and first renders to that. It then blanks out any pixels that an Intellivision sprite would occupy before displaying it on the screen. It reserves a portion of its video buffer where you would place sprite glyphs and tell it where the sprites are. The effect is that you could have the extra video appear *under* Intellivision sprites instead of mixed with them. Rendering character-mode screen modes is much more CPU intensive than pure graphics modes (which involves a simple block copy of memory), so there are restrictions on how many sprites you can exclude because of the time involved. You also cannot exclude any sprites if you're using 80-column mode, at least for now. I haven't attempted to try it and I doubt there's enough CPU horsepower available to pull it off (not to mention that I'm running hard into the RAM limit with all of the code that's already written). When using sprite exclusion with bitmap graphics modes, I should explain one more caveat. Intellivision sprites have a Y position resolution of 192 pixels, in other words they can be placed on any scan line. This means that whatever frame buffer my code uses when excluding sprites has to have 192 scan lines. So if you're using a "thick scanline" mode with 96 pixels, the code will always double it up to 191 scan lines when excluding sprites. This places limitations on which graphics modes allow sprite exclusion, since the total video memory is 128k bytes. Any graphics modes that need more than 128k for the normal and "shadowed" frame buffer cannot have sprite exclusion since there isn't enough room for a separate frame buffer. This applies to a handful of screen modes: 160x96x32bit 160x191x32bit 320x96x16bit 320x96x32bit 320x191x16bit 640x96x256 640x96x16bit 640x191x256 Edited January 9, 2022 by JohnPCAE Quote Link to comment Share on other sites More sharing options...
JohnPCAE Posted January 9, 2022 Author Share Posted January 9, 2022 (edited) Well, aside from testing the parallel port and any bugfixes, the software is basically complete. All of the existing screen modes are working and I'm right up at the RAM limit. I did learn something important last night: while the Pi Pico can run at up to 133MHz, it's default speed is only 125MHz. I set it for 133 and adjusted my bus timing code to match, so now it has a little extra speed margin. Tomorrow I should be receiving a dedicated RS-25 port testing breakout box so I can test the parallel port in earnest. This is the final list of available screen modes. Entries with an asterisk mean that sprite exclusion is unavailable due to insufficient RAM for the required shadow framebuffer. It's worth noting that you *can* do sprite exclusion for 320x191x256, the closest equivalent to VGA 320x200x256 mode. Since sprite exclusion reserves a large portion of the video buffer for a shadow framebuffer, it does restrict memory available for other things like RAM glyphs and emulation code. #define SCREEN_MODE_40_COLS 0 #define SCREEN_MODE_80_COLS 1 * #define SCREEN_MODE_160_96_2 2 #define SCREEN_MODE_160_96_4 3 #define SCREEN_MODE_160_96_16 4 #define SCREEN_MODE_160_96_256 5 #define SCREEN_MODE_160_96_TRUE16 6 #define SCREEN_MODE_160_96_TRUE32 7 * #define SCREEN_MODE_160_191_2 8 #define SCREEN_MODE_160_191_4 9 #define SCREEN_MODE_160_191_16 10 #define SCREEN_MODE_160_191_256 11 #define SCREEN_MODE_160_191_TRUE16 12 #define SCREEN_MODE_160_191_TRUE32 13 * #define SCREEN_MODE_320_96_2 14 #define SCREEN_MODE_320_96_4 15 #define SCREEN_MODE_320_96_16 16 #define SCREEN_MODE_320_96_256 17 #define SCREEN_MODE_320_96_TRUE16 18 * #define SCREEN_MODE_320_96_TRUE32 19 * #define SCREEN_MODE_320_191_2 20 #define SCREEN_MODE_320_191_4 21 #define SCREEN_MODE_320_191_16 22 #define SCREEN_MODE_320_191_256 23 #define SCREEN_MODE_320_191_TRUE16 24 * #define SCREEN_MODE_640_96_2 25 #define SCREEN_MODE_640_96_4 26 #define SCREEN_MODE_640_96_16 27 #define SCREEN_MODE_640_96_256 28 * #define SCREEN_MODE_640_96_TRUE16 29 * #define SCREEN_MODE_640_191_2 30 #define SCREEN_MODE_640_191_4 31 #define SCREEN_MODE_640_191_16 32 #define SCREEN_MODE_640_191_256 33 * Edited January 9, 2022 by JohnPCAE Quote Link to comment Share on other sites More sharing options...
JohnPCAE Posted January 9, 2022 Author Share Posted January 9, 2022 (edited) On 12/31/2021 at 12:38 AM, Lathe26 said: You should coordinate your instructions with Joe Zbiciak since the LTO has its own set of extended opcodes. I'm going through the Locutus documentation. The issue I see is that I have more opcodes than will fit into his reserved opcode areas. He blocks out 000001xxxxxxxxxx and 010000xxxxxxxxxx as reserved areas, but my opcodes won't fit in to just those areas. I would need a little more opcode space to fit them all. Also, the paradigm is completely different: the Locutus opcodes are designed to coexist with an existing CP-1600, whereas mine assume a CPU replacement that is backward compatible. It looks like all of the Locutus opcodes work around the 1001111xxx MVOI opcode. I might be able to move mine a little so that they don't use those bits. I'll see what I can do. EDIT: Okay. I've moved my instructions so that none of them occupy where MVOI/Locutus/CP-1600X would be. PV_DISPATCH dispatch[] = { DO_HLT, DO_SDBD, DO_EIS, DO_DIS, DO_J, DO_TCI, DO_CLRC, DO_SETC, DO_INCR, DO_INCR, DO_INCR, DO_INCR, DO_INCR, DO_INCR, DO_INCR, DO_INCR, DO_DECR, DO_DECR, DO_DECR, DO_DECR, DO_DECR, DO_DECR, DO_DECR, DO_DECR, DO_COMR, DO_COMR, DO_COMR, DO_COMR, DO_COMR, DO_COMR, DO_COMR, DO_COMR, DO_NEGR, DO_NEGR, DO_NEGR, DO_NEGR, DO_NEGR, DO_NEGR, DO_NEGR, DO_NEGR, DO_ADCR, DO_ADCR, DO_ADCR, DO_ADCR, DO_ADCR, DO_ADCR, DO_ADCR, DO_ADCR, DO_GSWD, DO_GSWD, DO_GSWD, DO_GSWD, DO_NOP, DO_NOP, DO_SIN, DO_SIN, DO_RSWD, DO_RSWD, DO_RSWD, DO_RSWD, DO_RSWD, DO_RSWD, DO_RSWD, DO_RSWD, DO_SWAP, DO_SWAP, DO_SWAP, DO_SWAP, DO_SWAP2, DO_SWAP2, DO_SWAP2, DO_SWAP2, DO_SLL, DO_SLL, DO_SLL, DO_SLL, DO_SLL2, DO_SLL2, DO_SLL2, DO_SLL2, DO_RLC, DO_RLC, DO_RLC, DO_RLC, DO_RLC2, DO_RLC2, DO_RLC2, DO_RLC2, DO_SLLC, DO_SLLC, DO_SLLC, DO_SLLC, DO_SLLC2, DO_SLLC2, DO_SLLC2, DO_SLLC2, DO_SLR, DO_SLR, DO_SLR, DO_SLR, DO_SLR2, DO_SLR2, DO_SLR2, DO_SLR2, DO_SAR, DO_SAR, DO_SAR, DO_SAR, DO_SAR2, DO_SAR2, DO_SAR2, DO_SAR2, DO_RRC, DO_RRC, DO_RRC, DO_RRC, DO_RRC2, DO_RRC2, DO_RRC2, DO_RRC2, DO_SARC, DO_SARC, DO_SARC, DO_SARC, DO_SARC2, DO_SARC2, DO_SARC2, DO_SARC2, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_MOVR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_ADDR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_SUBR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_CMPR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_ANDR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_XORR, DO_BADD, DO_BADDC, DO_BADDO, DO_BADDNS, DO_BADDZ, DO_BADDLT, DO_BADDLE, DO_BADDUSC, DO_BSKIP, DO_BADDNC, DO_BADDNO, DO_BADDS, DO_BADDNZ, DO_BADDGE, DO_BADDGT, DO_BADDESC, DO_BADDEXT, DO_BADDEXT, DO_BADDEXT, DO_BADDEXT, DO_BADDEXT, DO_BADDEXT, DO_BADDEXT, DO_BADDEXT, DO_BADDEXT, DO_BADDEXT, DO_BADDEXT, DO_BADDEXT, DO_BADDEXT, DO_BADDEXT, DO_BADDEXT, DO_BADDEXT, DO_BSUB, DO_BSUBC, DO_BSUBO, DO_BSUBNS, DO_BSUBZ, DO_BSUBLT, DO_BSUBLE, DO_BSUBUSC, DO_BSKIP, DO_BSUBNC, DO_BSUBNO, DO_BSUBS, DO_BSUBNZ, DO_BSUBGE, DO_BSUBGT, DO_BSUBESC, DO_BSUBEXT, DO_BSUBEXT, DO_BSUBEXT, DO_BSUBEXT, DO_BSUBEXT, DO_BSUBEXT, DO_BSUBEXT, DO_BSUBEXT, DO_BSUBEXT, DO_BSUBEXT, DO_BSUBEXT, DO_BSUBEXT, DO_BSUBEXT, DO_BSUBEXT, DO_BSUBEXT, DO_BSUBEXT, DO_MVO, DO_MVO, DO_MVO, DO_MVO, DO_MVO, DO_MVO, DO_MVO, DO_MVO, DO_MVOA123, DO_MVOA123, DO_MVOA123, DO_MVOA123, DO_MVOA123, DO_MVOA123, DO_MVOA123, DO_MVOA123, DO_MVOA123, DO_MVOA123, DO_MVOA123, DO_MVOA123, DO_MVOA123, DO_MVOA123, DO_MVOA123, DO_MVOA123, DO_MVOA123, DO_MVOA123, DO_MVOA123, DO_MVOA123, DO_MVOA123, DO_MVOA123, DO_MVOA123, DO_MVOA123, DO_MVOA4567, DO_MVOA4567, DO_MVOA4567, DO_MVOA4567, DO_MVOA4567, DO_MVOA4567, DO_MVOA4567, DO_MVOA4567, DO_MVOA4567, DO_MVOA4567, DO_MVOA4567, DO_MVOA4567, DO_MVOA4567, DO_MVOA4567, DO_MVOA4567, DO_MVOA4567, DO_MVOA4567, DO_MVOA4567, DO_MVOA4567, DO_MVOA4567, DO_MVOA4567, DO_MVOA4567, DO_MVOA4567, DO_MVOA4567, DO_MVOA4567, DO_MVOA4567, DO_MVOA4567, DO_MVOA4567, DO_MVOA4567, DO_MVOA4567, DO_MVOA4567, DO_MVOA4567, DO_MVI, DO_MVI, DO_MVI, DO_MVI, DO_MVI, DO_MVI, DO_MVI, DO_MVI7, DO_MVIA123, DO_MVIA123, DO_MVIA123, DO_MVIA123, DO_MVIA123, DO_MVIA123, DO_MVIA123, DO_MVIA123, DO_MVIA123, DO_MVIA123, DO_MVIA123, DO_MVIA123, DO_MVIA123, DO_MVIA123, DO_MVIA123, DO_MVIA123, DO_MVIA123, DO_MVIA123, DO_MVIA123, DO_MVIA123, DO_MVIA123, DO_MVIA123, DO_MVIA123, DO_MVIA123, DO_MVIA457, DO_MVIA457, DO_MVIA457, DO_MVIA457, DO_MVIA457, DO_MVIA457, DO_MVIA457, DO_MVIA457, DO_MVIA457, DO_MVIA457, DO_MVIA457, DO_MVIA457, DO_MVIA457, DO_MVIA457, DO_MVIA457, DO_MVIA457, DO_MVIA6, DO_MVIA6, DO_MVIA6, DO_MVIA6, DO_MVIA6, DO_MVIA6, DO_MVIA6, DO_MVIA6, DO_MVIA457, DO_MVIA457, DO_MVIA457, DO_MVIA457, DO_MVIA457, DO_MVIA457, DO_MVIA457, DO_MVIA457, DO_ADD, DO_ADD, DO_ADD, DO_ADD, DO_ADD, DO_ADD, DO_ADD, DO_ADD, DO_ADDA123, DO_ADDA123, DO_ADDA123, DO_ADDA123, DO_ADDA123, DO_ADDA123, DO_ADDA123, DO_ADDA123, DO_ADDA123, DO_ADDA123, DO_ADDA123, DO_ADDA123, DO_ADDA123, DO_ADDA123, DO_ADDA123, DO_ADDA123, DO_ADDA123, DO_ADDA123, DO_ADDA123, DO_ADDA123, DO_ADDA123, DO_ADDA123, DO_ADDA123, DO_ADDA123, DO_ADDA457, DO_ADDA457, DO_ADDA457, DO_ADDA457, DO_ADDA457, DO_ADDA457, DO_ADDA457, DO_ADDA457, DO_ADDA457, DO_ADDA457, DO_ADDA457, DO_ADDA457, DO_ADDA457, DO_ADDA457, DO_ADDA457, DO_ADDA457, DO_ADDA6, DO_ADDA6, DO_ADDA6, DO_ADDA6, DO_ADDA6, DO_ADDA6, DO_ADDA6, DO_ADDA6, DO_ADDA457, DO_ADDA457, DO_ADDA457, DO_ADDA457, DO_ADDA457, DO_ADDA457, DO_ADDA457, DO_ADDA457, DO_SUB, DO_SUB, DO_SUB, DO_SUB, DO_SUB, DO_SUB, DO_SUB, DO_SUB, DO_SUBA123, DO_SUBA123, DO_SUBA123, DO_SUBA123, DO_SUBA123, DO_SUBA123, DO_SUBA123, DO_SUBA123, DO_SUBA123, DO_SUBA123, DO_SUBA123, DO_SUBA123, DO_SUBA123, DO_SUBA123, DO_SUBA123, DO_SUBA123, DO_SUBA123, DO_SUBA123, DO_SUBA123, DO_SUBA123, DO_SUBA123, DO_SUBA123, DO_SUBA123, DO_SUBA123, DO_SUBA457, DO_SUBA457, DO_SUBA457, DO_SUBA457, DO_SUBA457, DO_SUBA457, DO_SUBA457, DO_SUBA457, DO_SUBA457, DO_SUBA457, DO_SUBA457, DO_SUBA457, DO_SUBA457, DO_SUBA457, DO_SUBA457, DO_SUBA457, DO_SUBA6, DO_SUBA6, DO_SUBA6, DO_SUBA6, DO_SUBA6, DO_SUBA6, DO_SUBA6, DO_SUBA6, DO_SUBA457, DO_SUBA457, DO_SUBA457, DO_SUBA457, DO_SUBA457, DO_SUBA457, DO_SUBA457, DO_SUBA457, DO_CMP, DO_CMP, DO_CMP, DO_CMP, DO_CMP, DO_CMP, DO_CMP, DO_CMP, DO_CMPA123, DO_CMPA123, DO_CMPA123, DO_CMPA123, DO_CMPA123, DO_CMPA123, DO_CMPA123, DO_CMPA123, DO_CMPA123, DO_CMPA123, DO_CMPA123, DO_CMPA123, DO_CMPA123, DO_CMPA123, DO_CMPA123, DO_CMPA123, DO_CMPA123, DO_CMPA123, DO_CMPA123, DO_CMPA123, DO_CMPA123, DO_CMPA123, DO_CMPA123, DO_CMPA123, DO_CMPA457, DO_CMPA457, DO_CMPA457, DO_CMPA457, DO_CMPA457, DO_CMPA457, DO_CMPA457, DO_CMPA457, DO_CMPA457, DO_CMPA457, DO_CMPA457, DO_CMPA457, DO_CMPA457, DO_CMPA457, DO_CMPA457, DO_CMPA457, DO_CMPA6, DO_CMPA6, DO_CMPA6, DO_CMPA6, DO_CMPA6, DO_CMPA6, DO_CMPA6, DO_CMPA6, DO_CMPA457, DO_CMPA457, DO_CMPA457, DO_CMPA457, DO_CMPA457, DO_CMPA457, DO_CMPA457, DO_CMPA457, DO_AND, DO_AND, DO_AND, DO_AND, DO_AND, DO_AND, DO_AND, DO_AND, DO_ANDA123, DO_ANDA123, DO_ANDA123, DO_ANDA123, DO_ANDA123, DO_ANDA123, DO_ANDA123, DO_ANDA123, DO_ANDA123, DO_ANDA123, DO_ANDA123, DO_ANDA123, DO_ANDA123, DO_ANDA123, DO_ANDA123, DO_ANDA123, DO_ANDA123, DO_ANDA123, DO_ANDA123, DO_ANDA123, DO_ANDA123, DO_ANDA123, DO_ANDA123, DO_ANDA123, DO_ANDA457, DO_ANDA457, DO_ANDA457, DO_ANDA457, DO_ANDA457, DO_ANDA457, DO_ANDA457, DO_ANDA457, DO_ANDA457, DO_ANDA457, DO_ANDA457, DO_ANDA457, DO_ANDA457, DO_ANDA457, DO_ANDA457, DO_ANDA457, DO_ANDA6, DO_ANDA6, DO_ANDA6, DO_ANDA6, DO_ANDA6, DO_ANDA6, DO_ANDA6, DO_ANDA6, DO_ANDA457, DO_ANDA457, DO_ANDA457, DO_ANDA457, DO_ANDA457, DO_ANDA457, DO_ANDA457, DO_ANDA457, DO_XOR, DO_XOR, DO_XOR, DO_XOR, DO_XOR, DO_XOR, DO_XOR, DO_XOR, DO_XORA123, DO_XORA123, DO_XORA123, DO_XORA123, DO_XORA123, DO_XORA123, DO_XORA123, DO_XORA123, DO_XORA123, DO_XORA123, DO_XORA123, DO_XORA123, DO_XORA123, DO_XORA123, DO_XORA123, DO_XORA123, DO_XORA123, DO_XORA123, DO_XORA123, DO_XORA123, DO_XORA123, DO_XORA123, DO_XORA123, DO_XORA123, DO_XORA457, DO_XORA457, DO_XORA457, DO_XORA457, DO_XORA457, DO_XORA457, DO_XORA457, DO_XORA457, DO_XORA457, DO_XORA457, DO_XORA457, DO_XORA457, DO_XORA457, DO_XORA457, DO_XORA457, DO_XORA457, DO_XORA6, DO_XORA6, DO_XORA6, DO_XORA6, DO_XORA6, DO_XORA6, DO_XORA6, DO_XORA6, DO_XORA457, DO_XORA457, DO_XORA457, DO_XORA457, DO_XORA457, DO_XORA457, DO_XORA457, DO_XORA457, // Extended opcodes start here // ORx ; RD |= Src // 000001 0000 sss ddd DO_ORA123, DO_ORA123, DO_ORA123, DO_ORA123, DO_ORA123, DO_ORA123, DO_ORA123, DO_ORA123, // OR@ R0, RD DO_ORA123, DO_ORA123, DO_ORA123, DO_ORA123, DO_ORA123, DO_ORA123, DO_ORA123, DO_ORA123, // OR@ R1, RD DO_ORA123, DO_ORA123, DO_ORA123, DO_ORA123, DO_ORA123, DO_ORA123, DO_ORA123, DO_ORA123, // OR@ R2, RD DO_ORA123, DO_ORA123, DO_ORA123, DO_ORA123, DO_ORA123, DO_ORA123, DO_ORA123, DO_ORA123, // OR@ R3, RD DO_ORA457, DO_ORA457, DO_ORA457, DO_ORA457, DO_ORA457, DO_ORA457, DO_ORA457, DO_ORA457, // OR@ R4, RD DO_ORA457, DO_ORA457, DO_ORA457, DO_ORA457, DO_ORA457, DO_ORA457, DO_ORA457, DO_ORA457, // OR@ R5, RD DO_ORA6, DO_ORA6, DO_ORA6, DO_ORA6, DO_ORA6, DO_ORA6, DO_ORA6, DO_ORA6, // OR@ R6, RD DO_ORA457, DO_ORA457, DO_ORA457, DO_ORA457, DO_ORA457, DO_ORA457, DO_ORA457, DO_ORA457, // ORI DATA, RD // ADCx ; RD += Src + C // 000001 0001 sss ddd DO_ADCA123, DO_ADCA123, DO_ADCA123, DO_ADCA123, DO_ADCA123, DO_ADCA123, DO_ADCA123, DO_ADCA123, // ADC@ R0, RD DO_ADCA123, DO_ADCA123, DO_ADCA123, DO_ADCA123, DO_ADCA123, DO_ADCA123, DO_ADCA123, DO_ADCA123, // ADC@ R1, RD DO_ADCA123, DO_ADCA123, DO_ADCA123, DO_ADCA123, DO_ADCA123, DO_ADCA123, DO_ADCA123, DO_ADCA123, // ADC@ R2, RD DO_ADCA123, DO_ADCA123, DO_ADCA123, DO_ADCA123, DO_ADCA123, DO_ADCA123, DO_ADCA123, DO_ADCA123, // ADC@ R3, RD DO_ADCA457, DO_ADCA457, DO_ADCA457, DO_ADCA457, DO_ADCA457, DO_ADCA457, DO_ADCA457, DO_ADCA457, // ADC@ R4, RD DO_ADCA457, DO_ADCA457, DO_ADCA457, DO_ADCA457, DO_ADCA457, DO_ADCA457, DO_ADCA457, DO_ADCA457, // ADC@ R5, RD DO_ADCA6, DO_ADCA6, DO_ADCA6, DO_ADCA6, DO_ADCA6, DO_ADCA6, DO_ADCA6, DO_ADCA6, // ADC@ R6, RD DO_ADCA457, DO_ADCA457, DO_ADCA457, DO_ADCA457, DO_ADCA457, DO_ADCA457, DO_ADCA457, DO_ADCA457, // ADCI DATA, RD // SBBx ; RD -= (Src + C) // 000001 0010 sss ddd DO_SBBA123, DO_SBBA123, DO_SBBA123, DO_SBBA123, DO_SBBA123, DO_SBBA123, DO_SBBA123, DO_SBBA123, // SBB@ R0, RD DO_SBBA123, DO_SBBA123, DO_SBBA123, DO_SBBA123, DO_SBBA123, DO_SBBA123, DO_SBBA123, DO_SBBA123, // SBB@ R1, RD DO_SBBA123, DO_SBBA123, DO_SBBA123, DO_SBBA123, DO_SBBA123, DO_SBBA123, DO_SBBA123, DO_SBBA123, // SBB@ R2, RD DO_SBBA123, DO_SBBA123, DO_SBBA123, DO_SBBA123, DO_SBBA123, DO_SBBA123, DO_SBBA123, DO_SBBA123, // SBB@ R3, RD DO_SBBA457, DO_SBBA457, DO_SBBA457, DO_SBBA457, DO_SBBA457, DO_SBBA457, DO_SBBA457, DO_SBBA457, // SBB@ R4, RD DO_SBBA457, DO_SBBA457, DO_SBBA457, DO_SBBA457, DO_SBBA457, DO_SBBA457, DO_SBBA457, DO_SBBA457, // SBB@ R5, RD DO_SBBA6, DO_SBBA6, DO_SBBA6, DO_SBBA6, DO_SBBA6, DO_SBBA6, DO_SBBA6, DO_SBBA6, // SBB@ R6, RD DO_SBBA457, DO_SBBA457, DO_SBBA457, DO_SBBA457, DO_SBBA457, DO_SBBA457, DO_SBBA457, DO_SBBA457, // SBBI DATA, RD // TSTx ; Sets the S and Z flags based on RS & Src // 000001 0011 sss ddd DO_TSTA123, DO_TSTA123, DO_TSTA123, DO_TSTA123, DO_TSTA123, DO_TSTA123, DO_TSTA123, DO_TSTA123, // TST@ R0, RS DO_TSTA123, DO_TSTA123, DO_TSTA123, DO_TSTA123, DO_TSTA123, DO_TSTA123, DO_TSTA123, DO_TSTA123, // TST@ R1, RS DO_TSTA123, DO_TSTA123, DO_TSTA123, DO_TSTA123, DO_TSTA123, DO_TSTA123, DO_TSTA123, DO_TSTA123, // TST@ R2, RS DO_TSTA123, DO_TSTA123, DO_TSTA123, DO_TSTA123, DO_TSTA123, DO_TSTA123, DO_TSTA123, DO_TSTA123, // TST@ R3, RS DO_TSTA457, DO_TSTA457, DO_TSTA457, DO_TSTA457, DO_TSTA457, DO_TSTA457, DO_TSTA457, DO_TSTA457, // TST@ R4, RS DO_TSTA457, DO_TSTA457, DO_TSTA457, DO_TSTA457, DO_TSTA457, DO_TSTA457, DO_TSTA457, DO_TSTA457, // TST@ R5, RS DO_TSTA6, DO_TSTA6, DO_TSTA6, DO_TSTA6, DO_TSTA6, DO_TSTA6, DO_TSTA6, DO_TSTA6, // TST@ R6, RS DO_TSTA457, DO_TSTA457, DO_TSTA457, DO_TSTA457, DO_TSTA457, DO_TSTA457, DO_TSTA457, DO_TSTA457, // TSTI DATA, RS // SLLx ; RD <<= Src // 000001 0100 sss ddd DO_SLLA123, DO_SLLA123, DO_SLLA123, DO_SLLA123, DO_SLLA123, DO_SLLA123, DO_SLLA123, DO_SLLA123, // SLL@ R0, RD DO_SLLA123, DO_SLLA123, DO_SLLA123, DO_SLLA123, DO_SLLA123, DO_SLLA123, DO_SLLA123, DO_SLLA123, // SLL@ R1, RD DO_SLLA123, DO_SLLA123, DO_SLLA123, DO_SLLA123, DO_SLLA123, DO_SLLA123, DO_SLLA123, DO_SLLA123, // SLL@ R2, RD DO_SLLA123, DO_SLLA123, DO_SLLA123, DO_SLLA123, DO_SLLA123, DO_SLLA123, DO_SLLA123, DO_SLLA123, // SLL@ R3, RD DO_SLLA457, DO_SLLA457, DO_SLLA457, DO_SLLA457, DO_SLLA457, DO_SLLA457, DO_SLLA457, DO_SLLA457, // SLL@ R4, RD DO_SLLA457, DO_SLLA457, DO_SLLA457, DO_SLLA457, DO_SLLA457, DO_SLLA457, DO_SLLA457, DO_SLLA457, // SLL@ R5, RD DO_SLLA6, DO_SLLA6, DO_SLLA6, DO_SLLA6, DO_SLLA6, DO_SLLA6, DO_SLLA6, DO_SLLA6, // SLL@ R6, RD DO_SLLA457, DO_SLLA457, DO_SLLA457, DO_SLLA457, DO_SLLA457, DO_SLLA457, DO_SLLA457, DO_SLLA457, // SLL RD, DATA // SLRx ; RD >>= Src // 000001 0101 sss ddd DO_SLRA123, DO_SLRA123, DO_SLRA123, DO_SLRA123, DO_SLRA123, DO_SLRA123, DO_SLRA123, DO_SLRA123, // SLR@ R0, RD DO_SLRA123, DO_SLRA123, DO_SLRA123, DO_SLRA123, DO_SLRA123, DO_SLRA123, DO_SLRA123, DO_SLRA123, // SLR@ R1, RD DO_SLRA123, DO_SLRA123, DO_SLRA123, DO_SLRA123, DO_SLRA123, DO_SLRA123, DO_SLRA123, DO_SLRA123, // SLR@ R2, RD DO_SLRA123, DO_SLRA123, DO_SLRA123, DO_SLRA123, DO_SLRA123, DO_SLRA123, DO_SLRA123, DO_SLRA123, // SLR@ R3, RD DO_SLRA457, DO_SLRA457, DO_SLRA457, DO_SLRA457, DO_SLRA457, DO_SLRA457, DO_SLRA457, DO_SLRA457, // SLR@ R4, RD DO_SLRA457, DO_SLRA457, DO_SLRA457, DO_SLRA457, DO_SLRA457, DO_SLRA457, DO_SLRA457, DO_SLRA457, // SLR@ R5, RD DO_SLRA6, DO_SLRA6, DO_SLRA6, DO_SLRA6, DO_SLRA6, DO_SLRA6, DO_SLRA6, DO_SLRA6, // SLR@ R6, RD DO_SLRA457, DO_SLRA457, DO_SLRA457, DO_SLRA457, DO_SLRA457, DO_SLRA457, DO_SLRA457, DO_SLRA457, // SLR RD, DATA // SARx ; RD = RD sar Src (arithmetic shift right) // 000001 0110 sss ddd DO_SARA123, DO_SARA123, DO_SARA123, DO_SARA123, DO_SARA123, DO_SARA123, DO_SARA123, DO_SARA123, // SAR@ R0, RD DO_SARA123, DO_SARA123, DO_SARA123, DO_SARA123, DO_SARA123, DO_SARA123, DO_SARA123, DO_SARA123, // SAR@ R1, RD DO_SARA123, DO_SARA123, DO_SARA123, DO_SARA123, DO_SARA123, DO_SARA123, DO_SARA123, DO_SARA123, // SAR@ R2, RD DO_SARA123, DO_SARA123, DO_SARA123, DO_SARA123, DO_SARA123, DO_SARA123, DO_SARA123, DO_SARA123, // SAR@ R3, RD DO_SARA457, DO_SARA457, DO_SARA457, DO_SARA457, DO_SARA457, DO_SARA457, DO_SARA457, DO_SARA457, // SAR@ R4, RD DO_SARA457, DO_SARA457, DO_SARA457, DO_SARA457, DO_SARA457, DO_SARA457, DO_SARA457, DO_SARA457, // SAR@ R5, RD DO_SARA6, DO_SARA6, DO_SARA6, DO_SARA6, DO_SARA6, DO_SARA6, DO_SARA6, DO_SARA6, // SAR@ R6, RD DO_SARA457, DO_SARA457, DO_SARA457, DO_SARA457, DO_SARA457, DO_SARA457, DO_SARA457, DO_SARA457, // SAR RD, DATA // ROLx ; RD = RD rol Src // 000001 0111 sss ddd DO_ROLA123, DO_ROLA123, DO_ROLA123, DO_ROLA123, DO_ROLA123, DO_ROLA123, DO_ROLA123, DO_ROLA123, // ROL@ R0, RD DO_ROLA123, DO_ROLA123, DO_ROLA123, DO_ROLA123, DO_ROLA123, DO_ROLA123, DO_ROLA123, DO_ROLA123, // ROL@ R1, RD DO_ROLA123, DO_ROLA123, DO_ROLA123, DO_ROLA123, DO_ROLA123, DO_ROLA123, DO_ROLA123, DO_ROLA123, // ROL@ R2, RD DO_ROLA123, DO_ROLA123, DO_ROLA123, DO_ROLA123, DO_ROLA123, DO_ROLA123, DO_ROLA123, DO_ROLA123, // ROL@ R3, RD DO_ROLA457, DO_ROLA457, DO_ROLA457, DO_ROLA457, DO_ROLA457, DO_ROLA457, DO_ROLA457, DO_ROLA457, // ROL@ R4, RD DO_ROLA457, DO_ROLA457, DO_ROLA457, DO_ROLA457, DO_ROLA457, DO_ROLA457, DO_ROLA457, DO_ROLA457, // ROL@ R5, RD DO_ROLA6, DO_ROLA6, DO_ROLA6, DO_ROLA6, DO_ROLA6, DO_ROLA6, DO_ROLA6, DO_ROLA6, // ROL@ R6, RD DO_ROLA457, DO_ROLA457, DO_ROLA457, DO_ROLA457, DO_ROLA457, DO_ROLA457, DO_ROLA457, DO_ROLA457, // ROL RD, DATA // RORx ; RD = RD ror Src // 000001 1000 sss ddd DO_RORA123, DO_RORA123, DO_RORA123, DO_RORA123, DO_RORA123, DO_RORA123, DO_RORA123, DO_RORA123, // ROR@ R0, RD DO_RORA123, DO_RORA123, DO_RORA123, DO_RORA123, DO_RORA123, DO_RORA123, DO_RORA123, DO_RORA123, // ROR@ R1, RD DO_RORA123, DO_RORA123, DO_RORA123, DO_RORA123, DO_RORA123, DO_RORA123, DO_RORA123, DO_RORA123, // ROR@ R2, RD DO_RORA123, DO_RORA123, DO_RORA123, DO_RORA123, DO_RORA123, DO_RORA123, DO_RORA123, DO_RORA123, // ROR@ R3, RD DO_RORA457, DO_RORA457, DO_RORA457, DO_RORA457, DO_RORA457, DO_RORA457, DO_RORA457, DO_RORA457, // ROR@ R4, RD DO_RORA457, DO_RORA457, DO_RORA457, DO_RORA457, DO_RORA457, DO_RORA457, DO_RORA457, DO_RORA457, // ROR@ R5, RD DO_RORA6, DO_RORA6, DO_RORA6, DO_RORA6, DO_RORA6, DO_RORA6, DO_RORA6, DO_RORA6, // ROR@ R6, RD DO_RORA457, DO_RORA457, DO_RORA457, DO_RORA457, DO_RORA457, DO_RORA457, DO_RORA457, DO_RORA457, // ROR RD, DATA // Reserved for Locutus // 000001 1001 ... ... DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, // MULx ; RD *= Src (unsigned multiply) // 000001 1010 sss ddd DO_MULA123, DO_MULA123, DO_MULA123, DO_MULA123, DO_MULA123, DO_MULA123, DO_MULA123, DO_MULA123, // MUL@ R0, RD DO_MULA123, DO_MULA123, DO_MULA123, DO_MULA123, DO_MULA123, DO_MULA123, DO_MULA123, DO_MULA123, // MUL@ R1, RD DO_MULA123, DO_MULA123, DO_MULA123, DO_MULA123, DO_MULA123, DO_MULA123, DO_MULA123, DO_MULA123, // MUL@ R2, RD DO_MULA123, DO_MULA123, DO_MULA123, DO_MULA123, DO_MULA123, DO_MULA123, DO_MULA123, DO_MULA123, // MUL@ R3, RD DO_MULA457, DO_MULA457, DO_MULA457, DO_MULA457, DO_MULA457, DO_MULA457, DO_MULA457, DO_MULA457, // MUL@ R4, RD DO_MULA457, DO_MULA457, DO_MULA457, DO_MULA457, DO_MULA457, DO_MULA457, DO_MULA457, DO_MULA457, // MUL@ R5, RD DO_MULA6, DO_MULA6, DO_MULA6, DO_MULA6, DO_MULA6, DO_MULA6, DO_MULA6, DO_MULA6, // MUL@ R6, RD DO_MULA457, DO_MULA457, DO_MULA457, DO_MULA457, DO_MULA457, DO_MULA457, DO_MULA457, DO_MULA457, // MULI DATA, RD // IMULx ; RD *= Src (signed multiply) // 000001 1011 sss ddd DO_IMULA123, DO_IMULA123, DO_IMULA123, DO_IMULA123, DO_IMULA123, DO_IMULA123, DO_IMULA123, DO_IMULA123, // IMUL@ R0, RD DO_IMULA123, DO_IMULA123, DO_IMULA123, DO_IMULA123, DO_IMULA123, DO_IMULA123, DO_IMULA123, DO_IMULA123, // IMUL@ R1, RD DO_IMULA123, DO_IMULA123, DO_IMULA123, DO_IMULA123, DO_IMULA123, DO_IMULA123, DO_IMULA123, DO_IMULA123, // IMUL@ R2, RD DO_IMULA123, DO_IMULA123, DO_IMULA123, DO_IMULA123, DO_IMULA123, DO_IMULA123, DO_IMULA123, DO_IMULA123, // IMUL@ R3, RD DO_IMULA457, DO_IMULA457, DO_IMULA457, DO_IMULA457, DO_IMULA457, DO_IMULA457, DO_IMULA457, DO_IMULA457, // IMUL@ R4, RD DO_IMULA457, DO_IMULA457, DO_IMULA457, DO_IMULA457, DO_IMULA457, DO_IMULA457, DO_IMULA457, DO_IMULA457, // IMUL@ R5, RD DO_IMULA6, DO_IMULA6, DO_IMULA6, DO_IMULA6, DO_IMULA6, DO_IMULA6, DO_IMULA6, DO_IMULA6, // IMUL@ R6, RD DO_IMULA457, DO_IMULA457, DO_IMULA457, DO_IMULA457, DO_IMULA457, DO_IMULA457, DO_IMULA457, DO_IMULA457, // IMULI DATA, RD // ORR RS, RD ; RD |= RS // 000001 1100 sss ddd DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, DO_ORR, // ADCR RS, RD ; RD += RS + C // 000001 1101 sss ddd DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, DO_ADCR2, // SBBR RS, RD ; RD -= (RS + C) // 000001 1110 sss ddd DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, DO_SBBR2, // INCLR RD ; Increments only the low byte of RD. If RD was 255, it rolls over to 0 without affecting the high byte but sets the carry flag. // TSTR RA, RB ; RA <> RB. Sets the S and Z flags based on RA & RB // 000001 1111 ddd ddd INCLR // 000001 1111 aaa bbb TSTR DO_INCLR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_INCLR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_INCLR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_INCLR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_INCLR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_INCLR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_INCLR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_TSTR, DO_INCLR, // SLLR RD, RA ; RD <<= RA // 000010 0000 ddd aaa DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, DO_SLLR, // SLRR RD, RA ; RD >>= RA // 000010 0001 ddd aaa DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, DO_SLRR, // SARR RD, RA ; RD = RD sar RA // 000010 0010 ddd aaa DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, DO_SARR, // ROLR RD, RA ; RD = RD rol RA // 000010 0011 ddd aaa DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, DO_ROLR, // RORR RD, RA ; RD = RD ror RA // 000010 0100 ddd aaa DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, DO_RORR, // MULR RS, RD ; RD *= RS (RD gets only the low word of the result) // 000010 0101 sss ddd DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, DO_MULR, // MULRW RA, RB ; R0:R1 = RA * RB (R0 = low word, R1 = high word) // 000010 0110 aaa bbb DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, DO_MULRW, // IMULR RS, RD ; RD *= RS (RD gets only the low word of the result) // 000010 0111 sss ddd DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, DO_IMULR, // IMULRW RA, RB ; R0:R1 = RA * RB (R0 = low word, R1 = high word) // 000010 1000 aaa bbb DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, DO_IMULRW, // Reserved for Locutus // 000010 1001 ... ... DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, // VMOVx Src, RD ; v3d[RD] = v3d[Src] Copies a 3-vector from [Src] to [RMD]. Each vector component is 32 bits. // LOOP RD ; RD--, if RD is nonzero afterwards, R7 += disp // BA disp ; Branch if above (unsigned compare) alternate: BNBE (branch if not below or equal) // BNA disp ; Branch if not above (unsigned compare) alternate: BBE (branch if below or equal) // 000010 1010 sss ddd VMOVx sss <> ddd // 000010 1010 ddd ddd LOOP ddd < 6 // 000010 1010 110 110 PPPP BA disp ((C or Z) = 0) // 000010 1010 111 111 PPPP BNA disp ((C or Z) = 1) DO_LOOP, DO_VMOVNN, DO_VMOVNN, DO_VMOVNN, DO_VMOVNI, DO_VMOVNI, DO_VMOVNI, DO_VMOVNI, // VMOV@@ R0, RD (RD <> R0, if RD = R6, VPSH@ R0) if RD = R0, LOOP R0 instead DO_VMOVNN, DO_LOOP, DO_VMOVNN, DO_VMOVNN, DO_VMOVNI, DO_VMOVNI, DO_VMOVNI, DO_VMOVNI, // VMOV@@ R1, RD (RD <> R1, if RD = R6, VPSH@ R1) if RD = R1, LOOP R1 instead DO_VMOVNN, DO_VMOVNN, DO_LOOP, DO_VMOVNN, DO_VMOVNI, DO_VMOVNI, DO_VMOVNI, DO_VMOVNI, // VMOV@@ R2, RD (RD <> R2, if RD = R6, VPSH@ R2) if RD = R2, LOOP R2 instead DO_VMOVNN, DO_VMOVNN, DO_VMOVNN, DO_LOOP, DO_VMOVNI, DO_VMOVNI, DO_VMOVNI, DO_VMOVNI, // VMOV@@ R3, RD (RD <> R3, if RD = R6, VPSH@ R3) if RD = R3, LOOP R3 instead DO_VMOVIN, DO_VMOVIN, DO_VMOVIN, DO_VMOVIN, DO_LOOP, DO_VMOVII, DO_VMOVII, DO_VMOVII, // VMOV@@ R4, RD (RD <> R4, if RD = R6, VPSH@ R4) if RD = R4, LOOP R4 instead DO_VMOVIN, DO_VMOVIN, DO_VMOVIN, DO_VMOVIN, DO_VMOVII, DO_LOOP, DO_VMOVII, DO_VMOVII, // VMOV@@ R5, RD (RD <> R5, if RD = R6, VPSH@ R5) if RD = R5, LOOP R5 instead DO_VMOV6N, DO_VMOV6N, DO_VMOV6N, DO_VMOV6N, DO_VMOV6I, DO_VMOV6I, DO_BA, DO_VMOV6I, // VMOV@@ R6, RD (RD <> R6, alternate: VPUL@ RD) if RD = R6, BA instead DO_VMOVIN, DO_VMOVIN, DO_VMOVIN, DO_VMOVIN, DO_VMOVII, DO_VMOVII, DO_VMOVII, DO_BNA, // VMVOI@ DATA, RD (RD <> R7, if RD = R6, VPSH@ DATA) if RD = R7, BNA instead // VADDx Src, RD ; v3d[RD] += v3d[Src] Adds a 3-vector from [Src] to [RD]. Each vector component is 32 bits. // 000010 1011 sss ddd DO_VADDNN, DO_VADDNN, DO_VADDNN, DO_VADDNN, DO_VADDNI, DO_VADDNI, DO_VADDNI, DO_VADDNI, // VADD@@ R0, RD DO_VADDNN, DO_VADDNN, DO_VADDNN, DO_VADDNN, DO_VADDNI, DO_VADDNI, DO_VADDNI, DO_VADDNI, // VADD@@ R1, RD DO_VADDNN, DO_VADDNN, DO_VADDNN, DO_VADDNN, DO_VADDNI, DO_VADDNI, DO_VADDNI, DO_VADDNI, // VADD@@ R2, RD DO_VADDNN, DO_VADDNN, DO_VADDNN, DO_VADDNN, DO_VADDNI, DO_VADDNI, DO_VADDNI, DO_VADDNI, // VADD@@ R3, RD DO_VADDIN, DO_VADDIN, DO_VADDIN, DO_VADDIN, DO_VADDSS, DO_VADDII, DO_VADDII, DO_VADDIN, // VADD@@ R4, RD DO_VADDIN, DO_VADDIN, DO_VADDIN, DO_VADDIN, DO_VADDII, DO_VADDSS, DO_VADDII, DO_VADDIN, // VADD@@ R5, RD DO_VADD6N, DO_VADD6N, DO_VADD6N, DO_VADD6N, DO_VADD6I, DO_VADD6I, DO_VADD66, DO_VADD6I, // VADD@@ R6, RD DO_VADDIN, DO_VADDIN, DO_VADDIN, DO_VADDIN, DO_VADDII, DO_VADDII, DO_VADDII, DO_VADDSS, // VADDI@ DATA, RD // VSUBx Src, RD ; v3d[RD] -= v3d[Src] Subtracts a 3-vector in [Src] from [RD]. Each vector component is 32 bits. // 000010 1100 sss ddd DO_VSUBNN, DO_VSUBNN, DO_VSUBNN, DO_VSUBNN, DO_VSUBNI, DO_VSUBNI, DO_VSUBNI, DO_VSUBNI, // VSUB@@ R0, RD DO_VSUBNN, DO_VSUBNN, DO_VSUBNN, DO_VSUBNN, DO_VSUBNI, DO_VSUBNI, DO_VSUBNI, DO_VSUBNI, // VSUB@@ R1, RD DO_VSUBNN, DO_VSUBNN, DO_VSUBNN, DO_VSUBNN, DO_VSUBNI, DO_VSUBNI, DO_VSUBNI, DO_VSUBNI, // VSUB@@ R2, RD DO_VSUBNN, DO_VSUBNN, DO_VSUBNN, DO_VSUBNN, DO_VSUBNI, DO_VSUBNI, DO_VSUBNI, DO_VSUBNI, // VSUB@@ R4, RD DO_VSUBIN, DO_VSUBIN, DO_VSUBIN, DO_VSUBIN, DO_VSUBSS, DO_VSUBII, DO_VSUBII, DO_VSUBIN, // VSUB@@ R4, RD DO_VSUBIN, DO_VSUBIN, DO_VSUBIN, DO_VSUBIN, DO_VSUBII, DO_VSUBSS, DO_VSUBII, DO_VSUBIN, // VSUB@@ R5, RD DO_VSUB6N, DO_VSUB6N, DO_VSUB6N, DO_VSUB6N, DO_VSUB6I, DO_VSUB6I, DO_VSUB66, DO_VSUB6I, // VSUB@@ R6, RD DO_VSUBIN, DO_VSUBIN, DO_VSUBIN, DO_VSUBIN, DO_VSUBII, DO_VSUBII, DO_VSUBII, DO_VSUBSS, // VSUBI@ DATA, RD // UNPR RB, RA ; RB = RA >> 8, RA &= 0xFF RA, RB = R0..R3 Unpacks RA into RB:RA // PCKR RS, RD ; RA = (RA & 0xFF) | (RB << 8) RA, RB = R0..R3 Packs the low bytes of RB:RA into RA // LOOPE RD ; RD--, ddd < 6, if RD is nonzero afterwards and if Z=1, R7 += disp // LOOPNE RD ; RD--, ddd < 6, if RD is nonzero afterwards and if Z=0, R7 += disp // BREVR RD ; RD = bit-reversed RD, RD = R0..R5 // LOOPS RD ; RD--, ddd < 6, if RD is negative afterwards and if S=1, R7 += disp // LOOPNS RD ; RD--, ddd < 6, if RD is not negative afterwards and if S=0, R7 += disp // COMC ; C = !C // STCP R0 ; if R0 contains an odd number of 1 bits, C = 1, else C = 0 (sets carry as R0 parity) // 000010 1101 00b baa UNPR // 000010 1101 01b baa PCKR // 000010 1101 100 ddd PPPP LOOPE ddd < 6 // 000010 1101 100 110 BREVR R0 // 000010 1101 100 111 BREVR R1 // 000010 1101 101 ddd PPPP LOOPNE ddd < 6 // 000010 1101 101 110 BREVR R2 // 000010 1101 101 111 BREVR R3 // 000010 1101 110 ddd PPPP LOOPS ddd < 6 // 000010 1101 110 110 BREVR R4 // 000010 1101 110 111 BREVR R5 // 000010 1101 111 ddd PPPP LOOPNS ddd < 6 // 000010 1101 111 110 COMC // 000010 1101 111 111 STCP DO_UNPR, DO_UNPR, DO_UNPR, DO_UNPR, DO_UNPR, DO_UNPR, DO_UNPR, DO_UNPR, // UNPR R0/R1, RA DO_UNPR, DO_UNPR, DO_UNPR, DO_UNPR, DO_UNPR, DO_UNPR, DO_UNPR, DO_UNPR, // UNPR R2/R3, RA DO_PCKR, DO_PCKR, DO_PCKR, DO_PCKR, DO_PCKR, DO_PCKR, DO_PCKR, DO_PCKR, // PCKR R0/R1, RA DO_PCKR, DO_PCKR, DO_PCKR, DO_PCKR, DO_PCKR, DO_PCKR, DO_PCKR, DO_PCKR, // PCKR R2/R3, RA DO_LOOPE, DO_LOOPE, DO_LOOPE, DO_LOOPE, DO_LOOPE, DO_LOOPE, DO_BREVR0, DO_BREVR1, // LOOPE R0..R5 BREVR R0/R1 DO_LOOPNE, DO_LOOPNE, DO_LOOPNE, DO_LOOPNE, DO_LOOPNE, DO_LOOPNE, DO_BREVR2, DO_BREVR3, // LOOPNE R0..R5 BREVR R2/R3 DO_LOOPS, DO_LOOPS, DO_LOOPS, DO_LOOPS, DO_LOOPS, DO_LOOPS, DO_BREVR4, DO_BREVR5, // LOOPS R0..R5 BREVR R4/R5 DO_LOOPNS, DO_LOOPNS, DO_LOOPNS, DO_LOOPNS, DO_LOOPNS, DO_LOOPNS, DO_COMC, DO_STCP, // LOOPNS R0..R5 COMC STCP // MAXR RS, RD ; RD = unsigned maximum of RS and RD. RS, RD = R0 .. R3 // MINR RS, RD ; RD = unsigned minimum of RS and RD. RS, RD = R0 .. R3 // IMAXR RS, RD ; RD = signed maximum of RS and RD. RS, RD = R0 .. R3 // IMINR RS, RD ; RD = signed minimum of RS and RD. RS, RD = R0 .. R3 // 000010 1110 00s sdd MAXR // 000010 1110 01s sdd MINR // 000010 1110 10s sdd IMAXR // 000010 1110 11s sdd IMINR DO_MAXR, DO_MAXR, DO_MAXR, DO_MAXR, DO_MAXR, DO_MAXR, DO_MAXR, DO_MAXR, // MAXR R0/R1, RD DO_MAXR, DO_MAXR, DO_MAXR, DO_MAXR, DO_MAXR, DO_MAXR, DO_MAXR, DO_MAXR, // MAXR R2/R3, RD DO_MINR, DO_MINR, DO_MINR, DO_MINR, DO_MINR, DO_MINR, DO_MINR, DO_MINR, // MINR R0/R1, RD DO_MINR, DO_MINR, DO_MINR, DO_MINR, DO_MINR, DO_MINR, DO_MINR, DO_MINR, // MINR R2/R3, RD DO_IMAXR, DO_IMAXR, DO_IMAXR, DO_IMAXR, DO_IMAXR, DO_IMAXR, DO_IMAXR, DO_IMAXR, // IMAXR R0/R1, RD DO_IMAXR, DO_IMAXR, DO_IMAXR, DO_IMAXR, DO_IMAXR, DO_IMAXR, DO_IMAXR, DO_IMAXR, // IMAXR R2/R3, RD DO_IMINR, DO_IMINR, DO_IMINR, DO_IMINR, DO_IMINR, DO_IMINR, DO_IMINR, DO_IMINR, // IMINR R0/R1, RD DO_IMINR, DO_IMINR, DO_IMINR, DO_IMINR, DO_IMINR, DO_IMINR, DO_IMINR, DO_IMINR, // IMINR R2/R3, RD // SBBR RD ; RD -= C // B2AH RD ; RD = hexadecimal ASCII representation of the low byte of RD (e.g. 0x0A --> 3041 "0A") // SHLD RD, IMM4 ; RD = high word of RD:R0 shifted left by 0 .. 15. C = high bit of RD shifted out if amount > 0. RD = R1 ... R3 // 000010 1111 000 ddd SBBR // 000010 1111 001 ddd B2AH // 000010 1111 dd aaaa SHLD DO_SBBR, DO_SBBR, DO_SBBR, DO_SBBR, DO_SBBR, DO_SBBR, DO_SBBR, DO_SBBR, // SBBR RD DO_B2AH, DO_B2AH, DO_B2AH, DO_B2AH, DO_B2AH, DO_B2AH, DO_B2AH, DO_B2AH, // B2AH RD DO_SHLD, DO_SHLD, DO_SHLD, DO_SHLD, DO_SHLD, DO_SHLD, DO_SHLD, DO_SHLD, // SHLD R1:R0 DO_SHLD, DO_SHLD, DO_SHLD, DO_SHLD, DO_SHLD, DO_SHLD, DO_SHLD, DO_SHLD, // SHLD R1:R0 DO_SHLD, DO_SHLD, DO_SHLD, DO_SHLD, DO_SHLD, DO_SHLD, DO_SHLD, DO_SHLD, // SHLD R2:R0 DO_SHLD, DO_SHLD, DO_SHLD, DO_SHLD, DO_SHLD, DO_SHLD, DO_SHLD, DO_SHLD, // SHLD R2:R0 DO_SHLD, DO_SHLD, DO_SHLD, DO_SHLD, DO_SHLD, DO_SHLD, DO_SHLD, DO_SHLD, // SHLD R3:R0 DO_SHLD, DO_SHLD, DO_SHLD, DO_SHLD, DO_SHLD, DO_SHLD, DO_SHLD, DO_SHLD, // SHLD R3:R0 // AH2B RD ; RD = binary value (0..255) of hexadecimal ASCII characters stored in RD. Invalid characters in a byte result // ; in that byte being interpreted as 0 (e.g. 3041 --> 0x0A, 2F41 --> 0x0A). Ignores case. // DIV5 RD ; RD /= 5 (unsigned divide) // SHRD RS, IMM4 ; R0 = low word of RS:R0 shifted right by 0 .. 15. C = low bit of R0 shifted out if amount > 0. RS = R1 ... R3 // 000011 0000 000 ddd AH2B // 000011 0000 001 ddd DIV5 // 000011 0000 ss aaaa SHRD DO_AH2B, DO_AH2B, DO_AH2B, DO_AH2B, DO_AH2B, DO_AH2B, DO_AH2B, DO_AH2B, // A2BH RD DO_DIV5, DO_DIV5, DO_DIV5, DO_DIV5, DO_DIV5, DO_DIV5, DO_DIV5, DO_DIV5, // DIV5 RD DO_SHRD, DO_SHRD, DO_SHRD, DO_SHRD, DO_SHRD, DO_SHRD, DO_SHRD, DO_SHRD, // SHRD R1:R0 DO_SHRD, DO_SHRD, DO_SHRD, DO_SHRD, DO_SHRD, DO_SHRD, DO_SHRD, DO_SHRD, // SHRD R1:R0 DO_SHRD, DO_SHRD, DO_SHRD, DO_SHRD, DO_SHRD, DO_SHRD, DO_SHRD, DO_SHRD, // SHRD R2:R0 DO_SHRD, DO_SHRD, DO_SHRD, DO_SHRD, DO_SHRD, DO_SHRD, DO_SHRD, DO_SHRD, // SHRD R2:R0 DO_SHRD, DO_SHRD, DO_SHRD, DO_SHRD, DO_SHRD, DO_SHRD, DO_SHRD, DO_SHRD, // SHRD R3:R0 DO_SHRD, DO_SHRD, DO_SHRD, DO_SHRD, DO_SHRD, DO_SHRD, DO_SHRD, DO_SHRD, // SHRD R3:R0 // CL0R RD ; RD = number of consecutive 0 bits in RD starting at the MSB // CL1R RD ; RD = number of consecutive 1 bits in RD starting at the MSB // CT0R RD ; RD = number of consecutive 0 bits in RD starting at the LSB // CT1R RD ; RD = number of consecutive 1 bits in RD starting at the LSB // SUBGER0 RD ; if RD >= R0 (unsigned compare), RD -= R0. Useful for speeding up division algorithms. // DIV3 RD ; RD /= 3 (unsigned divide) // DIV100 RD ; RD /= 100 (unsigned divide) // DUPLR RD ; RD = (RD & 0xFF) | (RD << 8) Duplicates the low byte in RD // 000011 0001 000 ddd CL0R // 000011 0001 001 ddd CL1R // 000011 0001 010 ddd CT0R // 000011 0001 011 ddd CT1R // 000011 0001 100 ddd SUBGER0 // 000011 0001 101 ddd DIV3 // 000011 0001 110 ddd DIV100 // 000011 0001 110 ddd DUPLR DO_CL0R, DO_CL0R, DO_CL0R, DO_CL0R, DO_CL0R, DO_CL0R, DO_CL0R, DO_CL0R, // CL0R RD DO_CL1R, DO_CL1R, DO_CL1R, DO_CL1R, DO_CL1R, DO_CL1R, DO_CL1R, DO_CL1R, // CL1R RD DO_CT0R, DO_CT0R, DO_CT0R, DO_CT0R, DO_CT0R, DO_CT0R, DO_CT0R, DO_CT0R, // CT0R RD DO_CT1R, DO_CT1R, DO_CT1R, DO_CT1R, DO_CT1R, DO_CT1R, DO_CT1R, DO_CT1R, // CT1R RD DO_SUBGER0, DO_SUBGER0, DO_SUBGER0, DO_SUBGER0, DO_SUBGER0, DO_SUBGER0, DO_SUBGER0, DO_SUBGER0, // SUBGER0 RD DO_DIV3, DO_DIV3, DO_DIV3, DO_DIV3, DO_DIV3, DO_DIV3, DO_DIV3, DO_DIV3, // DIV3 RD DO_DIV100, DO_DIV100, DO_DIV100, DO_DIV100, DO_DIV100, DO_DIV100, DO_DIV100, DO_DIV100, // DIV100 RD DO_DUPLR, DO_DUPLR, DO_DUPLR, DO_DUPLR, DO_DUPLR, DO_DUPLR, DO_DUPLR, DO_DUPLR, // DUPLR RD // DECLR RD ; Decrements only the low byte of RD. If RD was 0, it rolls over to 255 without affecting the high byte but sets the carry flag. // XCHGR RA, RB ; Swaps the contents of RA and RB RA <> RB // 000011 0010 aaa bbb XCHGR aaa <> bbb // 000011 0010 ddd ddd INCLR DO_DECLR, DO_XCHGR, DO_XCHGR, DO_XCHGR, DO_XCHGR, DO_XCHGR, DO_XCHGR, DO_XCHGR, // DECLR R0, XCHGR RA, RB DO_XCHGR, DO_DECLR, DO_XCHGR, DO_XCHGR, DO_XCHGR, DO_XCHGR, DO_XCHGR, DO_XCHGR, // DECLR R1, XCHGR RA, RB DO_XCHGR, DO_XCHGR, DO_DECLR, DO_XCHGR, DO_XCHGR, DO_XCHGR, DO_XCHGR, DO_XCHGR, // DECLR R2, XCHGR RA, RB DO_XCHGR, DO_XCHGR, DO_XCHGR, DO_DECLR, DO_XCHGR, DO_XCHGR, DO_XCHGR, DO_XCHGR, // DECLR R3, XCHGR RA, RB DO_XCHGR, DO_XCHGR, DO_XCHGR, DO_XCHGR, DO_DECLR, DO_XCHGR, DO_XCHGR, DO_XCHGR, // DECLR R4, XCHGR RA, RB DO_XCHGR, DO_XCHGR, DO_XCHGR, DO_XCHGR, DO_XCHGR, DO_DECLR, DO_XCHGR, DO_XCHGR, // DECLR R5, XCHGR RA, RB DO_XCHGR, DO_XCHGR, DO_XCHGR, DO_XCHGR, DO_XCHGR, DO_XCHGR, DO_DECLR, DO_XCHGR, // DECLR R6, XCHGR RA, RB DO_XCHGR, DO_XCHGR, DO_XCHGR, DO_XCHGR, DO_XCHGR, DO_XCHGR, DO_XCHGR, DO_DECLR, // DECLR R7, XCHGR RA, RB // MVID@ RM, RD, disp ; RD = [RM + disp] Does ***not*** change R4 .. R6 if mmm=4..6. Supports SDBD. // 000011 0011 mmm ddd PPPP MVID DO_MVID, DO_MVID, DO_MVID, DO_MVID, DO_MVID, DO_MVID, DO_MVID, DO_MVID, // MVID@ R0, RD, disp DO_MVID, DO_MVID, DO_MVID, DO_MVID, DO_MVID, DO_MVID, DO_MVID, DO_MVID, // MVID@ R1, RD, disp DO_MVID, DO_MVID, DO_MVID, DO_MVID, DO_MVID, DO_MVID, DO_MVID, DO_MVID, // MVID@ R2, RD, disp DO_MVID, DO_MVID, DO_MVID, DO_MVID, DO_MVID, DO_MVID, DO_MVID, DO_MVID, // MVID@ R3, RD, disp DO_MVID, DO_MVID, DO_MVID, DO_MVID, DO_MVID, DO_MVID, DO_MVID, DO_MVID, // MVID@ R4, RD, disp DO_MVID, DO_MVID, DO_MVID, DO_MVID, DO_MVID, DO_MVID, DO_MVID, DO_MVID, // MVID@ R5, RD, disp DO_MVID, DO_MVID, DO_MVID, DO_MVID, DO_MVID, DO_MVID, DO_MVID, DO_MVID, // MVID@ R6, RD, disp DO_MVID, DO_MVID, DO_MVID, DO_MVID, DO_MVID, DO_MVID, DO_MVID, DO_MVID, // MVID@ R7, RD, disp // MVOD@ RM, RS, disp ; [RM + disp] = RS Does ***not*** change R4 .. R6 if mmm=4..6. Supports SDBD. // 000011 0100 mmm sss PPPP MVOD DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, // MVOD@ R0, RD, disp DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, // MVOD@ R1, RD, disp DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, // MVOD@ R2, RD, disp DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, // MVOD@ R3, RD, disp DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, // MVOD@ R4, RD, disp DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, // MVOD@ R5, RD, disp DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, // MVOD@ R6, RD, disp DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, DO_MVOD, // MVOD@ R7, RD, disp // ABSR RD ; RD = |RD| // POW2R RD ; RD = 1 << RD If RD > 15, result is 0 // ABSRW@ RD ; D[RD] = |D[RD]| Replaces the 32-bit DWORD at [RD] with its absolute value // MVO@ R0, RS ; Just like normal MVO@ but supports R0 // MVI@ R0, RD ; Just like normal MVI@ but supports R0 // ADD@ R0, RD ; Just like normal ADD@ but supports R0 // SUB@ R0, RD ; Just like normal SUB@ but supports R0 // CMP@ R0, RD ; Just like normal CMP@ but supports R0 // 000011 0101 000 ddd ABSR // 000011 0101 001 ddd POW2R // 000011 0101 010 ddd ABSRW@ // 000011 0101 011 sss MVO@ R0, RS // 000011 0101 100 ddd MVI@ R0, RD // 000011 0101 101 ddd ADD@ R0, RD // 000011 0101 110 ddd SUB@ R0, RD // 000011 0101 111 ddd CMP@ R0, RD DO_ABSR, DO_ABSR, DO_ABSR, DO_ABSR, DO_ABSR, DO_ABSR, DO_ABSR, DO_ABSR, // ABSR RD DO_POW2R, DO_POW2R, DO_POW2R, DO_POW2R, DO_POW2R, DO_POW2R, DO_POW2R, DO_POW2R, // POW2R RD DO_ABSRWI, DO_ABSRWI, DO_ABSRWI, DO_ABSRWI, DO_ABSRWN, DO_ABSRWN, DO_ABSRW6, DO_ABSRWN, // ABSRW@ RD DO_MVOA0, DO_MVOA0, DO_MVOA0, DO_MVOA0, DO_MVOA0, DO_MVOA0, DO_MVOA0, DO_MVOA0, // MVO@ R0, RS DO_MVIA0, DO_MVIA0, DO_MVIA0, DO_MVIA0, DO_MVIA0, DO_MVIA0, DO_MVIA0, DO_MVIA0, // MVI@ R0, RD DO_ADDA0, DO_ADDA0, DO_ADDA0, DO_ADDA0, DO_ADDA0, DO_ADDA0, DO_ADDA0, DO_ADDA0, // ADD@ R0, RD DO_SUBA0, DO_SUBA0, DO_SUBA0, DO_SUBA0, DO_SUBA0, DO_SUBA0, DO_SUBA0, DO_SUBA0, // SUB@ R0, RD DO_CMPA0, DO_CMPA0, DO_CMPA0, DO_CMPA0, DO_CMPA0, DO_CMPA0, DO_CMPA0, DO_CMPA0, // CMP@ R0, RD // AND@ R0, RD ; Just like normal AND@ but supports R0 // XOR@ R0, RD ; Just like normal XOR@ but supports R0 // OR ADDR, RD ; RD |= [ADDR] // ADC ADDR, RD ; RD += [ADDR] + C // SBB ADDR, RD ; RD -= ([ADDR] + C) // TST ADDR, RD ; Set S and Z flags based on (RD & [ADDR]) // SLL ADDR, RD ; RD <<= [ADDR] // SLR ADDR, RD ; RD >>= [ADDR] // 000011 0110 000 ddd AND@ R0, RD // 000011 0110 001 ddd XOR@ R0, RD // 000011 0110 010 ddd OR ADDR, RD // 000011 0110 011 ddd ADC ADDR, RD // 000011 0110 100 ddd SBB ADDR, RD // 000011 0110 101 ddd TST ADDR, RD // 000011 0110 110 ddd SLL ADDR, RD // 000011 0110 111 ddd SLR ADDR, RD DO_ANDA0, DO_ANDA0, DO_ANDA0, DO_ANDA0, DO_ANDA0, DO_ANDA0, DO_ANDA0, DO_ANDA0, // AND@ R0, RD DO_XORA0, DO_XORA0, DO_XORA0, DO_XORA0, DO_XORA0, DO_XORA0, DO_XORA0, DO_XORA0, // XOR@ R0, RD DO_OR, DO_OR, DO_OR, DO_OR, DO_OR, DO_OR, DO_OR, DO_OR, // OR RD, ADDR DO_ADC, DO_ADC, DO_ADC, DO_ADC, DO_ADC, DO_ADC, DO_ADC, DO_ADC, // ADC RD, ADDR DO_SBB, DO_SBB, DO_SBB, DO_SBB, DO_SBB, DO_SBB, DO_SBB, DO_SBB, // SBB RD, ADDR DO_TST, DO_TST, DO_TST, DO_TST, DO_TST, DO_TST, DO_TST, DO_TST, // TST RS, ADDR DO_SLLA, DO_SLLA, DO_SLLA, DO_SLLA, DO_SLLA, DO_SLLA, DO_SLLA, DO_SLLA, // SLL RD, ADDR DO_SLRA, DO_SLRA, DO_SLRA, DO_SLRA, DO_SLRA, DO_SLRA, DO_SLRA, DO_SLRA, // SLR RD, ADDR // SAR ADDR, RD ; RD = RD sar [ADDR] (arithmetic shift right) // ROL ADDR, RD ; RD = RD rol [ADDR] // ROR ADDR, RD ; RD = RD ror [ADDR] // MUL ADDR, RD ; RD *= [ADDR] (unsigned multiply) // IMUL ADDR, RD ; RD *= [ADDR] (signed multiply) // VMOV@ ADDR, RD ; v3d[RD] = v3d[ADDR] Copies a 3-vector from [ADDR] to [RD]. Each vector component is 32 bits. // VADD@ ADDR, RD ; v3d[RD] += v3d[ADDR] Adds a 3-vector from [ADDR] to [RD]. Each vector component is 32 bits. // VSUB@ ADDR, RD ; v3d[RD] -= v3d[ADDR] Subtracts a 3-vector in [ADDR] from [RD]. Each vector component is 32 bits. // 000011 0111 000 ddd SAR ADDR, RD // 000011 0111 001 ddd ROL ADDR, RD // 000011 0111 010 ddd ROR ADDR, RD // 000011 0111 011 ddd MUL ADDR, RD // 000011 0111 100 ddd IMUL ADDR, RD // 000011 0111 101 ddd VMOV ADDR, RD // 000011 0111 110 ddd VADD ADDR, RD // 000011 0111 111 ddd VSUB ADDR, RD DO_SARA, DO_SARA, DO_SARA, DO_SARA, DO_SARA, DO_SARA, DO_SARA, DO_SARA, // SAR RD, ADDR DO_ROL, DO_ROL, DO_ROL, DO_ROL, DO_ROL, DO_ROL, DO_ROL, DO_ROL, // ROL RD, ADDR DO_ROR, DO_ROR, DO_ROR, DO_ROR, DO_ROR, DO_ROR, DO_ROR, DO_ROR, // ROR RD, ADDR DO_MUL, DO_MUL, DO_MUL, DO_MUL, DO_MUL, DO_MUL, DO_MUL, DO_MUL, // MUL ADDR, RD DO_IMUL, DO_IMUL, DO_IMUL, DO_IMUL, DO_IMUL, DO_IMUL, DO_IMUL, DO_IMUL, // IMUL ADDR, RD DO_VMOVN, DO_VMOVN, DO_VMOVN, DO_VMOVN, DO_VMOVI, DO_VMOVI, DO_VMOVI, DO_VMOVI, // VMOV@ ADDR, RMD (if RMD = R6, VPSH ADDR) DO_VADDN, DO_VADDN, DO_VADDN, DO_VADDN, DO_VADDI, DO_VADDI, DO_VADDI, DO_VADDI, // VADD@ ADDR, RMD DO_VSUBN, DO_VSUBN, DO_VSUBN, DO_VSUBN, DO_VSUBI, DO_VSUBI, DO_VSUBI, DO_VSUBI, // VSUB@ ADDR, RMD // FPMULDx Src, RD ; Unsigned 32-bit fixed-point values (16.16 format) at Src and [RD] are multiplied and the // ; 16.16 format fixed-point result placed in [RD]. // 000011 1000 sss ddd FPMULD@@ [RS], RD ; F[RD] *= F[RS] // 000011 1000 111 ddd FPMULDI@ DATA, RD ; F[RD] *= DATA (32-bit immediate in 16.16 format) DO_FPMULDNN, DO_FPMULDNN, DO_FPMULDNN, DO_FPMULDNN, DO_FPMULDNI, DO_FPMULDNI, DO_FPMULDNI, DO_FPMULDNI, // FPMULD@@ R0, RD DO_FPMULDNN, DO_FPMULDNN, DO_FPMULDNN, DO_FPMULDNN, DO_FPMULDNI, DO_FPMULDNI, DO_FPMULDNI, DO_FPMULDNI, // FPMULD@@ R1, RD DO_FPMULDNN, DO_FPMULDNN, DO_FPMULDNN, DO_FPMULDNN, DO_FPMULDNI, DO_FPMULDNI, DO_FPMULDNI, DO_FPMULDNI, // FPMULD@@ R2, RD DO_FPMULDNN, DO_FPMULDNN, DO_FPMULDNN, DO_FPMULDNN, DO_FPMULDNI, DO_FPMULDNI, DO_FPMULDNI, DO_FPMULDNI, // FPMULD@@ R3, RD DO_FPMULDIN, DO_FPMULDIN, DO_FPMULDIN, DO_FPMULDIN, DO_FPMULDII, DO_FPMULDII, DO_FPMULDII, DO_FPMULDII, // FPMULD@@ R4, RD DO_FPMULDIN, DO_FPMULDIN, DO_FPMULDIN, DO_FPMULDIN, DO_FPMULDII, DO_FPMULDII, DO_FPMULDII, DO_FPMULDII, // FPMULD@@ R5, RD DO_FPMULD6N, DO_FPMULD6N, DO_FPMULD6N, DO_FPMULD6N, DO_FPMULD6I, DO_FPMULD6I, DO_FPMULD6I, DO_FPMULD6I, // FPMULD@@ R6, RD DO_FPMULDIN, DO_FPMULDIN, DO_FPMULDIN, DO_FPMULDIN, DO_FPMULDII, DO_FPMULDII, DO_FPMULDII, DO_FPMULDII, // FPMULDI@ DATA, RD // Reserved for Locutus // 000011 1001 ... ... DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, DO_NOP, // IFPMULDx Src, RD ; Signed 32-bit fixed-point values (16.16 format) at Src and [RD] are multiplied and the // ; 16.16 format fixed-point result placed in [RD]. // 000011 1010 sss ddd IFPMULD@@ [RS], RD ; F[RD] *= F[RS] // 000011 1010 111 ddd IFPMULDI@ DATA, RD ; F[RD] *= DATA (32-bit immediate in 16.16 format) DO_IFPMULDNN, DO_IFPMULDNN, DO_IFPMULDNN, DO_IFPMULDNN, DO_IFPMULDNI, DO_IFPMULDNI, DO_IFPMULDNI, DO_IFPMULDNI, // IFPMULD@@ R0, RD DO_IFPMULDNN, DO_IFPMULDNN, DO_IFPMULDNN, DO_IFPMULDNN, DO_IFPMULDNI, DO_IFPMULDNI, DO_IFPMULDNI, DO_IFPMULDNI, // IFPMULD@@ R1, RD DO_IFPMULDNN, DO_IFPMULDNN, DO_IFPMULDNN, DO_IFPMULDNN, DO_IFPMULDNI, DO_IFPMULDNI, DO_IFPMULDNI, DO_IFPMULDNI, // IFPMULD@@ R2, RD DO_IFPMULDNN, DO_IFPMULDNN, DO_IFPMULDNN, DO_IFPMULDNN, DO_IFPMULDNI, DO_IFPMULDNI, DO_IFPMULDNI, DO_IFPMULDNI, // IFPMULD@@ R3, RD DO_IFPMULDIN, DO_IFPMULDIN, DO_IFPMULDIN, DO_IFPMULDIN, DO_IFPMULDII, DO_IFPMULDII, DO_IFPMULDII, DO_IFPMULDII, // IFPMULD@@ R4, RD DO_IFPMULDIN, DO_IFPMULDIN, DO_IFPMULDIN, DO_IFPMULDIN, DO_IFPMULDII, DO_IFPMULDII, DO_IFPMULDII, DO_IFPMULDII, // IFPMULD@@ R5, RD DO_IFPMULD6N, DO_IFPMULD6N, DO_IFPMULD6N, DO_IFPMULD6N, DO_IFPMULD6I, DO_IFPMULD6I, DO_IFPMULD6I, DO_IFPMULD6I, // IFPMULD@@ R6, RD DO_IFPMULDIN, DO_IFPMULDIN, DO_IFPMULDIN, DO_IFPMULDIN, DO_IFPMULDII, DO_IFPMULDII, DO_IFPMULDII, DO_IFPMULDII, // IFPMULDI@ DATA, RD // FPMULD@ ADDR, RD ; Unsigned 32-bit fixed-point values (16.16 format) at Src and [RD] are multiplied and the // ; 16.16 format fixed-point result placed in [RD]. // IFPMULDx ADDR, RD ; Signed 32-bit fixed-point values (16.16 format) at Src and [RD] are multiplied and the // ; 16.16 format fixed-point result placed in [RD]. // MVOI DATA, ADDR ; [ADDR] = DATA // ADDI DATA, ADDR ; [ADDR] += DATA // SUBI DATA, ADDR ; [ADDR] -= DATA // CMPI DATA, ADDR ; Sets flags based on ([ADDR] - DATA) // ANDI DATA, ADDR ; [ADDR] &= DATA // XORI DATA, ADDR ; [ADDR] ^= DATA // ORI DATA, ADDR ; [ADDR] |= DATA // ADCI DATA, ADDR ; [ADDR] += DATA + C // SBBI DATA, ADDR ; [ADDR] -= (DATA + C) // TSTI DATA, ADDR ; Sets Z and S flags based on ([ADDR] & DATA) // SLLI DATA, ADDR ; [ADDR] <<= DATA // SLRI DATA, ADDR ; [ADDR] >>= DATA // SARI DATA, ADDR ; [ADDR] = [ADDR] sar DATA (arithmetic shift right) // ROLI DATA, ADDR ; [ADDR] = [ADDR] rol DATA // ROLI DATA, ADDR ; [ADDR] = [ADDR] ror DATA // MULI DATA, ADDR ; [ADDR] *= DATA (unsigned multiply) // IMULI DATA, ADDR ; [ADDR] *= DATA (signed multiply) // STCP RD ; RD = R1..R3 if RD contains an odd number of 1 bits, C = 1, else C = 0 (sets carry as RD parity) // SWAP RD ; Same as SWAP, but supports R4..R7 // 000011 1011 000 ddd FPMULD@ ADDR, RD ; F[RD] *= F[ADDR] // 000011 1011 001 ddd IFPMULD@ ADDR, RD ; F[RD] *= F[ADDR] // 000011 1011 001 000 MVOIA DATA, ADDR // 000011 1011 001 001 ADDIA DATA, ADDR // 000011 1011 001 010 SUBIA DATA, ADDR // 000011 1011 001 011 CMPIA DATA, ADDR // 000011 1011 001 100 ANDIA DATA, ADDR // 000011 1011 001 101 XORIA DATA, ADDR // 000011 1011 001 110 ORIA DATA, ADDR // 000011 1011 001 111 ADCIA DATA, ADDR // 000011 1001 010 000 SBBIA DATA, ADDR // 000011 1011 010 001 TSTIA DATA, ADDR // 000011 1011 010 010 SLLIA DATA, ADDR // 000011 1011 010 011 SLRIA DATA, ADDR // 000011 1011 010 100 SARIA DATA, ADDR // 000011 1011 010 101 ROLIA DATA, ADDR // 000011 1011 010 110 RORIA DATA, ADDR // 000011 1011 010 111 MULIA DATA, ADDR // 000011 1011 011 000 IMULIA DATA, ADDR // 000011 1011 011 0dd STCP RD dd <> 0 // 000011 1011 011 1dd SWAP RD RD=dd+4 DO_FPMULDN, DO_FPMULDN, DO_FPMULDN, DO_FPMULDN, DO_FPMULDI, DO_FPMULDI, DO_FPMULDI, DO_FPMULDI, // FPMULD@ ADDR, RD DO_IFPMULDN, DO_IFPMULDN, DO_IFPMULDN, DO_IFPMULDN, DO_IFPMULDI, DO_IFPMULDI, DO_IFPMULDI, DO_IFPMULDI, // IFPMULD@ ADDR, RD DO_MVOIA, DO_ADDIA, DO_SUBIA, DO_CMPIA, DO_ANDIA, DO_XORIA, DO_ORIA, DO_ADCIA, DO_SBBIA, DO_TSTIA, DO_SLLIA, DO_SLRIA, DO_SARIA, DO_ROLIA, DO_RORIA, DO_MULIA, DO_IMULIA, DO_STCP123, DO_STCP123, DO_STCP123, DO_SWAP3, DO_SWAP3, DO_SWAP3, DO_SWAP3 }; Edited January 9, 2022 by JohnPCAE Quote Link to comment Share on other sites More sharing options...
JohnPCAE Posted January 10, 2022 Author Share Posted January 10, 2022 (edited) I managed to condense how I handle instruction dispatching to save space by using a pair of smaller lookup tables instead of one large one. It incurs a very tiny performance penalty but in the grand scheme of things it's only a few clock cycles. This freed up a bunch of RAM and I managed to add more emulated instructions and expand some existing ones. I found that the Pi Pico has a hardware integer divider so I've added a bunch of divide and remainder instructions, a bunch of new bitwise instructions inspired by the Locutus ones (NAND, NOR, etc.) and some other odds and ends. My RS-232 tester came in, but...Cancer? WTH? Edited January 10, 2022 by JohnPCAE Quote Link to comment Share on other sites More sharing options...
Sinjinhawke Posted January 10, 2022 Share Posted January 10, 2022 Wow, keep that away from your ovaries. Quote Link to comment Share on other sites More sharing options...
JohnPCAE Posted January 10, 2022 Author Share Posted January 10, 2022 1 hour ago, Sinjinhawke said: Wow, keep that away from your ovaries. LOL. I opened it up and took a look inside. I didn't see anything out of the ordinary, just a standard circuit board with LED's, DIP switches, and some SIP resistor arrays. I was half expecting a tritium battery or something ? 1 Quote Link to comment Share on other sites More sharing options...
JohnPCAE Posted January 11, 2022 Author Share Posted January 11, 2022 (edited) I'm happy to say that my Intellivision now has a working bidirectional parallel port ? The current hardware differs from standard parallel ports in one way: you cannot receive data on the four control signals (STROBE, AUTO_LINEFEED, INITIALIZE, SELECT_PRINTER). That said, I found a way to enhance the board design so that it's possible to receive data on three of them. I had three pins available on one of my LS245 chips so I can route the first three of them to those input pins. I have 1k resistors on those four control pins between my LS574 outputs and the actual parallel port pin, so I simply needed to run traces from three parallel port pins to the three free inputs on my LS245 chip. Those three inputs will show up in three spare bits on the printer status port. So with the exception of pin 17 (Select_Printer), the Inty can fulfill all of the functions of a standard parallel port (pin 17 will be output-only). And it has input capability on the data pins (you switch the data pins from output to input by setting bit 5 on the control port, just as you would on a PC). Edited January 11, 2022 by JohnPCAE 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.