Hub Memory
The Propeller 2 features 512 kiB of "Hub RAM" that is shared between all cogs. The architecture allows for up to 1024 kiB, but this additional space is unused in the current chip. Hub RAM is addressed in bytes, but an entire long (4 aligned bytes) can be read or written at once. All larger-than-byte memory operations are little-endian.
To facilitate the sharing of the memory, a round-robin access scheme is used. On each cycle, each cog has the potential to access a different "slice" of memory, consisting of all addresses where (A>>2)&7 == N
. On the following cycle, the access windows "rotate" and each cog has access to the logically following slice.
TODO: I suck at writing these
Block Transfers
By preceding RDLONG with either SETQ or SETQ2, multiple hub RAM longs can be read into either Cog RAM or Lookup RAM. This transfer happens at the rate of one long per cycle, assuming the hub FIFO interface is not accessing the same hub RAM slice as RDLONG, on the same cycle, in which case the FIFO gets priority access and the block move must wait 8 cycles(?? TODO) for the hub RAM slice to come around again. If WC/WZ/WCZ are used with RDLONG, the flags will be set according to the last long read in the sequence.
Use SETQ+RDLONG to read multiple hub longs into cog register RAM:
SETQ #x 'x = number of longs, minus 1, to read
RDLONG first_reg,S/#/PTRx 'read x+1 longs starting at first_reg
Use SETQ2+RDLONG to read multiple hub longs into cog lookup RAM:
SETQ2 #x 'x = number of longs, minus 1, to read
RDLONG first_lut,S/#/PTRx 'read x+1 longs starting at first_lut
(TODO: LUT addressing is kinda curious, elaborate)
Similarly, WRLONG and WMLONG can be preceded by either SETQ or SETQ2 to write either multiple register RAM longs or lookup RAM longs into hub RAM. When WRLONG/WMLONG‘s Destination field is an immediate, it instead writes that immediate value to RAM, functioning as a memory filler. (TODO I think I recall fill doesn't work with SETQ2)
Use SETQ+WRLONG/WMLONG to write multiple register RAM longs into hub RAM:
SETQ #x 'x = number of longs, minus 1, to write
WRLONG first_reg,S/#/PTRx 'write x+1 longs starting at first_reg
Use SETQ2+WRLONG/WMLONG to write multiple lookup RAM longs into hub RAM:
SETQ2 #x 'x = number of longs, minus 1, to write
WRLONG first_lut,S/#/PTRx 'write x+1 longs starting at first_lut
(TODO: LUT addressing is kinda curious, elaborate)
Use SETQ+WRLONG to fill multiple longs of hub RAM:
SETQ #x 'x = number of longs, minus 1, to write
WRLONG ##$89ABCDEF,S/#/PTRx 'write x+1 longs of $89ABCDEF
For block transfers, PTRx expressions cannot have arbitrary index values, since the index will be overridden with the number of longs. Only unindexed increment/decrement modes are allowed.
Pointer Expressions
Instead of using a normal Source register to provide the address, most Hub (and LUT) access instructions allow a "pointer expression", using the PTRA or PTRB registers with an offset and/or automatic increment/decrement.
TODO: More
Encoding | Syntax | Accessed Address | Post-Modify | Block Transfers |
---|---|---|---|---|
0IIIIIIII | #immediate | immediate | Valid | |
1x0000000 | PTRx | PTRx | Valid | |
1x0iiiiii | PTRx[INDEX6] | PTRx + INDEX*SCALE | Not Valid | |
1x1100001 | PTRx++ | PTRx, | PTRx += SCALE | Valid |
1x1111111 | PTRx-- | PTRx, | PTRx -= SCALE | Valid |
1x1000001 | ++PTRx | PTRx + SCALE, | PTRx += SCALE | Valid |
1x1011111 | --PTRx | PTRx - SCALE, | PTRx -= SCALE | Valid |
1x110NNNN | PTRx++[INDEX5] | PTRx, | PTRx += INDEX*SCALE | Not Valid |
1x111nnnn | PTRx--[INDEX5] | PTRx, | PTRx -= INDEX*SCALE | Not Valid |
1x100NNNN | ++PTRx[INDEX5] | PTRx + INDEX*SCALE | PTRx += INDEX*SCALE | Not Valid |
1x101nnnn | --PTRx[INDEX5] | PTRx - INDEX*SCALE | PTRx -= INDEX*SCALE | Not Valid |
SCALE
is 1 for BYTE and LUT operations, 2 for WORD operations and 4 for LONG operations. When using an augmented operand (##/AUGS), SCALE is always 1.- The bit indicated as
x
is set (1) for PTRB and clear (0) for PTRA - The index value for
PTRx[INDEX6]
(denotediiiiii
) is a 6-bit value and can thus can range from -32 to 31. - The index value for inc/dec expressions (denoted
0NNNN
or1nnnn
) is a 5-bit signed value with a special case wherein00000
means 16. It can thus range from 1 to 16 in either positive or negative direction.
Hub Timing
Reading from Hub RAM takes at least 9 cycles. Writing to Hub RAM takes at least 3 cycles.
Up to 7 cycles are added to wait for relevant slice's access slot.
An additional cycle is added if the access crosses a long boundary. (i.e. any unaligned long access or a word access to the last byte of a long).
TODO: Examples of optimal timing (research involved)
Instructions
{ SETQ/SETQ2 {#}Q }
RDLONG D,{#}S/P {WC/WZ/WCZ} - Read long from Hub
Encoding | Register Written | C Flag | Z Flag | Cycles (cogexec) | Cycles (hubexec) | IRQ Shield | EEEE 1011000 CZI DDDDDDDDD SSSSSSSSS | D | MSB of long | Result == 0 | 9..17 | 9..27 | No |
---|
RDLONG reads a long (32 bits) from the 4 consecutive Hub memory locations addressed by Source or a pointer expression into Destination. Only the bottom 20 bits of the effective address are considered, the rest are ignored. Unaligned reads are possible, but carry a one-cycle penalty. (See Hub Timing)
If the WC or WCZ effect is specified, the C flag is set to the MSB (bit 31) of the read value.
If the WZ or WCZ effect is specified, the Z flag is set (1) if the read value equals zero, or is cleared (0) if it is non-zero.
If prefixed with SETQ or SETQ2, a block transfer is initiated.
RDWORD D,{#}S/P {WC/WZ/WCZ} - Read word from Hub
Encoding | Register Written | C Flag | Z Flag | Cycles (cogexec) | Cycles (hubexec) | IRQ Shield | EEEE 1010111 CZI DDDDDDDDD SSSSSSSSS | D | MSB of word | Result == 0 | 9..17 | 9..27 | No |
---|
RDWORD reads a word (16 bits) from the 2 consecutive Hub memory locations addressed by Source or a pointer expression into Destination (the upper 16 bits are set to zeroes). Only the bottom 20 bits of the effective address are considered, the rest are ignored. Unaligned reads are possible, but carry a one-cycle penalty if the word crosses a long boundary (i.e. the bottom two bits of the effective address are both set). (See Hub Timing)
If the WC or WCZ effect is specified, the C flag is set to the MSB (bit 15) of the read value.
If the WZ or WCZ effect is specified, the Z flag is set (1) if the read value equals zero, or is cleared (0) if it is non-zero.
RDWORD cannot initiate block transfers.
RDBYTE D,{#}S/P {WC/WZ/WCZ} - Read byte from Hub
Encoding | Register Written | C Flag | Z Flag | Cycles (cogexec) | Cycles (hubexec) | IRQ Shield | EEEE 1010110 CZI DDDDDDDDD SSSSSSSSS | D | MSB of byte | Result == 0 | 9..16 | 9..26 | No |
---|
RDBYTE reads a byte (8 bits) from the Hub memory location addressed by Source or a pointer expression into Destination (the upper 24 bits are set to zeroes). Only the bottom 20 bits of the effective address are considered, the rest are ignored.
If the WC or WCZ effect is specified, the C flag is set to the MSB (bit 7) of the read value.
If the WZ or WCZ effect is specified, the Z flag is set (1) if the read value equals zero, or is cleared (0) if it is non-zero.
RDBYTE cannot be used for block transfers.
{ SETQ/SETQ2 {#}Q }
WRLONG {#}D,{#}S/P - Write long to Hub
Encoding | Register Written | C Flag | Z Flag | Cycles (cogexec) | Cycles (hubexec) | IRQ Shield | EEEE 1100011 0LI DDDDDDDDD SSSSSSSSS | none | --- | --- | 3..11 | 3..21 | No |
---|
WRLONG writes the 32 bits of Destination into the 4 consecutive Hub memory locations addressed by Source or a pointer expression. Only the bottom 20 bits of the effective address are considered, the rest are ignored. Unaligned writes are possible, but carry a one-cycle penalty. (See Hub Timing)
If prefixed with SETQ or SETQ2, a block transfer is initiated.
WRWORD {#}D,{#}S/P - Write word to Hub
Encoding | Register Written | C Flag | Z Flag | Cycles (cogexec) | Cycles (hubexec) | IRQ Shield | EEEE 1100010 1LI DDDDDDDDD SSSSSSSSS | none | --- | --- | 3..11 | 3..21 | No |
---|
WRWORD writes the bottom 16 bits of Destination into the 2 consecutive Hub memory locations addressed by Source or a pointer expression. Only the bottom 20 bits of the effective address are considered, the rest are ignored. Unaligned writes are possible, but carry a one-cycle penalty if the word crosses a long boundary (i.e. the bottom two bits of the effective address are both set). (See Hub Timing)
WRWORD cannot be used for block transfers.
WRBYTE {#}D,{#}S/P - Write byte to Hub
Encoding | Register Written | C Flag | Z Flag | Cycles (cogexec) | Cycles (hubexec) | IRQ Shield | EEEE 1100010 0LI DDDDDDDDD SSSSSSSSS | none | --- | --- | 3..10 | 3..20 | No |
---|
WRBYTE writes the bottom 8 bits of Destination into the Hub memory location addressed by Source or a pointer expression. Only the bottom 20 bits of the effective address are considered, the rest are ignored.
WRBYTE cannot be used for block transfers.
{ SETQ/SETQ2 {#}Q }
WMLONG D,{#}S/P - Write non-zero bytes in long to Hub
Encoding | Register Written | C Flag | Z Flag | Cycles (cogexec) | Cycles (hubexec) | IRQ Shield | EEEE 1010011 11I DDDDDDDDD SSSSSSSSS | none | --- | --- | 3..11 | 3..21 | No |
---|
WMLONG functions identically to WRLONG, except that if any of the 4 bytes to be written is zero, that byte is not written and the previous value remains in memory. This is useful for masked blitting operations.
If prefixed with SETQ or SETQ2, a block transfer is initiated.
Alias Instructions
PUSHA {#}D
Encoding | Register Written | C Flag | Z Flag | Cycles (cogexec) | Cycles (hubexec) | IRQ Shield | EEEE 1100011 0L1 DDDDDDDDD 101100001 | none | --- | --- | 3..11 | 3..21 | No |
---|
PUSHA is an alias for WRLONG {#}D,PTRA++.
PUSHB {#}D
Encoding | Register Written | C Flag | Z Flag | Cycles (cogexec) | Cycles (hubexec) | IRQ Shield | EEEE 1100011 0L1 DDDDDDDDD 111100001 | none | --- | --- | 3..11 | 3..21 | No |
---|
PUSHB is an alias for WRLONG {#}D,PTRB++.
POPA D {WC/WZ/WCZ}
Encoding | Register Written | C Flag | Z Flag | Cycles (cogexec) | Cycles (hubexec) | IRQ Shield | EEEE 1011000 CZ1 DDDDDDDDD 101011111 | D | MSB of long | Result == 0 | 9..17 | 9..27 | No |
---|
POPA is an alias for RDLONG D,--PTRA.
POPB D {WC/WZ/WCZ}
Encoding | Register Written | C Flag | Z Flag | Cycles (cogexec) | Cycles (hubexec) | IRQ Shield | EEEE 1011000 CZ1 DDDDDDDDD 111011111 | D | MSB of long | Result == 0 | 9..17 | 9..27 | No |
---|
POPB is an alias for RDLONG D,--PTRB.