forked from arti/vt1200
One PIXBLT B,XY per source row paints the whole screen: DYDX names `stretch` rows and SPTCH = 0 makes each of them read the same packed source row, so the vertical stretch costs no extra CPU work. vram_b.asm carries the primitive (PSIZE=1, CONVSP/CONVDP=0x14, PMASK=0, OFFSET=0x04000000, DPTCH=0x800, raster op 0) plus DINT/EINT thunks; vidstream.c masks interrupts for the burst (spec 8.9), refuses geometry the screen cannot hold, and counts an OS repaint through a sentinel word in the unused right edge of the last screen row (OS_TOUCH, 0x01810220). MAME mode draw injects a 128-row frame (stretch 8 = 1024 screen rows, ruling R3) and dumps the screen; vidstream_check.py compares all 1024 rows against the bytes actually delivered. RED: 0/1024 rows matched. GREEN: 1024/1024, RX_OK=1, OS_TOUCH=0. Fixes a latent harness bug found on the way: `bpclear <address>` takes a breakpoint INDEX, so the idle-loop breakpoint was never cleared; once a burst masked interrupts long enough, its stale action fired again and re-entered main (a second malloc, counters back to 0).
120 lines
4.6 KiB
NASM
120 lines
4.6 KiB
NASM
; vram_b.asm -- PIXBLT B,XY: a packed 1-bpp RAM row straight to the screen.
|
|
;
|
|
; Task 5's blit primitive. PIXBLT's B source form reads the source as packed
|
|
; 1-bit pixels from a LINEAR bit address and writes an XY destination, which is
|
|
; exactly the strip decoder's shape: a 1280-pixel row (160 bytes) in the slot,
|
|
; painted down `stretch` screen rows.
|
|
;
|
|
; The vertical stretch is one instruction, not a loop over screen rows: SPTCH
|
|
; = 0 makes every source row read the SAME source address, so a PIXBLT whose
|
|
; DYDX names `stretch` rows paints the one row `stretch` times.
|
|
;
|
|
; DESCRIPTION-register assignments for PIXBLT B,XY (TMS34010 User's Guide,
|
|
; instruction reference; vram.asm already uses the same values for L,XY):
|
|
; SADDR = B0 source bit address (1 bpp, packed)
|
|
; SPTCH = B1 source pitch in bits; 0 = do not advance the source
|
|
; DADDR = B2 destination XY: (y << 16) | x
|
|
; DPTCH = B3 destination pitch in bits (0x800 = 256-byte screen row)
|
|
; OFFSET = B4 VRAM base bit address
|
|
; DYDX = B7 dimensions in XY form: (rows << 16) | columns
|
|
;
|
|
; COLOR0 = B8 pixel value for a clear source bit (0 = black)
|
|
; COLOR1 = B9 pixel value for a set source bit (0xFFFF = white)
|
|
;
|
|
; B8/B9 are NOT I/O registers: COLOR0 and COLOR1 are implied B-register
|
|
; operands of every graphics instruction (vram.asm's FILL passes its pattern in
|
|
; B9 for the same reason). They are explicit here because a PIXBLT B expands
|
|
; a packed 1-bpp source into pixel values, so whatever the resident OS left in
|
|
; B9 becomes the colour of every set pixel -- measured: the first draw run
|
|
; painted every row it blitted black because nothing had set B9 (the padding
|
|
; past column 1280, which the blit does not write, kept the OS's old bytes).
|
|
;
|
|
; PSIZE (0C0000150h) 1 one bit per destination pixel
|
|
; CONVSP (0C0000130h) 14h 0x800-bit pitch code (1 << (~0x14 & 0x1F) = 2048)
|
|
; CONVDP (0C0000140h) 14h same, for the XY destination
|
|
; PMASK (0C0000160h) 0 every plane writable
|
|
; CONTROL (0C00000B0h) raster op 0 (replace), CD/RM/RR preserved
|
|
;
|
|
; Entry points. The TMS34010 C compiler passes arguments in its own frame-
|
|
; pointer scheme, and no hand-written assembly in this repository has ever
|
|
; DECODED that frame: the ROM thunks in entry.asm forward the caller's stack
|
|
; frame through `calla` without touching it, and the two array primitives in
|
|
; vram.asm take their inputs from published words in .bss with a no-argument
|
|
; entry (called by lance_cmd.c, measured on the unit). This primitive follows
|
|
; the vram.asm form, so the three interface values named in the plan live in
|
|
; blit_src / blit_daddr / blit_dydx (blit_sptch only exists for vram.asm and is
|
|
; ignored: this primitive always sets SPTCH = 0). The C side wraps them in
|
|
; blit_row() so the call reads as blit_row(src, daddr_xy, dydx).
|
|
;
|
|
; All inputs are reloaded on every call: PIXBLT leaves SADDR/DADDR advanced, so
|
|
; a caller that "saves" them saves a half-consumed rectangle.
|
|
;
|
|
; _vid_dint_ / _vid_eint_ -- interrupts off/on. The C compiler cannot emit
|
|
; DINT/EINT, and spec section 8.9 wants the OS masked for the whole burst so a
|
|
; resident repaint cannot tear the picture.
|
|
|
|
.ref _blit_src
|
|
.ref _blit_daddr
|
|
.ref _blit_dydx
|
|
.text
|
|
.globl _vram_blit_b_
|
|
_vram_blit_b_:
|
|
setf 32, 0, 1
|
|
move b0, -*sp, 1
|
|
move b1, -*sp, 1
|
|
move b2, -*sp, 1
|
|
move b3, -*sp, 1
|
|
move b4, -*sp, 1
|
|
move b7, -*sp, 1
|
|
move b8, -*sp, 1
|
|
move b9, -*sp, 1
|
|
|
|
move @_blit_src, b0, 1 ; SADDR: packed 1-bpp source row
|
|
clr b1 ; SPTCH = 0: every row is the same source row
|
|
move @_blit_daddr, b2, 1 ; DADDR (XY)
|
|
movi 800h, b3 ; DPTCH = 2048 bits = 256-byte row pitch
|
|
movi 04000000h, b4 ; OFFSET = VRAM base
|
|
move @_blit_dydx, b7, 1 ; DYDX (rows, columns)
|
|
clr b8 ; COLOR0 = 0 (black)
|
|
movi 0FFFFh, b9 ; COLOR1 = all planes set (white)
|
|
|
|
; --- pixel format ------------------------------------------------------
|
|
movi 1, a1
|
|
move a1, @0C0000150h, 0 ; PSIZE = 1
|
|
movi 14h, a1
|
|
move a1, @0C0000130h, 0 ; CONVSP = pitch code for 0x800 bits
|
|
move a1, @0C0000140h, 0 ; CONVDP
|
|
clr a1
|
|
move a1, @0C0000160h, 0 ; PMASK = 0 (all planes writable)
|
|
move a1, @0C0000170h, 0 ; upper half, for forward compatibility
|
|
|
|
; --- graphics operation: replace, no transparency, no window ----------
|
|
move @0C00000B0h, a1, 0 ; CONTROL
|
|
andi 0801Fh, a1 ; keep CD (15) and RM/RR (2-4) only
|
|
move a1, @0C00000B0h, 0
|
|
move @0C00000B0h, a1, 0 ; read back: I/O writes are pipelined
|
|
|
|
pixblt b, xy
|
|
|
|
move *sp+, b9, 1
|
|
move *sp+, b8, 1
|
|
move *sp+, b7, 1
|
|
move *sp+, b4, 1
|
|
move *sp+, b3, 1
|
|
move *sp+, b2, 1
|
|
move *sp+, b1, 1
|
|
move *sp+, b0, 1
|
|
rets
|
|
|
|
.globl _vid_dint_
|
|
_vid_dint_:
|
|
dint
|
|
rets
|
|
|
|
.globl _vid_eint_
|
|
_vid_eint_:
|
|
eint
|
|
rets
|
|
|
|
.end
|