User Tools

Site Tools


sd:isa

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
sd:isa [2026/09/08 03:51] – external edit 127.0.0.1sd:isa [2026/09/08 04:07] (current) – external edit 127.0.0.1
Line 180: Line 180:
 Instructions added to remove work from a specific hot path rather than to add expressiveness. Each one has a primary consumer noted below. Instructions added to remove work from a specific hot path rather than to add expressiveness. Each one has a primary consumer noted below.
  
-Canidates for inclusion: LEA, fused CMP-Bcc and CMP-Jcc, conditional move, LD_IDX16+Canidates for inclusion: LEA, fused CMP-Bcc and CMP-Jcc, conditional move, LD_IDX16, [[#ptrace|PTRACE]] (proposed, see below)
  
 | #   | hex  | Mnemonic | Example          | Description                                  | Consumer | Flags | | #   | hex  | Mnemonic | Example          | Description                                  | Consumer | Flags |
Line 629: Line 629:
 **Measured.** 7.2% off the cost of a turn in rogueima -- more than MAC, because **Measured.** 7.2% off the cost of a turn in rogueima -- more than MAC, because
 the branches it removes were unpredictable ones inside the hottest loop. the branches it removes were unpredictable ones inside the hottest loop.
 +
 +
 +<wrap #ptrace />
 +**''PTRACE'' -- PROPOSED, NOT IMPLEMENTED**\\
 +//No opcode assigned. This is a specification for review, not a description of
 +the machine.//
 +
 +Walk a line through a tile array, stopping at the first tile that blocks, and
 +optionally marking every tile visited on the way. A PPU instruction in the same
 +family as ''PLINE'', and taking its parameters in registers the same way.
 +
 +^ ^ ^
 +| **in** | ''ELM'' = tile array base |
 +| ::: | ''X'',''Y'' = start;  ''I'',''J'' = target |
 +| ::: | ''KL'',''KH'' = map width, height (for bounds) |
 +| ::: | ''BL'' = bytes per tile;  ''BH'' = offset of the flags byte within a tile |
 +| ::: | ''CL'' = block mask;  ''CH'' = set mask |
 +| **out** | ''X'',''Y'' = where it stopped |
 +| ::: | ''AL'' = tiles visited |
 +| ::: | ''Z'' set if it stopped on a blocker, clear if it reached the target |
 +
 +At every tile along the line it ORs ''CH'' into the flags byte; if
 +''flags & CL'' is non-zero it stops, having marked that tile. It also stops at
 +the edge of the array. A ''CH'' of zero traces without marking, which is what a
 +projectile or a "can this monster see me" test wants.
 +
 +<codify armasm>
 +    ; one line-of-sight ray, marking SEEN|VISIBLE and stopping at anything opaque
 +    LDELM [@level_tiles]
 +    LDB [@level_dim]        ; KL, KH = width, height
 +    MOV K, B
 +    LDBL #2                 ; two bytes per tile
 +    LDBH #1                 ; the flags are the second of them
 +    LDCL @TF_OPAQUE         ; what stops the ray
 +    LDCH $0C                ; TF_SEEN | TF_VISIBLE
 +    LDXL [@PX]
 +    LDYL [@PY]
 +    LDI [@target_x]
 +    LDJ [@target_y]
 +    PTRACE
 +</codify>
 +
 +**Why.** Rogueima's line of sight is 68 rays a turn, and the ray loop is about
 +45,000 of the 62,577 instructions a turn costs -- 48 ms at 1.3 MIPS. Each ray
 +is roughly 540 instructions of Bresenham stepping and per-tile testing. As one
 +instruction, a ray becomes "set ''I'',''J''; ''PTRACE''": three instructions
 +instead of 540, and a turn drops to roughly 15 ms.
 +
 +**Where else.** The masks are what make it general. Projectile and thrown-object
 +paths, wand and breath-weapon beams, monster targeting, swept collision in a
 +tile platformer, and post-pathfinding line smoothing ("can I walk straight from
 +here to there") are all this instruction with different masks and usually a
 +''CH'' of zero.
 +
 +The application that makes it a platform capability rather than one game's
 +helper is a **Wolfenstein-style raycaster**: one ray per screen column through a
 +tile map, 320 rays a frame at 60 Hz. In software that is several million
 +instructions a second, more than this machine has, so the genre is off the
 +table. As an instruction it is about 19,000 a second plus the column drawing.
 +
 +**A design fork worth settling first.** Two different things wear similar
 +clothes here:
 +
 +  * **Bresenham** visits the tiles a line passes through. Symmetric, integer,
 +    and what line of sight, projectiles, targeting and collision all want.
 +  * **DDA** steps to each grid //boundary// and carries the exact crossing
 +    distance. That is what a perspective raycaster needs -- Wolfenstein used it
 +    because Bresenham's nearest-tile approximation gives the wrong distance, and
 +    a wrong distance is a wrong wall height and a fisheye.
 +
 +''PTRACE'' as specified above is the Bresenham walk. A perspective raycaster
 +wants a sibling -- ''PCAST''? -- returning a fractional distance and which side
 +of the tile was struck, for texture mapping. Trying to make one instruction do
 +both would make both worse.
 +
 +The name deliberately says the job rather than the algorithm, so that the pair
 +reads ''PTRACE''/''PCAST'' rather than ''PBRES''/''PDDA''.
 +
 +**Open questions.**
 +  - Six registers in is a lot. Is a descriptor block at ''[FLX]'', the way
 +    ''LSTEPM'' does it, a better fit for the array parameters, which are
 +    level-scoped rather than per-call?
 +  - Should it also report the tile it stopped ON versus the last clear tile
 +    before it? Line of sight wants the blocker marked; a projectile wants the
 +    square in front of it.
 +  - Should a zero-length line (start == target) mark the start square?
 +
 +**Precedent.** No CPU precedent that I know of, but a strong coprocessor one:
 +this is what blitters did. The Amiga blitter (1985) had a hardware Bresenham
 +line mode, and the TMS34010 (1986) was a graphics processor with ''LINE'' as an
 +instruction. It belongs to that tradition, which is where the rest of the PPU
 +already lives.
  
sd/isa.1788839487.txt.gz · Last modified: by 127.0.0.1

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki