Shop OBEX P1 Docs P2 Docs Learn Events
Hub FIFO - what happens if the underlying hub value is changed for a value in the FIFO? — Parallax Forums

Hub FIFO - what happens if the underlying hub value is changed for a value in the FIFO?

To answer my own question, I'm assuming that the FIFO would return the original value, not the changed value, and that there's no detection of changes to the hub for the values stored in the FIFO.

In other words, changing hub values that are currently in the FIFO is a bad idea.

Why this matters:

I'm working on version 2 of my IBM 1130 emulator. Using XBYTE looks promising... but the 1130 uses self-modifying code. Which could mean that the FIFO becomes "dirty" when the hub is updated with a dynamically generated instruction.

Thanks,

Walter

Comments

  • cgraceycgracey Posts: 14,155
    Yes, the FIFO queues data from the hub and if the same locations in hub are rewritten, the FIFO doesn't know it and issues the old data it is storing, until it reloads for some reason and gets updated data.

    For what you are doing, it might be good to just do a RDBYTE.
  • wmosscrop wrote: »
    I'm working on version 2 of my IBM 1130 emulator. Using XBYTE looks promising... but the 1130 uses self-modifying code. Which could mean that the FIFO becomes "dirty" when the hub is updated with a dynamically generated instruction.

    My knowledge of the IBM 1130 is zero, but I suggest executing a hidden branch instruction to reload the FIFO at the end of an instruction that is or might be self-modifying.
  • That would probably work for a single-threaded application, but my emulator uses multiple cogs for purposes such as emulating the disk drive, etc.

    Code to be executed by XBYTE can be loaded into hub by the disk cog or the card reader (during system cold start) cog. I can't wait for the load to complete as the code is not in hub until after the "operation complete" interrupt occurs.

    In the case of the 1130, a significant percentage (about 25%) of the commonly-used instructions can cause hub values to change. This would mean reloading the FIFO about every 4th instruction on average.

    Thanks for the idea, but I think I will have to go with the RDBYTE suggestion.
  • TonyB_TonyB_ Posts: 2,179
    edited 2020-03-10 11:27
    So are you intending to use RDBYTE for every instruction fetch and not use XBYTE at all?

    I don't know how important execution speed is in this case. A normal RDFAST to reload the FIFO is only slightly slower then a RDBYTE and a no-delay RDFAST might end up quicker because other P2 instructions could be executed between the RDFAST and the first RFBYTE.

    I recommend using XBYTE if you can. It's a superfast mechanism and fetching instructions from the FIFO means you don't need to update the program counter (Instruction-Address Register). Use GETPTR instead, but only when you really need to know the PC (IAR).
  • Well, XBYTE became a moot point.

    The 1130 uses word-length instructions, and the opcode and some flags are stored in [15:8] of the instruction. But if I try to use XBYTE it will read [7:0] of the instruction word first. My initial assumption ignored the endian differences between the machines.

    Which won't work.

    But I may still be able to use RFWORD. Only about 10% of executed instructions affect the hub. I/O is the tricky one, but I think I can handle it since any executable code read in from a device would not be executed until the "operation complete" interrupt was processed.

    Many of the instructions use relative addressing for hub access, which would imply using GETPTR quite often. It might still be faster to do this, but I'll need to run some empirical trials to see what's faster.

    Overall, speed isn't really an issue. The original 1130 could only execute 100K to 200K instructions per second. My P1 emulator is about 4 times faster than that.

    Thanks for everyone's help!



  • wmosscrop wrote: »
    Well, XBYTE became a moot point.

    The 1130 uses word-length instructions, and the opcode and some flags are stored in [15:8] of the instruction. But if I try to use XBYTE it will read [7:0] of the instruction word first. My initial assumption ignored the endian differences between the machines.

    Which won't work.

    Much thought went into making XBYTE the best it could be for emulating old processors. Frankly too much to give up so easily! Byte order is not really important and XBYTE will work.

    Define opcode0 = instruction word[7:0] and opcode1 = instruction word[15:8], use RFBYTE to read and store opcode0, then do a return to start the XBYTE executor for opcode1 (with $1FF on top of stack and previous SETQ to set the mode). XBYTE writes the bytecode to PA so a separate opcode1 register is not essential, although you might need to copy PA sometimes to manipulate the non-opcode bits.

    Instruction fetch could be as simple as:
    	_ret_	rfbyte	opcode0		'read opcode0, _ret_ starts XBYTE for opcode1
    
  • I think that will work!

    In my case, there are 5 opcode bits (32 possible instructions), one instruction length bit (for which, if set, I[ do a RFWORD to get the second half of the "long" instruction), and two "tag" bits, which are used to select the IAR or one of three "index" registers.

    By using one or two SKIPF sequences (probably just one), I'll be able to quickly decode those three bits and the 8 bits of opcode0 (which vary depending on the instruction).

    My P2 board should arrive tomorrow. Basically about 10 years after I started working with the P1.

    Definitely looking forward to playing with all of these new instructions and features. I've held off until now to allow all of you wonderful folks to pave the way for the P2 basics.

    Thanks for your help!
  • TonyB_TonyB_ Posts: 2,179
    edited 2020-03-11 19:56
    wmosscrop wrote: »
    In my case, there are 5 opcode bits (32 possible instructions), one instruction length bit (for which, if set, I[ do a RFWORD to get the second half of the "long" instruction), and two "tag" bits, which are used to select the IAR or one of three "index" registers.

    By using one or two SKIPF sequences (probably just one), I'll be able to quickly decode those three bits and the 8 bits of opcode0 (which vary depending on the instruction).

    I've been looking at http://www.ibm1130.net/functional/ and the short/long Format bit is next to the five OPeration bits in the instruction word. Therefore {OP,F} could be used as a 6-bit LUT index for XBYTE, requiring 64 LUT longs, with no need to decode F later.

    As the instruction length is either one or two words, it might be easier to implement IAR and not use GETPTR. Also, a zero address register could be added to IAR to generate the physical memory address so that 1130 code could start anywhere in hub RAM.

    GETPTR is handy when instruction length varies considerably, as it can eliminate quite a lot of different program counter increment instructions that use up valuable skip bits.
  • I came to the same conclusion, to use only the opcode + length bit for XBYTE.

    I feel like I did when I first started working with the P1. So many new features, so little time...
Sign In or Register to comment.