#!/bin/sh # retroDE_ps2 OSD path validation — Ch232 hardware bring-up helper. # # Writes a 9-character white-on-blue test message ("01234 ABC") into # the Ch227/Ch229/Ch231 OSD tile RAM at cells (0,0)..(8,0), then # asserts OSD_CTRL[0]=1 to enable the overlay. Use it to confirm the # full HPS-to-video OSD path is alive on the DE25-Nano. # # The chars 0-9 + space + A,B,C are the glyphs currently populated in # `osd_overlay_stub.font_rom`. Other ASCII codes will render as solid # background blocks (correct "missing glyph" fallback) — see the Ch231 # section of the bring-up runbook. # # Usage: # ./ps2_osd_test.sh # write message + enable overlay # ./ps2_osd_test.sh --off # disable overlay (OSD_CTRL[0]=0) # ./ps2_osd_test.sh --clear # zero the 9 cells + leave overlay enabled # ./ps2_osd_test.sh --status # dump OSD_CTRL / tile RAM cells for inspection # # Uses `busybox devmem` (matching ps2_status.sh) — sidesteps the # devmem2 0x?4-offset quirk and reads/writes a single 32-bit word per # call. set -u BASE="${PS2_BRIDGE_BASE:-0x40000000}" DEVMEM="${DEVMEM:-busybox devmem}" MODE="${1:-write}" # Bridge offsets. OFF_OSD_CTRL=0x100 OFF_TILE_BASE=0x1000 # Compute an absolute address for a relative byte offset. addr() { printf "0x%08x" $(( BASE + $1 )) } write32() { # $1 = relative offset, $2 = 32-bit value (hex) $DEVMEM "$(addr $1)" w "$2" } read32() { # $1 = relative offset; prints "0x%08x" $DEVMEM "$(addr $1)" w } # Cell encoder: 16-bit value = {bg[3:0], fg[3:0], char[7:0]}. # Default fg=15 (white), bg=1 (blue) for the test message. cell_val() { # $1 = char code (decimal), $2 = fg (0..15), $3 = bg (0..15) printf "0x%04x" $(( ($3 << 12) | ($2 << 8) | $1 )) } # Pack two 16-bit cells into a 32-bit word. # word = {high_cell, low_cell} = (high << 16) | low # Software writes WORDS to the bridge; each word stores cells # (col=N, row) in the low half and (col=N+1, row) in the high half # at byte offset (row * 128 + (N & ~1) * 2). pack_word() { # $1 = low 16-bit cell value, $2 = high 16-bit cell value printf "0x%08x" $(( ($2 << 16) | $1 )) } # Write a cell at (col, row). Performs a read-modify-write of the # underlying 32-bit word so the neighboring cell in the same word # is preserved. write_cell() { # $1 = col, $2 = row, $3 = 16-bit cell value local col=$1 row=$2 val=$3 local word_byte_off=$(( OFF_TILE_BASE + row * 128 + (col / 2) * 4 )) local current_word=$($DEVMEM "$(addr $word_byte_off)" w) # Strip the leading 0x for arithmetic. local cur=$(( current_word )) local new if [ $(( col % 2 )) -eq 0 ]; then # Low half — preserve high half. new=$(( (cur & 0xFFFF0000) | (val & 0xFFFF) )) else # High half — preserve low half. new=$(( (cur & 0x0000FFFF) | ((val & 0xFFFF) << 16) )) fi $DEVMEM "$(addr $word_byte_off)" w "$(printf '0x%08x' $new)" } # Char codes for our test message "01234 ABC". MSG_CHARS="48 49 50 51 52 32 65 66 67" # '0'..'4' ' ' 'A' 'B' 'C' FG=15 # white BG=1 # blue write_message() { local col=0 for code in $MSG_CHARS; do local val=$(cell_val "$code" $FG $BG) write_cell "$col" 0 "$val" col=$(( col + 1 )) done } clear_message() { local col=0 for code in $MSG_CHARS; do write_cell "$col" 0 0x0000 col=$(( col + 1 )) done } set_osd_enable() { # $1 = 0 or 1 write32 $OFF_OSD_CTRL "0x0000000$1" } dump_status() { printf "OSD_CTRL @ 0x%03x : %s\n" $OFF_OSD_CTRL "$(read32 $OFF_OSD_CTRL)" printf "Tile cells (col, row=0) words:\n" local off=0 while [ $off -lt 20 ]; do local byte_off=$(( OFF_TILE_BASE + off * 4 )) printf " word @ 0x%04x : %s (cells %d, %d)\n" \ "$byte_off" "$(read32 $byte_off)" $(( off * 2 )) $(( off * 2 + 1 )) off=$(( off + 1 )) done } case "$MODE" in --off) set_osd_enable 0 echo "OSD disabled." ;; --clear) clear_message set_osd_enable 1 echo "Cleared 9 cells, overlay still enabled." ;; --status) dump_status ;; *) write_message set_osd_enable 1 echo 'Wrote "01234 ABC" at cells (0..8, 0), white on blue.' echo "Overlay enabled (OSD_CTRL[0]=1)." echo "The text should appear in the top-left of the HDMI image," echo "overlaying the Ch171 quadrant test card." ;; esac