mirror of
https://git.k-space.ee/arti/vt1200.git
synced 2026-10-30 12:03:54 +02:00
dwt/loader: COFF loader places GSPLNK images and runs them via create_process
This commit is contained in:
1 parent
dcca6bee4d
commit
139d89a10c
42 files changed
+3822
No files matched your search
@@ -0,0 +1,3 @@
|
||||
# Local SDK extraction and private emulator state; never commit.
|
||||
work/
|
||||
run/
|
||||
@@ -0,0 +1,60 @@
|
||||
# dwt/loader — the COFF loader half of the app loader
|
||||
|
||||
Loads a GSPLNK-linked COFF image that is already in RAM into a **first-class
|
||||
process** on the VT1200 OS. The transport (TFTP) is separate; this half takes a
|
||||
buffer and length, picks the addresses from the COFF, and calls
|
||||
`create_process`.
|
||||
|
||||
Read `dwt/notes/LOADER.md` for the full report and
|
||||
`dwt/notes/LOADER_CROSS.md` for the transport interface.
|
||||
|
||||
## Files
|
||||
|
||||
| file | purpose |
|
||||
|---|---|
|
||||
| `loader.asm` | the loader; linked at bit `0x01880000`, raw `.bin` 1220 B |
|
||||
| `marker.asm` | acceptance app with `.text`/`.data`/`.bss` at three addresses |
|
||||
| `coff.py` | TI COFF reader/dumper (`summary`, `raw`, `manifest`) |
|
||||
| `build.sh` | GSPA/GSPLNK wrapper; keeps the linked COFF |
|
||||
| `reldemo.sh`, `rel_a.asm`, `rel_b.asm` | relocation and position-dependence demo |
|
||||
| `loader.lua` | debugger-assisted harness (no network, no rdebug) |
|
||||
| `probe_os.lua` | heap-list and register-write probe used to design the harness |
|
||||
| `build/` | linked loader/app COFFs, raw `.bin`s, maps, listings |
|
||||
| `evidence/` | run logs, COFF dumps, the xhello window frame |
|
||||
|
||||
`work/` (the DOS tools extracted from the SDK floppy) and `run/` (private
|
||||
NVRAM/cfg) are local scratch and ignored.
|
||||
|
||||
## Build
|
||||
|
||||
```sh
|
||||
./dwt/loader/build.sh dwt/loader/loader.asm 01880000
|
||||
./dwt/loader/build.sh dwt/loader/marker.asm 018C0000 018D0000 018D8000
|
||||
./dwt/loader/build.sh dwt/gui/xhello.asm 01840000
|
||||
./dwt/loader/reldemo.sh
|
||||
```
|
||||
|
||||
`build.sh` takes `SOURCE.asm [TEXT_ORIGIN [DATA_ORIGIN [BSS_ORIGIN]]]`
|
||||
(origins are **bit** addresses) and writes `build/<name>.coff`, `.bin`, `.map`,
|
||||
`.lst`, `.obj`.
|
||||
|
||||
## Run (debugger-assisted, no network)
|
||||
|
||||
```sh
|
||||
VT1200_SKIP_LEVEL1=1 LOADER_AT=2500 LOADER_END=2620 \
|
||||
LOADER_COFF=dwt/loader/build/marker.coff LOADER_OUT=$PWD/dwt/loader/evidence \
|
||||
/home/arti/code/k-space/mame0289/vt1200 vt1200 \
|
||||
-rompath harness/mame/roms -video none -sound none -nothrottle -skip_gameinfo \
|
||||
-nvram_directory $PWD/dwt/loader/run/nvram \
|
||||
-cfg_directory $PWD/dwt/loader/run/cfg \
|
||||
-debug -debugger none \
|
||||
-autoboot_script dwt/loader/loader.lua -autoboot_delay 0
|
||||
```
|
||||
|
||||
The script pokes the loader at `0x01880000` and the COFF at `LOADER_BUF`
|
||||
(default `0x01900000`), writes the descriptor, and sets `PC`. It never uses the
|
||||
network, the rdebug service or a firmware transport.
|
||||
|
||||
Knobs: `LOADER_MODE=1` (callable/return instead of debug-resume),
|
||||
`LOADER_A8_DESC=1` (descriptor in `A8`), `LOADER_SNAP=1` (PNG at `LOADER_END`),
|
||||
`LOADER_VERBOSE=1`, `LOADER_TRACE=1`.
|
||||
Executable
+105
@@ -0,0 +1,105 @@
|
||||
#!/bin/sh
|
||||
# Build a VT1200 payload/app with the 1987 TI TMS34010 SDK (GSPA/GSPLNK under
|
||||
# DOSBox), keeping the linked COFF so dwt/loader/coff.py can inspect it.
|
||||
#
|
||||
# dwt/loader/build.sh SOURCE.asm [TEXT_ORIGIN [DATA_ORIGIN [BSS_ORIGIN]]]
|
||||
#
|
||||
# Origins are BIT addresses (the TMS34010 and GSPLNK's SECTIONS origins are
|
||||
# bit addresses). With only TEXT_ORIGIN the linker command binds .text alone,
|
||||
# exactly like dwt/gui/build.sh. With DATA_ORIGIN/BSS_ORIGIN it binds all
|
||||
# three sections, which is what the marker app needs.
|
||||
#
|
||||
# Outputs, all under dwt/loader/build/:
|
||||
# <name>.bin the linked .text bytes (convenience; not a COFF)
|
||||
# <name>.coff the GSPLNK output, byte-for-byte (the loader's real input)
|
||||
# <name>.map the link map
|
||||
# <name>.lst the assembler listing (addresses in bits)
|
||||
#
|
||||
# ENTRY_SYM=<symbol> adds `-e <symbol>`; default is `_start` if the symbol
|
||||
# exists, otherwise no -e (GSPLNK then writes entry = 0).
|
||||
set -eu
|
||||
|
||||
ROOT=$(cd "$(dirname "$0")/../.." && pwd)
|
||||
DIR=$(cd "$(dirname "$0")" && pwd)
|
||||
SRC=${1:?usage: build.sh SOURCE.asm [TEXT_ORIGIN [DATA_ORIGIN [BSS_ORIGIN]]]}
|
||||
TEXT=${2:-01800000}
|
||||
DATA=${3:-}
|
||||
BSS=${4:-}
|
||||
NAME=$(basename "$SRC" .asm)
|
||||
BASE=$(printf '%s' "$NAME" | tr 'a-z' 'A-Z')
|
||||
WORK="$DIR/work"
|
||||
OUT="$DIR/build"
|
||||
IMG="$ROOT/tools/tms34010-sdk/1987-05 TMS34010 SDK/1987-11-06 TMS34010 Simulator-C Tools-ASM Tools.img"
|
||||
DOSBOX_CONF="$ROOT/harness/sdk-scratch/dosbox-bench.conf"
|
||||
|
||||
mkdir -p "$WORK" "$OUT"
|
||||
|
||||
if [ ! -x "$WORK/GSPA.EXE" ]; then
|
||||
mcopy -s -n -i "$IMG" "::/A2/*" "$WORK/"
|
||||
mcopy -s -n -i "$IMG" "::/C2/*" "$WORK/"
|
||||
fi
|
||||
|
||||
cp "$SRC" "$WORK/$BASE.ASM"
|
||||
|
||||
# TI hex constants must begin with a decimal digit.
|
||||
tihex() {
|
||||
case "$1" in
|
||||
[0-9]*) printf '%s' "$1" ;;
|
||||
*) printf '0%s' "$1" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
TEXT=$(tihex "$TEXT")
|
||||
ENTRY=${ENTRY_SYM:-_start}
|
||||
|
||||
{
|
||||
printf '%s\n' '-a'
|
||||
printf '%s\n' '-o '"$BASE"'.out'
|
||||
printf '%s\n' '-m '"$BASE"'.map'
|
||||
[ -n "${ENTRY:-}" ] && printf '%s\n' '-e '"$ENTRY"
|
||||
printf '%s\n' "$BASE.obj"
|
||||
printf '%s\n' 'SECTIONS'
|
||||
printf '%s\n' '{'
|
||||
printf '%s\n' " .text ${TEXT}h: {}"
|
||||
if [ -n "$DATA" ]; then
|
||||
printf '%s\n' " .data $(tihex "$DATA")h: {}"
|
||||
fi
|
||||
if [ -n "$BSS" ]; then
|
||||
printf '%s\n' " .bss $(tihex "$BSS")h: {}"
|
||||
fi
|
||||
printf '%s\n' '}'
|
||||
} > "$WORK/$BASE.CMD"
|
||||
sed -i 's/$/\r/' "$WORK/$BASE.CMD"
|
||||
|
||||
rm -f "$WORK/$BASE.OBJ" "$WORK/$BASE.OUT" "$WORK/$BASE.LST" \
|
||||
"$WORK/$BASE.MAP" "$WORK/$BASE.HI" "$WORK/$BASE.LO"
|
||||
|
||||
SDL_VIDEODRIVER=dummy SDL_AUDIODRIVER=dummy \
|
||||
timeout 180 dosbox -conf "$DOSBOX_CONF" -noprimaryconf -nolocalconf \
|
||||
-c "mount c $WORK" -c "c:" \
|
||||
-c "gspa $BASE $BASE.obj $BASE.lst -l" \
|
||||
-c "gsplnk $BASE.cmd" \
|
||||
-c "exit" -exit >/dev/null 2>&1
|
||||
|
||||
if [ ! -f "$WORK/$BASE.OUT" ]; then
|
||||
echo "build.sh: GSPLNK produced no $BASE.OUT" >&2
|
||||
sed 's/\r$//' "$WORK/$BASE.MAP" 2>/dev/null | tail -20 >&2 || true
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -f "$WORK/$BASE.OBJ" ]; then
|
||||
echo "build.sh: GSPA produced no $BASE.OBJ" >&2
|
||||
grep -n '\*\*\*\*\*' "$WORK/$BASE.LST" >&2 || true
|
||||
exit 1
|
||||
fi
|
||||
if grep -q '\*\*\*\*\*' "$WORK/$BASE.LST"; then
|
||||
echo "build.sh: assembler diagnostics:" >&2
|
||||
grep -n '\*\*\*\*\*' "$WORK/$BASE.LST" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cp "$WORK/$BASE.OUT" "$OUT/$NAME.coff"
|
||||
cp "$WORK/$BASE.OBJ" "$OUT/$NAME.obj"
|
||||
sed 's/\r$//' "$WORK/$BASE.MAP" > "$OUT/$NAME.map"
|
||||
cp "$WORK/$BASE.LST" "$OUT/$NAME.lst"
|
||||
python3 "$ROOT/harness/hello-world/cofextract.py" "$WORK/$BASE.OUT" "$OUT/$NAME.bin"
|
||||
echo "build.sh: $OUT/$NAME.coff ($(wc -c < "$OUT/$NAME.coff") bytes); .bin $(wc -c < "$OUT/$NAME.bin") bytes at bit $TEXT"
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,746 @@
|
||||
GSP COFF Assembler, Version 2.00, 87.300 Sun Oct 18 15:19:03 2026
|
||||
(c) Copyright 1985, 1987, Texas Instruments Inc.
|
||||
|
||||
PAGE 1
|
||||
|
||||
0001 ; loader.asm -- COFF loader for the VT1200 / TMS34010.
|
||||
0002 ;
|
||||
0003 ; Input: a TI GSP COFF image (GSPLNK `-a` output) alrea
|
||||
0004 ; 16-byte descriptor (offsets in BITS, since all pointe
|
||||
0005 ; addresses; the byte offsets are 0, 2, 4, 8 and 12):
|
||||
0006 ;
|
||||
0007 ; DESC + 0x00 bits u16 0x4C44 "LD" ) magic; both
|
||||
0008 ; DESC + 0x10 bits u16 0x5231 "R1" )
|
||||
0009 ; DESC + 0x20 bits u32 buf bit address of
|
||||
0010 ; DESC + 0x40 bits u32 len length in byte
|
||||
0011 ; DESC + 0x60 bits u32 mode 1 = return to
|
||||
0012 ; 0 = debug resu
|
||||
0013 ;
|
||||
0014 ; The descriptor pointer is A8. If A8 is zero, or does
|
||||
0015 ; descriptor, the fixed descriptor at 0x01882C00 is use
|
||||
0016 ; receives a COFF over the network only has to write {b
|
||||
0017 ; call the loader entry; it does not choose a load addr
|
||||
0018 ; the addresses from the COFF section headers.
|
||||
0019 ;
|
||||
0020 ; Result block at 0x01882D00 (32-bit cells, bit address
|
||||
0021 ;
|
||||
0022 ; +0x000 status 0 ok, nonzero = error (see the l
|
||||
0023 ; +0x020 entry bit address passed to create_pro
|
||||
0024 ; +0x040 text addr .text paddr from the COFF (bits)
|
||||
0025 ; +0x060 text size .text size (bits)
|
||||
0026 ; +0x080 data addr .data paddr
|
||||
0027 ; +0x0A0 data size .data size (bits)
|
||||
0028 ; +0x0C0 bss addr .bss paddr
|
||||
0029 ; +0x0E0 bss size .bss size (bits)
|
||||
0030 ; +0x100 relocs relocation entries seen in the o
|
||||
0031 ; +0x120 pcb create_process() return value (0
|
||||
0032 ; +0x140 nscns section count from the file head
|
||||
0033 ; +0x160 coflen length from the descriptor (byte
|
||||
0034 ; +0x180 version loader base address, 0x01880000
|
||||
0035 ;
|
||||
0036 ; The image is POSITION-DEPENDENT: GSPLNK resolves ever
|
||||
0037 ; nreloc = 0, so each section is copied to the bit addr
|
||||
0038 ; no relocation is applied. A COFF that still carries
|
||||
0039 ; refused (status 7) rather than guessed at.
|
||||
0040 ;
|
||||
0041 ; Safety checks before any copy:
|
||||
0042 ; * size is a whole number of 16-bit words;
|
||||
0043 ; * the section bytes lie inside the descriptor's (bu
|
||||
0044 ; * paddr..paddr+size is inside main RAM (bits 0x100.
|
||||
0045 ; * it does not overlap the loader page [01880000,018
|
||||
0046 ; buffer;
|
||||
0047 ; * it lies inside one block of the firmware's global
|
||||
0048 ; (head at bit 0x1E8AC0, block header {u32 size_bit
|
||||
0049 ; user data at block+0x40). This is a check, not a
|
||||
0050 ; loader cannot make malloc hand out a chosen addre
|
||||
0051 ;
|
||||
0052 ; Delivered debugger-assisted for now: poke the raw .bi
|
||||
0053 ; the COFF at buf, write the descriptor, then set PC =
|
||||
0054 ; fine). mode = 0 resumes at LD_ORIG_PC (the harness s
|
||||
0055 ; PC); mode = 1 returns to the caller and passes the st
|
||||
0056 ;
|
||||
GSP COFF Assembler, Version 2.00, 87.300 Sun Oct 18 15:19:03 2026
|
||||
(c) Copyright 1985, 1987, Texas Instruments Inc.
|
||||
|
||||
PAGE 2
|
||||
|
||||
0057 ; Linked at bit 0x01880000; position-dependent itself.
|
||||
0058
|
||||
0059 .def _start
|
||||
0060
|
||||
0061 01880000 LOADER_BASE equ 01880000h
|
||||
0062 01882800 LD_SCRATCH equ 01882800h
|
||||
0063 01882C00 DESC_ADDR equ 01882C00h
|
||||
0064 01882D00 RESULT_BASE equ 01882D00h
|
||||
0065 01882B00 ARG_AREA equ 01882B00h
|
||||
0066 01883100 RETURN_STUB equ 01883100h
|
||||
0067
|
||||
0068 01882800 LD_SP_AFTER equ LD_SCRATCH+000h
|
||||
0069 01882820 LD_A14 equ LD_SCRATCH+020h
|
||||
0070 01882840 LD_ENTRY equ LD_SCRATCH+040h
|
||||
0071 01882860 LD_BUF equ LD_SCRATCH+060h
|
||||
0072 01882880 LD_LEN equ LD_SCRATCH+080h
|
||||
0073 018828A0 LD_MODE equ LD_SCRATCH+0A0h
|
||||
0074 018828C0 LD_NSCNS equ LD_SCRATCH+0C0h
|
||||
0075 018828E0 LD_RELOCS equ LD_SCRATCH+0E0h
|
||||
0076 01882900 LD_SEC_PADDR equ LD_SCRATCH+100h
|
||||
0077 01882920 LD_SEC_SIZE equ LD_SCRATCH+120h
|
||||
0078 01882940 LD_SEC_SCNPTR equ LD_SCRATCH+140h
|
||||
0079 01882960 LD_TEXT_ADDR equ LD_SCRATCH+160h
|
||||
0080 01882980 LD_TEXT_SIZE equ LD_SCRATCH+180h
|
||||
0081 018829A0 LD_DATA_ADDR equ LD_SCRATCH+1A0h
|
||||
0082 018829C0 LD_DATA_SIZE equ LD_SCRATCH+1C0h
|
||||
0083 018829E0 LD_BSS_ADDR equ LD_SCRATCH+1E0h
|
||||
0084 01882A00 LD_BSS_SIZE equ LD_SCRATCH+200h
|
||||
0085 01882A20 LD_ORIG_PC equ LD_SCRATCH+220h
|
||||
0086
|
||||
0087 01882D00 RESULT_STATUS equ RESULT_BASE+000h
|
||||
0088 01882D20 RESULT_ENTRY equ RESULT_BASE+020h
|
||||
0089 01882D40 RESULT_TEXT_A equ RESULT_BASE+040h
|
||||
0090 01882D60 RESULT_TEXT_S equ RESULT_BASE+060h
|
||||
0091 01882D80 RESULT_DATA_A equ RESULT_BASE+080h
|
||||
0092 01882DA0 RESULT_DATA_S equ RESULT_BASE+0A0h
|
||||
0093 01882DC0 RESULT_BSS_A equ RESULT_BASE+0C0h
|
||||
0094 01882DE0 RESULT_BSS_S equ RESULT_BASE+0E0h
|
||||
0095 01882E00 RESULT_RELOCS equ RESULT_BASE+100h
|
||||
0096 01882E20 RESULT_PCB equ RESULT_BASE+120h
|
||||
0097 01882E40 RESULT_NSCNS equ RESULT_BASE+140h
|
||||
0098 01882E60 RESULT_LEN equ RESULT_BASE+160h
|
||||
0099 01882E80 RESULT_VERSION equ RESULT_BASE+180h
|
||||
0100
|
||||
0101 00000000 .text
|
||||
0102 00000000 _start:
|
||||
0103 00000000 098F mmtm sp, a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13
|
||||
00000010 FFFC
|
||||
0104 00000020 078F move sp, @LD_SP_AFTER, 1
|
||||
00000030 01882800
|
||||
0105 00000050 078E move a14, @LD_A14, 1
|
||||
00000060 01882820
|
||||
0106 00000080 0550 setf 16, 0, 0
|
||||
0107 00000090 0740 setf 32, 0, 1
|
||||
0108
|
||||
0109 ; ---- descriptor ------------------------------------
|
||||
GSP COFF Assembler, Version 2.00, 87.300 Sun Oct 18 15:19:03 2026
|
||||
(c) Copyright 1985, 1987, Texas Instruments Inc.
|
||||
|
||||
PAGE 3
|
||||
|
||||
0110 ; A8 points at it only if both magic words match; else
|
||||
0111 000000A0 4D06 move a8, a6
|
||||
0112 000000B0 4D08 move a8, a8
|
||||
0113 000000C0 CA09 jreq ld_fixed_desc
|
||||
0114 000000D0 84C0 move *a6, a0, 0
|
||||
0115 000000E0 0B40 cmpi 4C44h, a0
|
||||
000000F0 B3BB
|
||||
0116 00000100 CB05 jrne ld_fixed_desc
|
||||
0117 00000110 B4C0 move *a6(10h), a0, 0
|
||||
00000120 0010
|
||||
0118 00000130 0B40 cmpi 5231h, a0
|
||||
00000140 ADCE
|
||||
0119 00000150 CA0E jreq ld_have_desc
|
||||
0120 00000160 ld_fixed_desc:
|
||||
0121 00000160 09E6 movi DESC_ADDR, a6, L
|
||||
00000170 01882C00
|
||||
0122 00000190 84C0 move *a6, a0, 0
|
||||
0123 000001A0 0B40 cmpi 4C44h, a0
|
||||
000001B0 B3BB
|
||||
0124 000001C0 CB00 jrne ld_bad_desc
|
||||
000001D0 01D5
|
||||
0125 000001E0 B4C0 move *a6(10h), a0, 0
|
||||
000001F0 0010
|
||||
0126 00000200 0B40 cmpi 5231h, a0
|
||||
00000210 ADCE
|
||||
0127 00000220 CB00 jrne ld_bad_desc
|
||||
00000230 01CF
|
||||
0128 00000240 ld_have_desc:
|
||||
0129 00000240 B6C7 move *a6(20h), a7, 1 ; buf
|
||||
00000250 0020
|
||||
0130 00000260 B6C8 move *a6(40h), a8, 1 ; len
|
||||
00000270 0040
|
||||
0131 00000280 B6CC move *a6(60h), a12, 1 ; mode
|
||||
00000290 0060
|
||||
0132 000002A0 0787 move a7, @LD_BUF, 1
|
||||
000002B0 01882860
|
||||
0133 000002D0 0788 move a8, @LD_LEN, 1
|
||||
000002E0 01882880
|
||||
0134 00000300 078C move a12, @LD_MODE, 1
|
||||
00000310 018828A0
|
||||
0135 00000330 078C move a12, @RESULT_VERSION, 1 ; harmless; overwritten b
|
||||
00000340 01882E80
|
||||
0136 00000360 09E0 movi LOADER_BASE, a0, L
|
||||
00000370 01880000
|
||||
0137 00000390 0780 move a0, @RESULT_VERSION, 1
|
||||
000003A0 01882E80
|
||||
0138
|
||||
0139 ; clear the counters we report; status stays FF until
|
||||
0140 000003C0 09E0 movi 0FFFFFFFFh, a0, L
|
||||
000003D0 FFFFFFFF
|
||||
0141 000003F0 0780 move a0, @RESULT_STATUS, 1
|
||||
00000400 01882D00
|
||||
0142 00000420 4400 sub a0, a0
|
||||
0143 00000430 0780 move a0, @LD_RELOCS, 1
|
||||
00000440 018828E0
|
||||
0144 00000460 0780 move a0, @LD_TEXT_ADDR, 1
|
||||
GSP COFF Assembler, Version 2.00, 87.300 Sun Oct 18 15:19:03 2026
|
||||
(c) Copyright 1985, 1987, Texas Instruments Inc.
|
||||
|
||||
PAGE 4
|
||||
|
||||
00000470 01882960
|
||||
0145 00000490 0780 move a0, @LD_TEXT_SIZE, 1
|
||||
000004A0 01882980
|
||||
0146 000004C0 0780 move a0, @LD_DATA_ADDR, 1
|
||||
000004D0 018829A0
|
||||
0147 000004F0 0780 move a0, @LD_DATA_SIZE, 1
|
||||
00000500 018829C0
|
||||
0148 00000520 0780 move a0, @LD_BSS_ADDR, 1
|
||||
00000530 018829E0
|
||||
0149 00000550 0780 move a0, @LD_BSS_SIZE, 1
|
||||
00000560 01882A00
|
||||
0150 00000580 0780 move a0, @RESULT_ENTRY, 1
|
||||
00000590 01882D20
|
||||
0151 000005B0 0780 move a0, @RESULT_TEXT_A, 1
|
||||
000005C0 01882D40
|
||||
0152 000005E0 0780 move a0, @RESULT_TEXT_S, 1
|
||||
000005F0 01882D60
|
||||
0153 00000610 0780 move a0, @RESULT_DATA_A, 1
|
||||
00000620 01882D80
|
||||
0154 00000640 0780 move a0, @RESULT_DATA_S, 1
|
||||
00000650 01882DA0
|
||||
0155 00000670 0780 move a0, @RESULT_BSS_A, 1
|
||||
00000680 01882DC0
|
||||
0156 000006A0 0780 move a0, @RESULT_BSS_S, 1
|
||||
000006B0 01882DE0
|
||||
0157 000006D0 0780 move a0, @RESULT_RELOCS, 1
|
||||
000006E0 01882E00
|
||||
0158 00000700 0780 move a0, @RESULT_PCB, 1
|
||||
00000710 01882E20
|
||||
0159
|
||||
0160 ; ---- file header -----------------------------------
|
||||
0161 00000730 09E0 movi 20, a0, L
|
||||
00000740 00000014
|
||||
0162 00000760 4808 cmp a0, a8
|
||||
0163 00000770 C800 jrlo ld_err_short
|
||||
00000780 017E
|
||||
0164 00000790 84E0 move *a7, a0, 0 ; magic
|
||||
0165 000007A0 0B40 cmpi 0090h, a0
|
||||
000007B0 FF6F
|
||||
0166 000007C0 CB00 jrne ld_err_magic
|
||||
000007D0 017D
|
||||
0167 000007E0 B4E9 move *a7(10h), a9, 0 ; nscns (+2 bytes)
|
||||
000007F0 0010
|
||||
0168 00000800 0789 move a9, @LD_NSCNS, 1
|
||||
00000810 018828C0
|
||||
0169 00000830 B4E0 move *a7(10h), a0, 0
|
||||
00000840 0010
|
||||
0170 00000850 0789 move a9, @RESULT_NSCNS, 1
|
||||
00000860 01882E40
|
||||
0171 00000880 0788 move a8, @RESULT_LEN, 1
|
||||
00000890 01882E60
|
||||
0172
|
||||
0173 ; section headers = buf + (20 + opthdr + nscns*40) byt
|
||||
0174 000008B0 B4E1 move *a7(80h), a1, 0 ; opthdr (+16 bytes)
|
||||
000008C0 0080
|
||||
0175 000008D0 4D22 move a9, a2
|
||||
GSP COFF Assembler, Version 2.00, 87.300 Sun Oct 18 15:19:03 2026
|
||||
(c) Copyright 1985, 1987, Texas Instruments Inc.
|
||||
|
||||
PAGE 5
|
||||
|
||||
0176 000008E0 24A2 sll 5, a2 ; nscns*32
|
||||
0177 000008F0 4D23 move a9, a3
|
||||
0178 00000900 2463 sll 3, a3 ; nscns*8
|
||||
0179 00000910 4062 add a3, a2 ; nscns*40
|
||||
0180 00000920 4022 add a1, a2
|
||||
0181 00000930 0B02 addi 20, a2 ; byte offset of section headers end
|
||||
00000940 0014
|
||||
0182 00000950 4848 cmp a2, a8 ; a8 - a2
|
||||
0183 00000960 C800 jrlo ld_err_short
|
||||
00000970 015F
|
||||
0184
|
||||
0185 ; secbase = buf + (20 + opthdr)*8 bits
|
||||
0186 00000980 2461 sll 3, a1 ; opthdr in bits
|
||||
0187 00000990 0B01 addi 160, a1 ; 20 bytes in bits
|
||||
000009A0 00A0
|
||||
0188 000009B0 40E1 add a7, a1
|
||||
0189 000009C0 4C2A move a1, a10
|
||||
0190
|
||||
0191 ; ---- entry point -----------------------------------
|
||||
0192 ; optional header at buf+20 bytes (0x0A0 bits): magic
|
||||
0193 ; +16 bytes (0x080 bits further); textstart at +20 byt
|
||||
0194 000009D0 B4E0 move *a7(0A0h), a0, 0
|
||||
000009E0 00A0
|
||||
0195 000009F0 0B40 cmpi 0108h, a0
|
||||
00000A00 FEF7
|
||||
0196 00000A10 CB07 jrne ld_no_opt
|
||||
0197 00000A20 B6E5 move *a7(120h), a5, 1 ; entry (bits)
|
||||
00000A30 0120
|
||||
0198 00000A40 4CA5 move a5, a5
|
||||
0199 00000A50 CB04 jrne ld_entry_set
|
||||
0200 00000A60 B6E5 move *a7(140h), a5, 1 ; textstart (bits)
|
||||
00000A70 0140
|
||||
0201 00000A80 C001 jruc ld_entry_set
|
||||
0202 00000A90 ld_no_opt:
|
||||
0203 00000A90 44A5 sub a5, a5
|
||||
0204
|
||||
0205 00000AA0 ld_entry_set:
|
||||
0206 00000AA0 0785 move a5, @LD_ENTRY, 1
|
||||
00000AB0 01882840
|
||||
0207 00000AD0 0785 move a5, @RESULT_ENTRY, 1
|
||||
00000AE0 01882D20
|
||||
0208
|
||||
0209 ; ---- section loop ----------------------------------
|
||||
0210 00000B00 456B sub a11, a11 ; section index
|
||||
0211 00000B10 ld_sec_loop:
|
||||
0212 00000B10 492B cmp a9, a11 ; a11 - a9
|
||||
0213 00000B20 C900 jrhs ld_sec_done
|
||||
00000B30 00DC
|
||||
0214 00000B40 B740 move *a10(40h), a0, 1 ; paddr (bits) +8 bytes
|
||||
00000B50 0040
|
||||
0215 00000B60 B741 move *a10(80h), a1, 1 ; size (bits) +16
|
||||
00000B70 0080
|
||||
0216 00000B80 B742 move *a10(0A0h), a2, 1 ; scnptr (bytes) +20
|
||||
00000B90 00A0
|
||||
0217 00000BA0 B543 move *a10(100h), a3, 0 ; nreloc +32
|
||||
00000BB0 0100
|
||||
GSP COFF Assembler, Version 2.00, 87.300 Sun Oct 18 15:19:03 2026
|
||||
(c) Copyright 1985, 1987, Texas Instruments Inc.
|
||||
|
||||
PAGE 6
|
||||
|
||||
0218 00000BC0 B744 move *a10(120h), a4, 1 ; flags +36
|
||||
00000BD0 0120
|
||||
0219 00000BE0 0780 move a0, @LD_SEC_PADDR, 1
|
||||
00000BF0 01882900
|
||||
0220 00000C10 0781 move a1, @LD_SEC_SIZE, 1
|
||||
00000C20 01882920
|
||||
0221 00000C40 0782 move a2, @LD_SEC_SCNPTR, 1
|
||||
00000C50 01882940
|
||||
0222
|
||||
0223 ; record the first text/data/bss section for the resul
|
||||
0224 00000C70 4C85 move a4, a5
|
||||
0225 00000C80 0B85 andi 20h, a5
|
||||
00000C90 FFFFFFDF
|
||||
0226 00000CB0 4CA5 move a5, a5
|
||||
0227 00000CC0 CA0B jreq ld_not_text
|
||||
0228 00000CD0 07A5 move @LD_TEXT_ADDR, a5, 1
|
||||
00000CE0 01882960
|
||||
0229 00000D00 4CA5 move a5, a5
|
||||
0230 00000D10 CB06 jrne ld_not_text
|
||||
0231 00000D20 0780 move a0, @LD_TEXT_ADDR, 1
|
||||
00000D30 01882960
|
||||
0232 00000D50 0781 move a1, @LD_TEXT_SIZE, 1
|
||||
00000D60 01882980
|
||||
0233 00000D80 ld_not_text:
|
||||
0234 00000D80 4C85 move a4, a5
|
||||
0235 00000D90 0B85 andi 40h, a5
|
||||
00000DA0 FFFFFFBF
|
||||
0236 00000DC0 4CA5 move a5, a5
|
||||
0237 00000DD0 CA0B jreq ld_not_data
|
||||
0238 00000DE0 07A5 move @LD_DATA_ADDR, a5, 1
|
||||
00000DF0 018829A0
|
||||
0239 00000E10 4CA5 move a5, a5
|
||||
0240 00000E20 CB06 jrne ld_not_data
|
||||
0241 00000E30 0780 move a0, @LD_DATA_ADDR, 1
|
||||
00000E40 018829A0
|
||||
0242 00000E60 0781 move a1, @LD_DATA_SIZE, 1
|
||||
00000E70 018829C0
|
||||
0243 00000E90 ld_not_data:
|
||||
0244 00000E90 4C85 move a4, a5
|
||||
0245 00000EA0 0B85 andi 80h, a5
|
||||
00000EB0 FFFFFF7F
|
||||
0246 00000ED0 4CA5 move a5, a5
|
||||
0247 00000EE0 CA0B jreq ld_not_bss
|
||||
0248 00000EF0 07A5 move @LD_BSS_ADDR, a5, 1
|
||||
00000F00 018829E0
|
||||
0249 00000F20 4CA5 move a5, a5
|
||||
0250 00000F30 CB06 jrne ld_not_bss
|
||||
0251 00000F40 0780 move a0, @LD_BSS_ADDR, 1
|
||||
00000F50 018829E0
|
||||
0252 00000F70 0781 move a1, @LD_BSS_SIZE, 1
|
||||
00000F80 01882A00
|
||||
0253 00000FA0 ld_not_bss:
|
||||
0254
|
||||
0255 ; relocation records: count, then refuse (the linked i
|
||||
0256 00000FA0 4C63 move a3, a3
|
||||
0257 00000FB0 CA09 jreq ld_no_reloc
|
||||
GSP COFF Assembler, Version 2.00, 87.300 Sun Oct 18 15:19:03 2026
|
||||
(c) Copyright 1985, 1987, Texas Instruments Inc.
|
||||
|
||||
PAGE 7
|
||||
|
||||
0258 00000FC0 07A5 move @LD_RELOCS, a5, 1
|
||||
00000FD0 018828E0
|
||||
0259 00000FF0 4065 add a3, a5
|
||||
0260 00001000 0785 move a5, @LD_RELOCS, 1
|
||||
00001010 018828E0
|
||||
0261 00001030 C000 jruc ld_err_reloc
|
||||
00001040 0106
|
||||
0262 00001050 ld_no_reloc:
|
||||
0263
|
||||
0264 ; size 0: nothing to place; size must be whole 16-bit
|
||||
0265 00001050 4C21 move a1, a1
|
||||
0266 00001060 CA00 jreq ld_sec_next
|
||||
00001070 0082
|
||||
0267 00001080 4C25 move a1, a5
|
||||
0268 00001090 0B85 andi 0Fh, a5
|
||||
000010A0 FFFFFFF0
|
||||
0269 000010C0 4CA5 move a5, a5
|
||||
0270 000010D0 CB00 jrne ld_err_size
|
||||
000010E0 00F0
|
||||
0271
|
||||
0272 ; source range: scnptr + size/8 <= len (when there are
|
||||
0273 000010F0 4C42 move a2, a2
|
||||
0274 00001100 CA06 jreq ld_no_src
|
||||
0275 00001110 4C25 move a1, a5
|
||||
0276 00001120 2FA5 srl 3, a5 ; size in bytes
|
||||
0277 00001130 40A2 add a5, a2 ; scnptr + nbytes
|
||||
0278 00001140 4902 cmp a8, a2 ; a8 - a2
|
||||
0279 00001150 C300 jrhi ld_err_short
|
||||
00001160 00E0
|
||||
0280 00001170 ld_no_src:
|
||||
0281
|
||||
0282 ; target range: 0x100 <= paddr and paddr+size <= 0x200
|
||||
0283 00001170 07A0 move @LD_SEC_PADDR, a0, 1
|
||||
00001180 01882900
|
||||
0284 000011A0 0B40 cmpi 100h, a0
|
||||
000011B0 FEFF
|
||||
0285 000011C0 C800 jrlo ld_err_bounds
|
||||
000011D0 00E5
|
||||
0286 000011E0 07A1 move @LD_SEC_SIZE, a1, 1
|
||||
000011F0 01882920
|
||||
0287 00001210 4C03 move a0, a3
|
||||
0288 00001220 4023 add a1, a3 ; target end
|
||||
0289 00001230 09E5 movi 2000000h, a5, L
|
||||
00001240 02000000
|
||||
0290 00001260 48A3 cmp a5, a3
|
||||
0291 00001270 C300 jrhi ld_err_bounds
|
||||
00001280 00DA
|
||||
0292
|
||||
0293 ; overlap with the loader page [01880000,01883200)
|
||||
0294 00001290 09E5 movi 01883200h, a5, L
|
||||
000012A0 01883200
|
||||
0295 000012C0 48A0 cmp a5, a0
|
||||
0296 000012D0 C907 jrhs ld_ov1_done
|
||||
0297 000012E0 09E5 movi 01880000h, a5, L
|
||||
000012F0 01880000
|
||||
0298 00001310 4865 cmp a3, a5
|
||||
GSP COFF Assembler, Version 2.00, 87.300 Sun Oct 18 15:19:03 2026
|
||||
(c) Copyright 1985, 1987, Texas Instruments Inc.
|
||||
|
||||
PAGE 8
|
||||
|
||||
0299 00001320 C902 jrhs ld_ov1_done
|
||||
0300 00001330 C000 jruc ld_err_overlap
|
||||
00001340 00D2
|
||||
0301 00001350 ld_ov1_done:
|
||||
0302
|
||||
0303 ; overlap with the COFF buffer [buf, buf+len*8)
|
||||
0304 00001350 4D05 move a8, a5
|
||||
0305 00001360 2465 sll 3, a5
|
||||
0306 00001370 40E5 add a7, a5 ; buffer end in bits
|
||||
0307 00001380 48A0 cmp a5, a0
|
||||
0308 00001390 C904 jrhs ld_ov2_done
|
||||
0309 000013A0 4867 cmp a3, a7
|
||||
0310 000013B0 C902 jrhs ld_ov2_done
|
||||
0311 000013C0 C000 jruc ld_err_overlap
|
||||
000013D0 00C9
|
||||
0312 000013E0 ld_ov2_done:
|
||||
0313
|
||||
0314 ; ---- global free-list check ------------------------
|
||||
0315 ; a block is {u32 size_bits; ...; u32 next@+0x20}; dat
|
||||
0316 000013E0 0780 move a0, @LD_SEC_PADDR, 1 ; (unchanged, kept for clari
|
||||
000013F0 01882900
|
||||
0317 00001410 0783 move a3, @LD_SEC_SIZE, 1 ; temporarily hold target end
|
||||
00001420 01882920
|
||||
0318 00001440 07A6 move @1E8AC0h, a6, 1 ; global free-list head (block a
|
||||
00001450 001E8AC0
|
||||
0319 00001470 09E5 movi 64, a5, L
|
||||
00001480 00000040
|
||||
0320 000014A0 ld_free_walk:
|
||||
0321 000014A0 4CC6 move a6, a6
|
||||
0322 000014B0 CA00 jreq ld_err_notfree
|
||||
000014C0 00C2
|
||||
0323 000014D0 86C1 move *a6, a1, 1 ; block size in bits
|
||||
0324 000014E0 B6C2 move *a6(20h), a2, 1 ; next block
|
||||
000014F0 0020
|
||||
0325 00001500 4CC0 move a6, a0
|
||||
0326 00001510 0B00 addi 40h, a0 ; user start
|
||||
00001520 0040
|
||||
0327 00001530 07A3 move @LD_SEC_PADDR, a3, 1
|
||||
00001540 01882900
|
||||
0328 00001560 4803 cmp a0, a3
|
||||
0329 00001570 C808 jrlo ld_free_next
|
||||
0330 00001580 4CC4 move a6, a4
|
||||
0331 00001590 4024 add a1, a4 ; block end
|
||||
0332 000015A0 07A1 move @LD_SEC_SIZE, a1, 1 ; target end (stashed above)
|
||||
000015B0 01882920
|
||||
0333 000015D0 4881 cmp a4, a1
|
||||
0334 000015E0 C301 jrhi ld_free_next
|
||||
0335 000015F0 C004 jruc ld_free_ok
|
||||
0336 00001600 ld_free_next:
|
||||
0337 00001600 4C46 move a2, a6
|
||||
0338 00001610 3F05 dsjs a5, ld_free_walk
|
||||
0339 00001620 C000 jruc ld_err_notfree
|
||||
00001630 00AB
|
||||
0340 00001640 ld_free_ok:
|
||||
0341
|
||||
0342 ; restore size in LD_SEC_SIZE (the stash overwrote it)
|
||||
GSP COFF Assembler, Version 2.00, 87.300 Sun Oct 18 15:19:03 2026
|
||||
(c) Copyright 1985, 1987, Texas Instruments Inc.
|
||||
|
||||
PAGE 9
|
||||
|
||||
0343 ; target end - paddr = size
|
||||
0344 00001640 07A1 move @LD_SEC_SIZE, a1, 1
|
||||
00001650 01882920
|
||||
0345 00001670 07A0 move @LD_SEC_PADDR, a0, 1
|
||||
00001680 01882900
|
||||
0346 000016A0 4401 sub a0, a1 ; a1 = size again
|
||||
0347 000016B0 0781 move a1, @LD_SEC_SIZE, 1
|
||||
000016C0 01882920
|
||||
0348
|
||||
0349 ; ---- place the section -----------------------------
|
||||
0350 000016E0 07A0 move @LD_SEC_SCNPTR, a0, 1
|
||||
000016F0 01882940
|
||||
0351 00001710 4C00 move a0, a0
|
||||
0352 00001720 CA0D jreq ld_zero_sec
|
||||
0353 00001730 2460 sll 3, a0 ; file offset -> bit offset
|
||||
0354 00001740 40E0 add a7, a0 ; source address
|
||||
0355 00001750 07A2 move @LD_SEC_PADDR, a2, 1
|
||||
00001760 01882900
|
||||
0356 00001780 07A1 move @LD_SEC_SIZE, a1, 1
|
||||
00001790 01882920
|
||||
0357 000017B0 2F81 srl 4, a1 ; number of 16-bit words
|
||||
0358 000017C0 ld_copy_words:
|
||||
0359 000017C0 9404 move *a0+, a4, 0
|
||||
0360 000017D0 9082 move a4, *a2+, 0
|
||||
0361 000017E0 3C61 dsjs a1, ld_copy_words
|
||||
0362 000017F0 C00A jruc ld_sec_next
|
||||
0363
|
||||
0364 00001800 ld_zero_sec:
|
||||
0365 00001800 07A2 move @LD_SEC_PADDR, a2, 1
|
||||
00001810 01882900
|
||||
0366 00001830 07A1 move @LD_SEC_SIZE, a1, 1
|
||||
00001840 01882920
|
||||
0367 00001860 2F81 srl 4, a1
|
||||
0368 00001870 4484 sub a4, a4
|
||||
0369 00001880 ld_zero_words:
|
||||
0370 00001880 9082 move a4, *a2+, 0
|
||||
0371 00001890 3C41 dsjs a1, ld_zero_words
|
||||
0372
|
||||
0373 000018A0 ld_sec_next:
|
||||
0374 000018A0 0B0A addi 140h, a10 ; 40-byte section header = 320 bits
|
||||
000018B0 0140
|
||||
0375 000018C0 0B0B addi 1, a11
|
||||
000018D0 0001
|
||||
0376 000018E0 C000 jruc ld_sec_loop
|
||||
000018F0 FF21
|
||||
0377
|
||||
0378 00001900 ld_sec_done:
|
||||
0379 00001900 07A0 move @LD_TEXT_ADDR, a0, 1
|
||||
00001910 01882960
|
||||
0380 00001930 0780 move a0, @RESULT_TEXT_A, 1
|
||||
00001940 01882D40
|
||||
0381 00001960 07A1 move @LD_TEXT_SIZE, a1, 1
|
||||
00001970 01882980
|
||||
0382 00001990 0781 move a1, @RESULT_TEXT_S, 1
|
||||
000019A0 01882D60
|
||||
0383 000019C0 07A0 move @LD_DATA_ADDR, a0, 1
|
||||
GSP COFF Assembler, Version 2.00, 87.300 Sun Oct 18 15:19:03 2026
|
||||
(c) Copyright 1985, 1987, Texas Instruments Inc.
|
||||
|
||||
PAGE 10
|
||||
|
||||
000019D0 018829A0
|
||||
0384 000019F0 0780 move a0, @RESULT_DATA_A, 1
|
||||
00001A00 01882D80
|
||||
0385 00001A20 07A1 move @LD_DATA_SIZE, a1, 1
|
||||
00001A30 018829C0
|
||||
0386 00001A50 0781 move a1, @RESULT_DATA_S, 1
|
||||
00001A60 01882DA0
|
||||
0387 00001A80 07A0 move @LD_BSS_ADDR, a0, 1
|
||||
00001A90 018829E0
|
||||
0388 00001AB0 0780 move a0, @RESULT_BSS_A, 1
|
||||
00001AC0 01882DC0
|
||||
0389 00001AE0 07A1 move @LD_BSS_SIZE, a1, 1
|
||||
00001AF0 01882A00
|
||||
0390 00001B10 0781 move a1, @RESULT_BSS_S, 1
|
||||
00001B20 01882DE0
|
||||
0391 00001B40 07A0 move @LD_RELOCS, a0, 1
|
||||
00001B50 018828E0
|
||||
0392 00001B70 0780 move a0, @RESULT_RELOCS, 1
|
||||
00001B80 01882E00
|
||||
0393
|
||||
0394 ; ---- create_process(entry, name, stack, 1, arg) ----
|
||||
0395 00001BA0 07A0 move @LD_ENTRY, a0, 1
|
||||
00001BB0 01882840
|
||||
0396 00001BD0 4C00 move a0, a0
|
||||
0397 00001BE0 CB01 jrne ld_have_entry
|
||||
0398 00001BF0 C053 jruc ld_err_noentry
|
||||
0399 00001C00 ld_have_entry:
|
||||
0400 00001C00 07AE move @LD_A14, a14, 1
|
||||
00001C10 01882820
|
||||
0401 00001C30 07AF move @LD_SP_AFTER, sp, 1
|
||||
00001C40 01882800
|
||||
0402 00001C60 A3CF move a14, -*sp, 1 ; the slot the firmware callee rest
|
||||
0403 00001C70 09EE movi ARG_AREA, a14, L
|
||||
00001C80 01882B00
|
||||
0404 00001CA0 09E0 movi 0, a0, L
|
||||
00001CB0 00000000
|
||||
0405 00001CD0 920E move a0, *a14+, 1 ; arg4 = 0
|
||||
0406 00001CE0 09E0 movi 1, a0, L
|
||||
00001CF0 00000001
|
||||
0407 00001D10 920E move a0, *a14+, 1 ; arg3 = 1
|
||||
0408 00001D20 09E0 movi 6000h, a0, L
|
||||
00001D30 00006000
|
||||
0409 00001D50 920E move a0, *a14+, 1 ; arg2 = stack bytes
|
||||
0410 00001D60 09E0 movi ld_appname, a0, L
|
||||
00001D70 000025E0'
|
||||
0411 00001D90 920E move a0, *a14+, 1 ; arg1 = name string
|
||||
0412 00001DA0 07A0 move @LD_ENTRY, a0, 1
|
||||
00001DB0 01882840
|
||||
0413 00001DD0 920E move a0, *a14+, 1 ; arg0 = entry (bit address)
|
||||
0414 00001DE0 0D5F calla 3F706A40h ; create_process
|
||||
00001DF0 3F706A40
|
||||
0415 00001E10 07AF move @LD_SP_AFTER, sp, 1
|
||||
00001E20 01882800
|
||||
0416 00001E40 07AE move @LD_A14, a14, 1
|
||||
00001E50 01882820
|
||||
0417 00001E70 0550 setf 16, 0, 0
|
||||
GSP COFF Assembler, Version 2.00, 87.300 Sun Oct 18 15:19:03 2026
|
||||
(c) Copyright 1985, 1987, Texas Instruments Inc.
|
||||
|
||||
PAGE 11
|
||||
|
||||
0418 00001E80 0740 setf 32, 0, 1
|
||||
0419 00001E90 0788 move a8, @RESULT_PCB, 1
|
||||
00001EA0 01882E20
|
||||
0420 00001EC0 4D08 move a8, a8
|
||||
0421 00001ED0 CA29 jreq ld_err_create
|
||||
0422
|
||||
0423 00001EE0 4400 sub a0, a0
|
||||
0424 00001EF0 0780 move a0, @RESULT_STATUS, 1
|
||||
00001F00 01882D00
|
||||
0425 00001F20 C036 jruc ld_finish
|
||||
0426
|
||||
0427 ; ---- errors ----------------------------------------
|
||||
0428 00001F30 ld_bad_desc:
|
||||
0429 00001F30 09E0 movi 1, a0, L
|
||||
00001F40 00000001
|
||||
0430 00001F60 C023 jruc ld_error
|
||||
0431 00001F70 ld_err_short:
|
||||
0432 00001F70 09E0 movi 2, a0, L
|
||||
00001F80 00000002
|
||||
0433 00001FA0 C01F jruc ld_error
|
||||
0434 00001FB0 ld_err_magic:
|
||||
0435 00001FB0 09E0 movi 3, a0, L
|
||||
00001FC0 00000003
|
||||
0436 00001FE0 C01B jruc ld_error
|
||||
0437 00001FF0 ld_err_size:
|
||||
0438 00001FF0 09E0 movi 4, a0, L
|
||||
00002000 00000004
|
||||
0439 00002020 C017 jruc ld_error
|
||||
0440 00002030 ld_err_bounds:
|
||||
0441 00002030 09E0 movi 5, a0, L
|
||||
00002040 00000005
|
||||
0442 00002060 C013 jruc ld_error
|
||||
0443 00002070 ld_err_overlap:
|
||||
0444 00002070 09E0 movi 6, a0, L
|
||||
00002080 00000006
|
||||
0445 000020A0 C00F jruc ld_error
|
||||
0446 000020B0 ld_err_reloc:
|
||||
0447 000020B0 09E0 movi 7, a0, L
|
||||
000020C0 00000007
|
||||
0448 000020E0 C00B jruc ld_error
|
||||
0449 000020F0 ld_err_notfree:
|
||||
0450 000020F0 09E0 movi 8, a0, L
|
||||
00002100 00000008
|
||||
0451 00002120 C007 jruc ld_error
|
||||
0452 00002130 ld_err_noentry:
|
||||
0453 00002130 09E0 movi 9, a0, L
|
||||
00002140 00000009
|
||||
0454 00002160 C003 jruc ld_error
|
||||
0455 00002170 ld_err_create:
|
||||
0456 00002170 09E0 movi 10, a0, L
|
||||
00002180 0000000A
|
||||
0457 000021A0 ld_error:
|
||||
0458 000021A0 0780 move a0, @RESULT_STATUS, 1
|
||||
000021B0 01882D00
|
||||
0459 000021D0 07A0 move @LD_NSCNS, a0, 1
|
||||
000021E0 018828C0
|
||||
GSP COFF Assembler, Version 2.00, 87.300 Sun Oct 18 15:19:03 2026
|
||||
(c) Copyright 1985, 1987, Texas Instruments Inc.
|
||||
|
||||
PAGE 12
|
||||
|
||||
0460 00002200 0780 move a0, @RESULT_NSCNS, 1
|
||||
00002210 01882E40
|
||||
0461 00002230 07A0 move @LD_RELOCS, a0, 1
|
||||
00002240 018828E0
|
||||
0462 00002260 0780 move a0, @RESULT_RELOCS, 1
|
||||
00002270 01882E00
|
||||
0463
|
||||
0464 00002290 ld_finish:
|
||||
0465 00002290 07A0 move @LD_ENTRY, a0, 1
|
||||
000022A0 01882840
|
||||
0466 000022C0 0780 move a0, @RESULT_ENTRY, 1
|
||||
000022D0 01882D20
|
||||
0467 000022F0 07A0 move @LD_NSCNS, a0, 1
|
||||
00002300 018828C0
|
||||
0468 00002320 0780 move a0, @RESULT_NSCNS, 1
|
||||
00002330 01882E40
|
||||
0469 00002350 07A0 move @LD_LEN, a0, 1
|
||||
00002360 01882880
|
||||
0470 00002380 0780 move a0, @RESULT_LEN, 1
|
||||
00002390 01882E60
|
||||
0471 000023B0 09E0 movi LOADER_BASE, a0, L
|
||||
000023C0 01880000
|
||||
0472 000023E0 0780 move a0, @RESULT_VERSION, 1
|
||||
000023F0 01882E80
|
||||
0473
|
||||
0474 ; ---- return or spin --------------------------------
|
||||
0475 00002410 07A0 move @LD_MODE, a0, 1
|
||||
00002420 018828A0
|
||||
0476 00002440 4C00 move a0, a0
|
||||
0477 00002450 CB0C jrne ld_return
|
||||
0478 ; mode 0 (debugger entry): restore the interrupted sta
|
||||
0479 ; the PC the harness hijacked. Returning to the OS id
|
||||
0480 ; scheduler run the created child.
|
||||
0481 00002460 07AF move @LD_SP_AFTER, sp, 1
|
||||
00002470 01882800
|
||||
0482 00002490 07AE move @LD_A14, a14, 1
|
||||
000024A0 01882820
|
||||
0483 000024C0 09AF mmfm sp, a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13
|
||||
000024D0 3FFF
|
||||
0484 000024E0 07A0 move @LD_ORIG_PC, a0, 1
|
||||
000024F0 01882A20
|
||||
0485 00002510 0160 jump a0
|
||||
0486
|
||||
0487 00002520 ld_return:
|
||||
0488 00002520 07AF move @LD_SP_AFTER, sp, 1
|
||||
00002530 01882800
|
||||
0489 00002550 07AE move @LD_A14, a14, 1
|
||||
00002560 01882820
|
||||
0490 00002580 09AF mmfm sp, a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13
|
||||
00002590 3FFF
|
||||
0491 000025A0 07A8 move @RESULT_STATUS, a8, 1 ; 0 = ok, else the error co
|
||||
000025B0 01882D00
|
||||
0492 000025D0 0960 rets
|
||||
0493
|
||||
0494 000025E0 ld_appname:
|
||||
0495 000025E0 4C .byte "LOADER", 0
|
||||
GSP COFF Assembler, Version 2.00, 87.300 Sun Oct 18 15:19:03 2026
|
||||
(c) Copyright 1985, 1987, Texas Instruments Inc.
|
||||
|
||||
PAGE 13
|
||||
|
||||
000025E8 4F
|
||||
000025F0 41
|
||||
000025F8 44
|
||||
00002600 45
|
||||
00002608 52
|
||||
00002610 00
|
||||
0496 .end
|
||||
|
||||
No Errors, No Warnings
|
||||
@@ -0,0 +1,35 @@
|
||||
*****************************************************
|
||||
GSP COFF Linker, Version 2.00, 87.300
|
||||
*****************************************************
|
||||
Sun Oct 18 15:19:03 2026
|
||||
|
||||
OUTPUT FILE NAME: <LOADER.out>
|
||||
ENTRY POINT SYMBOL: "_start" address: 01880000
|
||||
|
||||
|
||||
SECTION ALLOCATION MAP
|
||||
|
||||
output attributes/
|
||||
section page origin length input sections
|
||||
-------- ---- ---------- ---------- ----------------
|
||||
.data 0 00000000 00000000
|
||||
|
||||
.bss 0 00000000 00000000 UNINITIALIZED
|
||||
|
||||
.text 0 01880000 00002620
|
||||
01880000 00002620 LOADER.obj (.text)
|
||||
|
||||
|
||||
GLOBAL SYMBOLS
|
||||
|
||||
address name address name
|
||||
-------- ---- -------- ----
|
||||
00000000 .bss 00000000 edata
|
||||
00000000 .data 00000000 .bss
|
||||
01880000 .text 00000000 end
|
||||
01880000 _start 00000000 .data
|
||||
00000000 edata 01880000 _start
|
||||
00000000 end 01880000 .text
|
||||
01882620 etext 01882620 etext
|
||||
|
||||
[7 symbols]
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,90 @@
|
||||
GSP COFF Assembler, Version 2.00, 87.300 Sun Oct 18 15:08:14 2026
|
||||
(c) Copyright 1985, 1987, Texas Instruments Inc.
|
||||
|
||||
PAGE 1
|
||||
|
||||
0001 ; marker.asm -- loader acceptance app.
|
||||
0002 ;
|
||||
0003 ; Built by dwt/loader/build.sh with three separate sect
|
||||
0004 ; .text 018C0000h (byte 0x318000)
|
||||
0005 ; .data 018D0000h (byte 0x31A000)
|
||||
0006 ; .bss 018D8000h (byte 0x31B000)
|
||||
0007 ;
|
||||
0008 ; It is the *COFF image* that the loader must place; it
|
||||
0009 ; raw blob. The loader parses the COFF, copies .text a
|
||||
0010 ; and calls create_process() with the image's entry poi
|
||||
0011 ;
|
||||
0012 ; Evidence cells (32-bit, bit addresses; outside every
|
||||
0013 ; 018E0000 _start address at run time (must be 018C0
|
||||
0014 ; 018E0020 d_magic read from .data (must be DEADBEE
|
||||
0015 ; 018E0040 d_two read from .data (must be 1234567
|
||||
0016 ; 018E0060 b_zero read from .bss (must be 0; the
|
||||
0017 ; 018E0080 b_counter, incremented forever (proves th
|
||||
0018 ;
|
||||
0019 ; The harness pre-fills the whole .bss range with A5A5A
|
||||
0020 ; a zero at 018E0060 is the loader's zero-fill, not a f
|
||||
0021
|
||||
0022 .def _start
|
||||
0023 00000000 .text
|
||||
0024 00000000 _start:
|
||||
0025 00000000 0550 setf 16, 0, 0
|
||||
0026 00000010 0740 setf 32, 0, 1
|
||||
0027
|
||||
0028 ; Run-time address of this code: position dependence,
|
||||
0029 00000020 09E2 movi _start, a2, L
|
||||
00000030 00000000'
|
||||
0030 00000050 0782 move a2, @018E0000h, 1
|
||||
00000060 018E0000
|
||||
0031
|
||||
0032 ; Initialised .data must have been copied by the loade
|
||||
0033 00000080 07A0 move @d_magic, a0, 1
|
||||
00000090 00000000"
|
||||
0034 000000B0 0780 move a0, @018E0020h, 1
|
||||
000000C0 018E0020
|
||||
0035
|
||||
0036 000000E0 07A1 move @d_two, a1, 1
|
||||
000000F0 00000020"
|
||||
0037 00000110 0781 move a1, @018E0040h, 1
|
||||
00000120 018E0040
|
||||
0038
|
||||
0039 ; .bss must have been zeroed by the loader (harness pr
|
||||
0040 00000140 07A3 move @b_zero, a3, 1
|
||||
00000150 00000000+
|
||||
0041 00000170 0783 move a3, @018E0060h, 1
|
||||
00000180 018E0060
|
||||
0042
|
||||
0043 ; A live counter: a created process, not a one-shot ju
|
||||
0044 000001A0 4484 sub a4, a4
|
||||
0045 000001B0 loop:
|
||||
0046 000001B0 0B04 addi 1, a4
|
||||
000001C0 0001
|
||||
0047 000001D0 0784 move a4, @b_counter, 1
|
||||
GSP COFF Assembler, Version 2.00, 87.300 Sun Oct 18 15:08:14 2026
|
||||
(c) Copyright 1985, 1987, Texas Instruments Inc.
|
||||
|
||||
PAGE 2
|
||||
|
||||
000001E0 00000020+
|
||||
0048 00000200 0784 move a4, @018E0080h, 1
|
||||
00000210 018E0080
|
||||
0049 00000230 09E5 movi 2000h, a5, L
|
||||
00000240 00002000
|
||||
0050 00000260 delay:
|
||||
0051 00000260 3C25 dsjs a5, delay
|
||||
0052 00000270 C0F3 jruc loop
|
||||
0053
|
||||
0054 ; Kept to leave a call in the image (and a relocation
|
||||
0055 .global sub
|
||||
0056 00000280 sub:
|
||||
0057 00000280 0960 rets
|
||||
0058
|
||||
0059 00000000 .data
|
||||
0060 00000000 DEADBEEF d_magic: .long 0DEADBEEFh
|
||||
0061 00000020 12345678 d_two: .long 012345678h
|
||||
0062
|
||||
0063 00000000 .bss b_zero, 32, 1
|
||||
0064 00000020 .bss b_counter, 32, 1
|
||||
0065
|
||||
0066 .end
|
||||
|
||||
No Errors, No Warnings
|
||||
@@ -0,0 +1,38 @@
|
||||
*****************************************************
|
||||
GSP COFF Linker, Version 2.00, 87.300
|
||||
*****************************************************
|
||||
Sun Oct 18 15:08:14 2026
|
||||
|
||||
OUTPUT FILE NAME: <MARKER.out>
|
||||
ENTRY POINT SYMBOL: "_start" address: 018C0000
|
||||
|
||||
|
||||
SECTION ALLOCATION MAP
|
||||
|
||||
output attributes/
|
||||
section page origin length input sections
|
||||
-------- ---- ---------- ---------- ----------------
|
||||
.text 0 018C0000 00000290
|
||||
018C0000 00000290 MARKER.obj (.text)
|
||||
|
||||
.data 0 018D0000 00000040
|
||||
018D0000 00000040 MARKER.obj (.data)
|
||||
|
||||
.bss 0 018D8000 00000040 UNINITIALIZED
|
||||
018D8000 00000040 MARKER.obj (.bss)
|
||||
|
||||
|
||||
GLOBAL SYMBOLS
|
||||
|
||||
address name address name
|
||||
-------- ---- -------- ----
|
||||
018D8000 .bss 018C0000 .text
|
||||
018D0000 .data 018C0000 _start
|
||||
018C0000 .text 018C0280 sub
|
||||
018C0000 _start 018C0290 etext
|
||||
018D0040 edata 018D0000 .data
|
||||
018D8040 end 018D0040 edata
|
||||
018C0290 etext 018D8000 .bss
|
||||
018C0280 sub 018D8040 end
|
||||
|
||||
[8 symbols]
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,229 @@
|
||||
GSP COFF Assembler, Version 2.00, 87.300 Sun Oct 18 15:04:44 2026
|
||||
(c) Copyright 1985, 1987, Texas Instruments Inc.
|
||||
|
||||
PAGE 1
|
||||
|
||||
0001 ; xhello.asm -- open a *new* X connection and create/ma
|
||||
0002 ; DWT X server.
|
||||
0003 ;
|
||||
0004 ; Run as a first-class process created by xlaunch.asm (
|
||||
0005 ; the rdebug dispatcher's context: a connect made from
|
||||
0006 ; accepted at the service layer but the server never re
|
||||
0007 ; XOpenDisplay returns an unusable Display. A fresh pr
|
||||
0008 ;
|
||||
0009 ; Calling convention (the one the firmware itself uses;
|
||||
0010 ; 07F57044 and the TM at 07E5D2B4):
|
||||
0011 ;
|
||||
0012 ; MOVE A14,-*SP,1 ; reserve the slot the ca
|
||||
0013 ; MOVI argN,A0 / MOVE A0,*A14+,1 ; last argument
|
||||
0014 ; ...
|
||||
0015 ; MOVI arg0,A0 / MOVE A0,*A14+,1 ; first argumen
|
||||
0016 ; CALLA target
|
||||
0017 ;
|
||||
0018 ; Xlib clobbers the CPU's SETF field state, so the ABI'
|
||||
0019 ; re-established after every call. The Display pointer
|
||||
0020 ; kept in a11/a10 (both callee-saved by every Xlib entr
|
||||
0021 ; be overwritten by the new process's stack, a register
|
||||
0022 ;
|
||||
0023 ; Xlib entry points (Ghidra address -> bit address):
|
||||
0024 ; 7F384AE XOpenDisplay(name) -> 3F9C2570
|
||||
0025 ; 7FA8372 XCreateSimpleWindow(...) -> 3FD41B90
|
||||
0026 ; 7FAC8B6 XMapWindow(display,window) -> 3FD645B0
|
||||
0027 ; 7FB3ED6 XSync(display,discard) -> 3FD9F6B0
|
||||
0028 ; 7F68B1A strlen(s) -> 3FB458D0
|
||||
0029 ;
|
||||
0030 ; Markers (32-bit cells, bit addresses; diagnostic only
|
||||
0031 ; 01890100 display pointer
|
||||
0032 ; 01890110 root window
|
||||
0033 ; 01890120 window id
|
||||
0034 ; 01890130 XSync return
|
||||
0035 ; 01890140 stage counter
|
||||
0036 ; 01890160 strlen("0::0") -- must be 4; if not, we s
|
||||
0037
|
||||
0038 00000000 .text
|
||||
0039 00000000 _start:
|
||||
0040 00000000 0550 setf 16, 0, 0
|
||||
0041 00000010 0740 setf 32, 0, 1
|
||||
0042 00000020 098F mmtm sp, a0,a1,a2,a3,a4,a5,a6,a7
|
||||
00000030 FF00
|
||||
0043
|
||||
0044 00000040 078F move sp, @01890420h, 1 ; entry SP
|
||||
00000050 01890420
|
||||
0045 00000070 078E move a14, @01890400h, 1 ; entry A14
|
||||
00000080 01890400
|
||||
0046
|
||||
0047 000000A0 09E0 movi 1, a0, L
|
||||
000000B0 00000001
|
||||
0048 000000D0 0780 move a0, @01890140h, 1 ; stage = 1
|
||||
000000E0 01890140
|
||||
0049
|
||||
0050 ; ---- convention check: strlen("0::0") == 4 ---------
|
||||
0051 00000100 A3CF move a14, -*sp, 1
|
||||
GSP COFF Assembler, Version 2.00, 87.300 Sun Oct 18 15:04:44 2026
|
||||
(c) Copyright 1985, 1987, Texas Instruments Inc.
|
||||
|
||||
PAGE 2
|
||||
|
||||
0052 00000110 09EE movi 01892000h, a14, L
|
||||
00000120 01892000
|
||||
0053 00000140 09E0 movi 3FACE948h, a0, L ; ROM "0::0"
|
||||
00000150 3FACE948
|
||||
0054 00000170 920E move a0, *a14+, 1 ; arg0
|
||||
0055 00000180 0D5F calla 3FB458D0h ; strlen
|
||||
00000190 3FB458D0
|
||||
0056 000001B0 07AF move @01890420h, sp, 1
|
||||
000001C0 01890420
|
||||
0057 000001E0 07AE move @01890400h, a14, 1
|
||||
000001F0 01890400
|
||||
0058 00000210 0550 setf 16, 0, 0 ; Xlib leaves the field sizes changed;
|
||||
0059 00000220 0740 setf 32, 0, 1 ; re-establish the ABI's 32-bit field 1
|
||||
0060 00000230 0788 move a8, @01890160h, 1 ; MARK strlen
|
||||
00000240 01890160
|
||||
0061 00000260 09E0 movi 4, a0, L
|
||||
00000270 00000004
|
||||
0062 00000290 4808 cmp a0, a8
|
||||
0063 000002A0 CB00 jrne done
|
||||
000002B0 0091
|
||||
0064
|
||||
0065 000002C0 09E0 movi 2, a0, L
|
||||
000002D0 00000002
|
||||
0066 000002F0 0780 move a0, @01890140h, 1
|
||||
00000300 01890140
|
||||
0067
|
||||
0068 ; ---- display = XOpenDisplay("0::0") ----------------
|
||||
0069 00000320 A3CF move a14, -*sp, 1
|
||||
0070 00000330 09EE movi 01892000h, a14, L
|
||||
00000340 01892000
|
||||
0071 00000360 09E0 movi 3FACE948h, a0, L
|
||||
00000370 3FACE948
|
||||
0072 00000390 920E move a0, *a14+, 1 ; arg0 = name
|
||||
0073 000003A0 0D5F calla 3F9C2570h ; XOpenDisplay
|
||||
000003B0 3F9C2570
|
||||
0074 000003D0 07AF move @01890420h, sp, 1
|
||||
000003E0 01890420
|
||||
0075 00000400 07AE move @01890400h, a14, 1
|
||||
00000410 01890400
|
||||
0076 00000430 0550 setf 16, 0, 0
|
||||
0077 00000440 0740 setf 32, 0, 1
|
||||
0078 00000450 4D0B move a8, a11 ; keep the Display in a callee-saved re
|
||||
0079 00000460 078B move a11, @01890100h, 1 ; MARK display
|
||||
00000470 01890100
|
||||
0080 00000490 4D6B move a11, a11
|
||||
0081 000004A0 CA72 jreq done
|
||||
0082
|
||||
0083 000004B0 09E0 movi 3, a0, L
|
||||
000004C0 00000003
|
||||
0084 000004E0 0780 move a0, @01890140h, 1
|
||||
000004F0 01890140
|
||||
0085
|
||||
0086 ; ---- root = *(*(display+0x480)+0x40) ---------------
|
||||
0087 00000510 B76A move *a11(0480h), a10, 1
|
||||
00000520 0480
|
||||
0088 00000530 B74A move *a10(040h), a10, 1
|
||||
GSP COFF Assembler, Version 2.00, 87.300 Sun Oct 18 15:04:44 2026
|
||||
(c) Copyright 1985, 1987, Texas Instruments Inc.
|
||||
|
||||
PAGE 3
|
||||
|
||||
00000540 0040
|
||||
0089 00000550 078A move a10, @01890110h, 1 ; MARK root
|
||||
00000560 01890110
|
||||
0090
|
||||
0091 ; ---- XCreateSimpleWindow(display,root,100,100,400,20
|
||||
0092 00000580 A3CF move a14, -*sp, 1
|
||||
0093 00000590 09EE movi 01892000h, a14, L
|
||||
000005A0 01892000
|
||||
0094 000005C0 09E0 movi 0, a0, L
|
||||
000005D0 00000000
|
||||
0095 000005F0 920E move a0, *a14+, 1 ; background = 0 (black)
|
||||
0096 00000600 920E move a0, *a14+, 1 ; border = 0
|
||||
0097 00000610 09E0 movi 2, a0, L
|
||||
00000620 00000002
|
||||
0098 00000640 920E move a0, *a14+, 1 ; border width
|
||||
0099 00000650 09E0 movi 200, a0, L
|
||||
00000660 000000C8
|
||||
0100 00000680 920E move a0, *a14+, 1 ; height
|
||||
0101 00000690 09E0 movi 400, a0, L
|
||||
000006A0 00000190
|
||||
0102 000006C0 920E move a0, *a14+, 1 ; width
|
||||
0103 000006D0 09E0 movi 100, a0, L
|
||||
000006E0 00000064
|
||||
0104 00000700 920E move a0, *a14+, 1 ; y
|
||||
0105 00000710 920E move a0, *a14+, 1 ; x
|
||||
0106 00000720 934E move a10, *a14+, 1 ; parent = root
|
||||
0107 00000730 936E move a11, *a14+, 1 ; display
|
||||
0108 00000740 0D5F calla 3FD41B90h ; XCreateSimpleWindow
|
||||
00000750 3FD41B90
|
||||
0109 00000770 07AF move @01890420h, sp, 1
|
||||
00000780 01890420
|
||||
0110 000007A0 07AE move @01890400h, a14, 1
|
||||
000007B0 01890400
|
||||
0111 000007D0 0550 setf 16, 0, 0
|
||||
0112 000007E0 0740 setf 32, 0, 1
|
||||
0113 000007F0 4D0A move a8, a10 ; window id (root no longer needed)
|
||||
0114 00000800 078A move a10, @01890120h, 1 ; MARK window
|
||||
00000810 01890120
|
||||
0115
|
||||
0116 00000830 09E0 movi 4, a0, L
|
||||
00000840 00000004
|
||||
0117 00000860 0780 move a0, @01890140h, 1
|
||||
00000870 01890140
|
||||
0118
|
||||
0119 ; ---- XMapWindow(display, window) -------------------
|
||||
0120 00000890 A3CF move a14, -*sp, 1
|
||||
0121 000008A0 09EE movi 01892000h, a14, L
|
||||
000008B0 01892000
|
||||
0122 000008D0 934E move a10, *a14+, 1 ; window
|
||||
0123 000008E0 936E move a11, *a14+, 1 ; display
|
||||
0124 000008F0 0D5F calla 3FD645B0h ; XMapWindow
|
||||
00000900 3FD645B0
|
||||
0125 00000920 07AF move @01890420h, sp, 1
|
||||
00000930 01890420
|
||||
0126 00000950 07AE move @01890400h, a14, 1
|
||||
00000960 01890400
|
||||
GSP COFF Assembler, Version 2.00, 87.300 Sun Oct 18 15:04:44 2026
|
||||
(c) Copyright 1985, 1987, Texas Instruments Inc.
|
||||
|
||||
PAGE 4
|
||||
|
||||
0127 00000980 0550 setf 16, 0, 0
|
||||
0128 00000990 0740 setf 32, 0, 1
|
||||
0129
|
||||
0130 000009A0 09E0 movi 5, a0, L
|
||||
000009B0 00000005
|
||||
0131 000009D0 0780 move a0, @01890140h, 1
|
||||
000009E0 01890140
|
||||
0132
|
||||
0133 ; ---- XSync(display, 0) -----------------------------
|
||||
0134 00000A00 A3CF move a14, -*sp, 1
|
||||
0135 00000A10 09EE movi 01892000h, a14, L
|
||||
00000A20 01892000
|
||||
0136 00000A40 09E0 movi 0, a0, L
|
||||
00000A50 00000000
|
||||
0137 00000A70 920E move a0, *a14+, 1 ; discard = 0
|
||||
0138 00000A80 936E move a11, *a14+, 1 ; display
|
||||
0139 00000A90 0D5F calla 3FD9F6B0h ; XSync
|
||||
00000AA0 3FD9F6B0
|
||||
0140 00000AC0 07AF move @01890420h, sp, 1
|
||||
00000AD0 01890420
|
||||
0141 00000AF0 07AE move @01890400h, a14, 1
|
||||
00000B00 01890400
|
||||
0142 00000B20 0550 setf 16, 0, 0
|
||||
0143 00000B30 0740 setf 32, 0, 1
|
||||
0144 00000B40 0788 move a8, @01890130h, 1 ; MARK sync
|
||||
00000B50 01890130
|
||||
0145
|
||||
0146 00000B70 09E0 movi 6, a0, L
|
||||
00000B80 00000006
|
||||
0147 00000BA0 0780 move a0, @01890140h, 1
|
||||
00000BB0 01890140
|
||||
0148
|
||||
0149 00000BD0 done:
|
||||
0150 00000BD0 09AF mmfm sp, a0,a1,a2,a3,a4,a5,a6,a7
|
||||
00000BE0 00FF
|
||||
0151 00000BF0 09E8 movi 0, a8, L
|
||||
00000C00 00000000
|
||||
0152 00000C20 0960 rets
|
||||
0153 .end
|
||||
|
||||
No Errors, No Warnings
|
||||
@@ -0,0 +1,34 @@
|
||||
*****************************************************
|
||||
GSP COFF Linker, Version 2.00, 87.300
|
||||
*****************************************************
|
||||
Sun Oct 18 15:04:44 2026
|
||||
|
||||
OUTPUT FILE NAME: <XHELLO.out>
|
||||
ENTRY POINT SYMBOL: 0
|
||||
|
||||
|
||||
SECTION ALLOCATION MAP
|
||||
|
||||
output attributes/
|
||||
section page origin length input sections
|
||||
-------- ---- ---------- ---------- ----------------
|
||||
.data 0 00000000 00000000
|
||||
|
||||
.bss 0 00000000 00000000 UNINITIALIZED
|
||||
|
||||
.text 0 01840000 00000C30
|
||||
01840000 00000C30 XHELLO.obj (.text)
|
||||
|
||||
|
||||
GLOBAL SYMBOLS
|
||||
|
||||
address name address name
|
||||
-------- ---- -------- ----
|
||||
00000000 .bss 00000000 edata
|
||||
00000000 .data 00000000 .bss
|
||||
01840000 .text 00000000 end
|
||||
00000000 edata 00000000 .data
|
||||
00000000 end 01840000 .text
|
||||
01840C30 etext 01840C30 etext
|
||||
|
||||
[6 symbols]
|
||||
Binary file not shown.
Executable
+200
@@ -0,0 +1,200 @@
|
||||
#!/usr/bin/env python3
|
||||
"""coff.py -- TI TMS34010 GSP COFF reader for the VT1200 loader work.
|
||||
|
||||
GSPLNK 2.00 emits the "TI COFF" described in the 1987 Assembler Tools guide,
|
||||
Appendix A. All section addresses and sizes in the section headers are in
|
||||
BITS (the TMS34010 is bit-addressed); file offsets (scnptr/relptr/symptr) are
|
||||
in BYTES.
|
||||
|
||||
Commands
|
||||
coff.py summary FILE... dump header, optional header, sections,
|
||||
symbols (with aux entries) and relocations
|
||||
coff.py raw ABS1 ABS2 extract each section from two absolute
|
||||
outputs and report byte differences
|
||||
coff.py manifest FILE print shell-ish KEY=VALUE lines for one file
|
||||
|
||||
The loader itself parses the same structures in assembly; this script is the
|
||||
reference and the evidence generator.
|
||||
"""
|
||||
import struct
|
||||
import sys
|
||||
|
||||
MAGIC = 0x0090
|
||||
OPTHDR_MAGIC = 0x0108
|
||||
|
||||
RELOC_NAMES = {
|
||||
0x00: "R-ABS",
|
||||
0x10: "R-RELWORD",
|
||||
0x11: "R-RELLONG",
|
||||
0x18: "R-OCRLONG",
|
||||
0x19: "R-GSPPCR16",
|
||||
}
|
||||
|
||||
SECTION_FLAGS = {
|
||||
0x20: "text",
|
||||
0x40: "data",
|
||||
0x80: "bss",
|
||||
}
|
||||
|
||||
|
||||
class CoffError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def parse(path):
|
||||
d = open(path, "rb").read()
|
||||
if len(d) < 20:
|
||||
raise CoffError("%s: shorter than a COFF file header" % path)
|
||||
magic, nscns, timdat, symptr, nsyms, opthdr, flags = struct.unpack_from(
|
||||
"<HHIIIHH", d, 0)
|
||||
if magic != MAGIC:
|
||||
raise CoffError("%s: magic %#06x, expected %#06x"
|
||||
% (path, magic, MAGIC))
|
||||
opt = None
|
||||
if opthdr:
|
||||
if 20 + opthdr > len(d):
|
||||
raise CoffError("%s: optional header past EOF" % path)
|
||||
# TI COFF optional header: magic, vstamp, textsize, datasize, bsssize,
|
||||
# entry, textstart, datastart (all sizes/addresses in bits).
|
||||
opt = struct.unpack_from("<HHIIIIII", d, 20)
|
||||
base = 20 + opthdr
|
||||
secs = []
|
||||
for i in range(nscns):
|
||||
off = base + i * 40
|
||||
if off + 40 > len(d):
|
||||
raise CoffError("%s: section header %d past EOF" % (path, i))
|
||||
raw = d[off:off + 40]
|
||||
name = raw[:8].rstrip(b"\0").decode("latin1")
|
||||
(paddr, vaddr, size, scnptr, relptr, lnnoptr, nreloc, nlnno,
|
||||
sflags) = struct.unpack_from("<IIIIIIHHI", d, off + 8)
|
||||
relocs = []
|
||||
for r in range(nreloc):
|
||||
ro = relptr + r * 10
|
||||
if ro + 10 > len(d):
|
||||
raise CoffError("%s: relocation %d past EOF" % (path, r))
|
||||
raddr, symidx, rtype = struct.unpack_from("<IIH", d, ro)
|
||||
relocs.append((raddr, symidx, rtype))
|
||||
secs.append(dict(index=i + 1, name=name, paddr=paddr, vaddr=vaddr,
|
||||
size=size, scnptr=scnptr, relptr=relptr,
|
||||
lnnoptr=lnnoptr, nreloc=nreloc, nlnno=nlnno,
|
||||
flags=sflags, relocs=relocs, raw=raw))
|
||||
syms = []
|
||||
i = 0
|
||||
while i < nsyms:
|
||||
off = symptr + i * 18
|
||||
if off + 18 > len(d):
|
||||
raise CoffError("%s: symbol %d past EOF" % (path, i))
|
||||
e = d[off:off + 18]
|
||||
name = e[:8].rstrip(b"\0").decode("latin1", "replace")
|
||||
val, secno, stype, sclass, naux = struct.unpack_from("<IHhBB", e, 8)
|
||||
aux = d[off + 18:off + 18 + naux * 18]
|
||||
syms.append(dict(index=i, name=name, value=val, secno=secno,
|
||||
type=stype, sclass=sclass, naux=naux, aux=aux))
|
||||
i += 1 + naux
|
||||
return dict(path=path, size=len(d), magic=magic, nscns=nscns,
|
||||
timdat=timdat, symptr=symptr, nsyms=nsyms, opthdr=opthdr,
|
||||
flags=flags, opt=opt, sections=secs, symbols=syms, data=d)
|
||||
|
||||
|
||||
def summary(path):
|
||||
c = parse(path)
|
||||
print("== %s (%d bytes)" % (path, c["size"]))
|
||||
print(" file hdr: magic=%#06x nscns=%d symptr=%#x nsyms=%d "
|
||||
"opthdr=%d flags=%#06x"
|
||||
% (c["magic"], c["nscns"], c["symptr"], c["nsyms"], c["opthdr"],
|
||||
c["flags"]))
|
||||
if c["opt"]:
|
||||
magic, vstamp, tsize, dsize, bsize, entry, tstart, dstart = c["opt"]
|
||||
print(" optional: magic=%#06x vstamp=%#06x text=%#x bits "
|
||||
"data=%#x bits bss=%#x bits entry=%#010x textstart=%#010x "
|
||||
"datastart=%#010x"
|
||||
% (magic, vstamp, tsize, dsize, bsize, entry, tstart, dstart))
|
||||
print(" optional: sizes in bytes text=%d data=%d bss=%d; "
|
||||
"entry in bits=%s"
|
||||
% (tsize // 8, dsize // 8, bsize // 8,
|
||||
"0 (no -e global symbol)" if entry == 0 else hex(entry)))
|
||||
for s in c["sections"]:
|
||||
fl = ",".join(v for k, v in SECTION_FLAGS.items() if s["flags"] & k)
|
||||
print(" sec %d %-8s paddr=%010x vaddr=%010x size=%#x bits (%d B) "
|
||||
"scnptr=%#x nreloc=%d flags=%#x%s"
|
||||
% (s["index"], s["name"], s["paddr"], s["vaddr"], s["size"],
|
||||
s["size"] // 8, s["scnptr"], s["nreloc"], s["flags"],
|
||||
(" [" + fl + "]") if fl else ""))
|
||||
for raddr, symidx, rtype in s["relocs"]:
|
||||
print(" reloc at %#x sym=%d type=%#x %s"
|
||||
% (raddr, symidx, rtype,
|
||||
RELOC_NAMES.get(rtype, "?")))
|
||||
for sym in c["symbols"]:
|
||||
if sym["naux"]:
|
||||
print(" sym[%d] %-10s value=%010x sec=%d class=%d naux=%d"
|
||||
% (sym["index"], sym["name"], sym["value"], sym["secno"],
|
||||
sym["sclass"], sym["naux"]))
|
||||
else:
|
||||
print(" sym[%d] %-10s value=%010x sec=%d class=%d"
|
||||
% (sym["index"], sym["name"], sym["value"], sym["secno"],
|
||||
sym["sclass"]))
|
||||
print()
|
||||
|
||||
|
||||
def section_bytes(c, name):
|
||||
for s in c["sections"]:
|
||||
if s["name"] == name:
|
||||
return s, c["data"][s["scnptr"]:s["scnptr"] + s["size"] // 8]
|
||||
return None, None
|
||||
|
||||
|
||||
def raw(paths):
|
||||
if len(paths) != 2:
|
||||
raise SystemExit("coff.py raw: need exactly two files")
|
||||
a, b = parse(paths[0]), parse(paths[1])
|
||||
for name in (".text", ".data", ".bss"):
|
||||
sa, ba = section_bytes(a, name)
|
||||
sb, bb = section_bytes(b, name)
|
||||
if sa is None or sb is None:
|
||||
continue
|
||||
print("== %s: %d vs %d bytes" % (name, len(ba), len(bb)))
|
||||
n = min(len(ba), len(bb))
|
||||
bad = [i for i in range(n) if ba[i] != bb[i]]
|
||||
print(" differing bytes: %d" % (len(bad) + abs(len(ba) - len(bb))))
|
||||
for i in bad[:24]:
|
||||
print(" %#06x: %02x -> %02x" % (i, ba[i], bb[i]))
|
||||
print()
|
||||
|
||||
|
||||
def manifest(path):
|
||||
c = parse(path)
|
||||
print("COFF=%s" % path)
|
||||
print("SIZE=%d" % c["size"])
|
||||
print("NSECTIONS=%d" % c["nscns"])
|
||||
if c["opt"]:
|
||||
_, _, tsize, dsize, bsize, entry, tstart, dstart = c["opt"]
|
||||
print("ENTRY=%#010x" % entry)
|
||||
print("TEXTSTART=%#010x" % tstart)
|
||||
print("DATASTART=%#010x" % dstart)
|
||||
print("TEXTSIZE_BITS=%d" % tsize)
|
||||
print("DATASIZE_BITS=%d" % dsize)
|
||||
print("BSSSIZE_BITS=%d" % bsize)
|
||||
for s in c["sections"]:
|
||||
key = s["name"].lstrip(".").upper() or ("SEC%d" % s["index"])
|
||||
print("%s_PADDR=%#010x" % (key, s["paddr"]))
|
||||
print("%s_SIZE_BITS=%d" % (key, s["size"]))
|
||||
print("%s_NRELOC=%d" % (key, s["nreloc"]))
|
||||
|
||||
|
||||
def main(argv):
|
||||
if len(argv) < 3:
|
||||
raise SystemExit(__doc__)
|
||||
cmd = argv[1]
|
||||
if cmd == "summary":
|
||||
for p in argv[2:]:
|
||||
summary(p)
|
||||
elif cmd == "raw":
|
||||
raw(argv[2:])
|
||||
elif cmd == "manifest":
|
||||
manifest(argv[2])
|
||||
else:
|
||||
raise SystemExit(__doc__)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv)
|
||||
@@ -0,0 +1,68 @@
|
||||
=== marker.coff hexdump (first 176 bytes) ===
|
||||
00000000: 90 00 03 00 de e0 d4 6a 02 01 00 00 0e 00 00 00 .......j........
|
||||
00000010: 1c 00 03 01 08 01 c7 00 90 02 00 00 40 00 00 00 ............@...
|
||||
00000020: 40 00 00 00 00 00 8c 01 00 00 8c 01 00 00 8d 01 @...............
|
||||
00000030: 2e 74 65 78 74 00 00 00 00 00 8c 01 00 00 8c 01 .text...........
|
||||
00000040: 90 02 00 00 a8 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||
00000050: 00 00 00 00 20 00 00 00 2e 64 61 74 61 00 00 00 .... ....data...
|
||||
00000060: 00 00 8d 01 00 00 8d 01 40 00 00 00 fa 00 00 00 ........@.......
|
||||
00000070: 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 00 ............@...
|
||||
00000080: 2e 62 73 73 00 00 00 00 00 80 8d 01 00 80 8d 01 .bss............
|
||||
00000090: 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 @...............
|
||||
000000a0: 00 00 00 00 80 00 00 00 50 05 40 07 e2 09 00 00 ........P.@.....
|
||||
|
||||
=== marker.coff parsed ===
|
||||
== dwt/loader/build/marker.coff (510 bytes)
|
||||
file hdr: magic=0x0090 nscns=3 symptr=0x102 nsyms=14 opthdr=28 flags=0x0103
|
||||
optional: magic=0x0108 vstamp=0x00c7 text=0x290 bits data=0x40 bits bss=0x40 bits entry=0x018c0000 textstart=0x018c0000 datastart=0x018d0000
|
||||
optional: sizes in bytes text=82 data=8 bss=8; entry in bits=0x18c0000
|
||||
sec 1 .text paddr=00018c0000 vaddr=00018c0000 size=0x290 bits (82 B) scnptr=0xa8 nreloc=0 flags=0x20 [text]
|
||||
sec 2 .data paddr=00018d0000 vaddr=00018d0000 size=0x40 bits (8 B) scnptr=0xfa nreloc=0 flags=0x40 [data]
|
||||
sec 3 .bss paddr=00018d8000 vaddr=00018d8000 size=0x40 bits (8 B) scnptr=0x0 nreloc=0 flags=0x80 [bss]
|
||||
sym[0] .text value=00018c0000 sec=1 class=3 naux=1
|
||||
sym[2] .data value=00018d0000 sec=2 class=3 naux=1
|
||||
sym[4] .bss value=00018d8000 sec=3 class=3 naux=1
|
||||
sym[6] sub value=00018c0280 sec=1 class=2
|
||||
sym[7] _start value=00018c0000 sec=1 class=2
|
||||
sym[8] .text value=00018c0000 sec=1 class=2
|
||||
sym[9] etext value=00018c0290 sec=1 class=2
|
||||
sym[10] .data value=00018d0000 sec=2 class=2
|
||||
sym[11] edata value=00018d0040 sec=2 class=2
|
||||
sym[12] .bss value=00018d8000 sec=3 class=2
|
||||
sym[13] end value=00018d8040 sec=3 class=2
|
||||
|
||||
=== xhello.coff parsed ===
|
||||
== dwt/loader/build/xhello.coff (774 bytes)
|
||||
file hdr: magic=0x0090 nscns=3 symptr=0x22e nsyms=12 opthdr=28 flags=0x0103
|
||||
optional: magic=0x0108 vstamp=0x00c7 text=0xc30 bits data=0x0 bits bss=0x0 bits entry=0x00000000 textstart=0x01840000 datastart=0x00000000
|
||||
optional: sizes in bytes text=390 data=0 bss=0; entry in bits=0 (no -e global symbol)
|
||||
sec 1 .data paddr=0000000000 vaddr=0000000000 size=0x0 bits (0 B) scnptr=0xa8 nreloc=0 flags=0x40 [data]
|
||||
sec 2 .bss paddr=0000000000 vaddr=0000000000 size=0x0 bits (0 B) scnptr=0x0 nreloc=0 flags=0x80 [bss]
|
||||
sec 3 .text paddr=0001840000 vaddr=0001840000 size=0xc30 bits (390 B) scnptr=0xa8 nreloc=0 flags=0x20 [text]
|
||||
sym[0] .text value=0001840000 sec=3 class=3 naux=1
|
||||
sym[2] .data value=0000000000 sec=1 class=3 naux=1
|
||||
sym[4] .bss value=0000000000 sec=2 class=3 naux=1
|
||||
sym[6] .text value=0001840000 sec=3 class=2
|
||||
sym[7] etext value=0001840c30 sec=3 class=2
|
||||
sym[8] .data value=0000000000 sec=1 class=2
|
||||
sym[9] edata value=0000000000 sec=1 class=2
|
||||
sym[10] .bss value=0000000000 sec=2 class=2
|
||||
sym[11] end value=0000000000 sec=2 class=2
|
||||
|
||||
=== marker.obj (assembler output: relocations present) ===
|
||||
== dwt/loader/build/marker.obj (424 bytes)
|
||||
file hdr: magic=0x0090 nscns=3 symptr=0x118 nsyms=8 opthdr=0 flags=0x0100
|
||||
sec 1 .text paddr=0000000000 vaddr=0000000000 size=0x290 bits (82 B) scnptr=0x8c nreloc=5 flags=0x20 [text]
|
||||
reloc at 0x30 sym=65535 type=0x11 R-RELLONG
|
||||
reloc at 0x90 sym=2 type=0x11 R-RELLONG
|
||||
reloc at 0xf0 sym=2 type=0x11 R-RELLONG
|
||||
reloc at 0x150 sym=4 type=0x11 R-RELLONG
|
||||
reloc at 0x1e0 sym=4 type=0x11 R-RELLONG
|
||||
sec 2 .data paddr=0000000000 vaddr=0000000000 size=0x40 bits (8 B) scnptr=0xde nreloc=0 flags=0x40 [data]
|
||||
sec 3 .bss paddr=0000000000 vaddr=0000000000 size=0x40 bits (8 B) scnptr=0x0 nreloc=0 flags=0x80 [bss]
|
||||
sym[0] .text value=0000000000 sec=1 class=3 naux=1
|
||||
sym[2] .data value=0000000000 sec=2 class=3 naux=1
|
||||
sym[4] .bss value=0000000000 sec=3 class=3 naux=1
|
||||
sym[6] sub value=0000000280 sec=1 class=2
|
||||
sym[7] _start value=0000000000 sec=1 class=2
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
=== ELF in the 1987 SDK documentation ===
|
||||
grep -ni elf harness/sdk-scratch/asmguide.txt harness/sdk-scratch/cguide.txt
|
||||
harness/sdk-scratch/cguide.txt:903: • The preprocessor produces self-explanatory error messages. The line
|
||||
harness/sdk-scratch/cguide.txt:1830: ever, the structure or array itself begins at a 16-bit boundary. In the case
|
||||
harness/sdk-scratch/asmguide.txt:2047: A label on a line by itself is a valid statement. It assigns the current value of
|
||||
harness/sdk-scratch/asmguide.txt:2058: When a label appears on a line by itself, it usually points to the instruction on
|
||||
harness/sdk-scratch/asmguide.txt:4828: listing page. The .title directive itself is not printed, but the line counter is
|
||||
harness/sdk-scratch/asmguide.txt:9927: TMS34010 simulator; the messages are self explanatory.
|
||||
harness/sdk-scratch/asmguide.txt:10244: and then executes the contents of buffer 1. A buffer can even reference itself
|
||||
harness/sdk-scratch/asmguide.txt:11230:Syntax elF
|
||||
harness/sdk-scratch/asmguide.txt:14123: example, if bytes 18 and 19 are set to 0003h, then F-RELFLG and F-EXEC
|
||||
harness/sdk-scratch/asmguide.txt:14129: F-RELFLG 0001h Relocation information was stripped from
|
||||
|
||||
The SDK's documented object formats (asmguide §1.2 / §10):
|
||||
569: The object format converter converts a COFF object file into Intel
|
||||
|
||||
No ELF writer or ELF reader exists in the toolchain: COFF is the only linker output.
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
@@ -0,0 +1,88 @@
|
||||
Warning: -video none doesn't make much sense without -seconds_to_run
|
||||
vt1200: screen_update#1 frame=0 clip_y=0..0 screen=1280x901
|
||||
LOADER: payload dwt/loader/build/loader.bin (1220 B) -> bit 01880000
|
||||
LOADER: COFF dwt/loader/build/marker.coff (510 B) -> bit 01900000
|
||||
LOADER: file magic=0090 nscns=3 opthdr=28 optmagic=0108 entry=018C0000 textstart=018C0000
|
||||
LOADER: sec .text paddr=018C0000 size=656 bits (82 B) scnptr=0xa8 flags=0x20
|
||||
LOADER: sec .data paddr=018D0000 size=64 bits (8 B) scnptr=0xfa flags=0x40
|
||||
LOADER: sec .bss paddr=018D8000 size=64 bits (8 B) scnptr=0 flags=0x80
|
||||
vt1200: screen_update#2 frame=0 clip_y=1..900 screen=1280x901
|
||||
vt1200: scanline#1 line=1 enabled=1
|
||||
vt1200: guard#1 frame=0 dump_frame=-1 dump_ram=-1
|
||||
vt1200: screen_update#3 frame=1 clip_y=0..0 screen=1280x901
|
||||
vt1200: scanline#2 line=0 enabled=1
|
||||
vt1200: screen_update#4 frame=1 clip_y=1..1 screen=1280x901
|
||||
vt1200: scanline#3 line=1 enabled=1
|
||||
vt1200: scanline#4 line=2 enabled=1
|
||||
LOADER: loader poked 610 words, readback 0 bad at 01880000
|
||||
LOADER: COFF poked 255 words, readback 0 bad at 01900000
|
||||
LOADER: pre-filled .bss 018D8000..018D8040 with A5A5
|
||||
LOADER: descriptor @01882C00 magic=4C44/5231 buf=01900000 len=510 mode=1
|
||||
LOADER: will resume at 3F579970 after create_process
|
||||
LOADER: frame 2500: entered loader at 01880000 (caller SP=007F5290)
|
||||
LOADER: marker counter 1431655765 -> 5 (child running)
|
||||
LOADER: marker counter 5 -> 11 (child running)
|
||||
LOADER: marker counter 11 -> 16 (child running)
|
||||
LOADER: marker counter 16 -> 21 (child running)
|
||||
LOADER: marker counter 21 -> 26 (child running)
|
||||
LOADER: marker counter 26 -> 31 (child running)
|
||||
LOADER: marker counter 31 -> 36 (child running)
|
||||
LOADER: marker counter 36 -> 41 (child running)
|
||||
LOADER: marker counter 41 -> 47 (child running)
|
||||
LOADER: marker counter 47 -> 52 (child running)
|
||||
LOADER: marker counter 52 -> 57 (child running)
|
||||
LOADER: marker counter 57 -> 62 (child running)
|
||||
LOADER: marker counter 62 -> 67 (child running)
|
||||
LOADER: marker counter 67 -> 72 (child running)
|
||||
LOADER: marker counter 72 -> 77 (child running)
|
||||
LOADER: marker counter 77 -> 83 (child running)
|
||||
LOADER: marker counter 83 -> 88 (child running)
|
||||
LOADER: marker counter 88 -> 93 (child running)
|
||||
LOADER: marker counter 93 -> 98 (child running)
|
||||
LOADER: marker counter 98 -> 103 (child running)
|
||||
LOADER: marker counter 103 -> 108 (child running)
|
||||
LOADER: marker counter 108 -> 114 (child running)
|
||||
LOADER: marker counter 114 -> 119 (child running)
|
||||
LOADER: marker counter 119 -> 124 (child running)
|
||||
LOADER: marker counter 124 -> 129 (child running)
|
||||
LOADER: marker counter 129 -> 134 (child running)
|
||||
LOADER: marker counter 134 -> 139 (child running)
|
||||
LOADER: marker counter 139 -> 145 (child running)
|
||||
LOADER: marker counter 145 -> 150 (child running)
|
||||
LOADER: marker counter 150 -> 155 (child running)
|
||||
LOADER: marker counter 155 -> 160 (child running)
|
||||
LOADER: marker counter 160 -> 165 (child running)
|
||||
LOADER: marker counter 165 -> 170 (child running)
|
||||
LOADER: marker counter 170 -> 176 (child running)
|
||||
LOADER: marker counter 176 -> 181 (child running)
|
||||
LOADER: marker counter 181 -> 186 (child running)
|
||||
LOADER: marker counter 186 -> 191 (child running)
|
||||
LOADER: marker counter 191 -> 196 (child running)
|
||||
LOADER: marker counter 196 -> 201 (child running)
|
||||
LOADER: marker counter 201 -> 207 (child running)
|
||||
LOADER: marker counter 207 -> 212 (child running)
|
||||
LOADER: marker counter 212 -> 217 (child running)
|
||||
LOADER: marker counter 217 -> 222 (child running)
|
||||
LOADER: marker counter 222 -> 227 (child running)
|
||||
LOADER: marker counter 227 -> 232 (child running)
|
||||
LOADER: marker counter 232 -> 238 (child running)
|
||||
LOADER: marker counter 238 -> 243 (child running)
|
||||
LOADER: marker counter 243 -> 248 (child running)
|
||||
LOADER: marker counter 248 -> 253 (child running)
|
||||
LOADER: marker counter 253 -> 258 (child running)
|
||||
LOADER: marker counter 258 -> 263 (child running)
|
||||
LOADER: marker counter 263 -> 269 (child running)
|
||||
LOADER: marker counter 269 -> 274 (child running)
|
||||
LOADER: marker counter 274 -> 279 (child running)
|
||||
LOADER: marker counter 279 -> 284 (child running)
|
||||
LOADER: marker counter 284 -> 289 (child running)
|
||||
LOADER: marker counter 289 -> 294 (child running)
|
||||
LOADER: marker counter 294 -> 299 (child running)
|
||||
LOADER: marker counter 299 -> 305 (child running)
|
||||
LOADER: marker counter 305 -> 310 (child running)
|
||||
LOADER: result status=0 (OK) entry=018C0000 text=018C0000/656 bits data=018D0000/64 bits bss=018D8000/64 bits relocs=0 pcb=003FFBD0 nscns=3 len=510
|
||||
LOADER: placed .text at 018C0000: 82 bytes, 0 differing
|
||||
LOADER: placed .data at 018D0000: 8 bytes, 0 differing
|
||||
LOADER: marker app: start=018C0000 data=DEADBEEF data2=12345678 bss=00000000 count=310
|
||||
LOADER: PC at inspection = 018C0260
|
||||
Average speed: 332.37% (35 seconds)
|
||||
@@ -0,0 +1,128 @@
|
||||
Warning: -video none doesn't make much sense without -seconds_to_run
|
||||
vt1200: screen_update#1 frame=0 clip_y=0..0 screen=1280x901
|
||||
LOADER: payload dwt/loader/build/loader.bin (1220 B) -> bit 01880000
|
||||
LOADER: COFF dwt/loader/build/marker.coff (510 B) -> bit 01900000
|
||||
LOADER: file magic=0090 nscns=3 opthdr=28 optmagic=0108 entry=018C0000 textstart=018C0000
|
||||
LOADER: sec .text paddr=018C0000 size=656 bits (82 B) scnptr=0xa8 flags=0x20
|
||||
LOADER: sec .data paddr=018D0000 size=64 bits (8 B) scnptr=0xfa flags=0x40
|
||||
LOADER: sec .bss paddr=018D8000 size=64 bits (8 B) scnptr=0 flags=0x80
|
||||
vt1200: screen_update#2 frame=0 clip_y=1..900 screen=1280x901
|
||||
vt1200: scanline#1 line=1 enabled=1
|
||||
vt1200: guard#1 frame=0 dump_frame=-1 dump_ram=-1
|
||||
vt1200: screen_update#3 frame=1 clip_y=0..0 screen=1280x901
|
||||
vt1200: scanline#2 line=0 enabled=1
|
||||
vt1200: screen_update#4 frame=1 clip_y=1..1 screen=1280x901
|
||||
vt1200: scanline#3 line=1 enabled=1
|
||||
vt1200: scanline#4 line=2 enabled=1
|
||||
LOADER: loader poked 610 words, readback 0 bad at 01880000
|
||||
LOADER: COFF poked 255 words, readback 0 bad at 01900000
|
||||
LOADER: pre-filled .bss 018D8000..018D8040 with A5A5
|
||||
LOADER: descriptor @01882C00 magic=4C44/5231 buf=01900000 len=510 mode=1
|
||||
LOADER: will resume at 3F579970 after create_process
|
||||
LOADER: frame 2500: entered loader at 01880000 (caller SP=007F5290)
|
||||
LOADER: marker counter 1431655765 -> 5 (child running)
|
||||
LOADER: marker counter 5 -> 11 (child running)
|
||||
LOADER: marker counter 11 -> 16 (child running)
|
||||
LOADER: marker counter 16 -> 21 (child running)
|
||||
LOADER: marker counter 21 -> 26 (child running)
|
||||
LOADER: marker counter 26 -> 31 (child running)
|
||||
LOADER: marker counter 31 -> 36 (child running)
|
||||
LOADER: marker counter 36 -> 41 (child running)
|
||||
LOADER: marker counter 41 -> 47 (child running)
|
||||
LOADER: marker counter 47 -> 52 (child running)
|
||||
LOADER: marker counter 52 -> 57 (child running)
|
||||
LOADER: marker counter 57 -> 62 (child running)
|
||||
LOADER: marker counter 62 -> 67 (child running)
|
||||
LOADER: marker counter 67 -> 72 (child running)
|
||||
LOADER: marker counter 72 -> 77 (child running)
|
||||
LOADER: marker counter 77 -> 83 (child running)
|
||||
LOADER: marker counter 83 -> 88 (child running)
|
||||
LOADER: marker counter 88 -> 93 (child running)
|
||||
LOADER: marker counter 93 -> 98 (child running)
|
||||
LOADER: marker counter 98 -> 103 (child running)
|
||||
LOADER: marker counter 103 -> 108 (child running)
|
||||
LOADER: marker counter 108 -> 114 (child running)
|
||||
LOADER: marker counter 114 -> 119 (child running)
|
||||
LOADER: marker counter 119 -> 124 (child running)
|
||||
LOADER: marker counter 124 -> 129 (child running)
|
||||
LOADER: marker counter 129 -> 134 (child running)
|
||||
LOADER: marker counter 134 -> 139 (child running)
|
||||
LOADER: marker counter 139 -> 145 (child running)
|
||||
LOADER: marker counter 145 -> 150 (child running)
|
||||
LOADER: marker counter 150 -> 155 (child running)
|
||||
LOADER: marker counter 155 -> 160 (child running)
|
||||
LOADER: marker counter 160 -> 165 (child running)
|
||||
LOADER: marker counter 165 -> 170 (child running)
|
||||
LOADER: marker counter 170 -> 176 (child running)
|
||||
LOADER: marker counter 176 -> 181 (child running)
|
||||
LOADER: marker counter 181 -> 186 (child running)
|
||||
LOADER: marker counter 186 -> 191 (child running)
|
||||
LOADER: marker counter 191 -> 196 (child running)
|
||||
LOADER: marker counter 196 -> 201 (child running)
|
||||
LOADER: marker counter 201 -> 207 (child running)
|
||||
LOADER: marker counter 207 -> 212 (child running)
|
||||
LOADER: marker counter 212 -> 217 (child running)
|
||||
LOADER: marker counter 217 -> 222 (child running)
|
||||
LOADER: marker counter 222 -> 227 (child running)
|
||||
LOADER: marker counter 227 -> 232 (child running)
|
||||
LOADER: marker counter 232 -> 238 (child running)
|
||||
LOADER: marker counter 238 -> 243 (child running)
|
||||
LOADER: marker counter 243 -> 248 (child running)
|
||||
LOADER: marker counter 248 -> 253 (child running)
|
||||
LOADER: marker counter 253 -> 258 (child running)
|
||||
LOADER: marker counter 258 -> 263 (child running)
|
||||
LOADER: marker counter 263 -> 269 (child running)
|
||||
LOADER: marker counter 269 -> 274 (child running)
|
||||
LOADER: marker counter 274 -> 279 (child running)
|
||||
LOADER: marker counter 279 -> 284 (child running)
|
||||
LOADER: marker counter 284 -> 289 (child running)
|
||||
LOADER: marker counter 289 -> 294 (child running)
|
||||
LOADER: marker counter 294 -> 299 (child running)
|
||||
LOADER: marker counter 299 -> 305 (child running)
|
||||
LOADER: marker counter 305 -> 310 (child running)
|
||||
LOADER: marker counter 310 -> 315 (child running)
|
||||
LOADER: marker counter 315 -> 320 (child running)
|
||||
LOADER: marker counter 320 -> 325 (child running)
|
||||
LOADER: marker counter 325 -> 330 (child running)
|
||||
LOADER: marker counter 330 -> 336 (child running)
|
||||
LOADER: marker counter 336 -> 341 (child running)
|
||||
LOADER: marker counter 341 -> 346 (child running)
|
||||
LOADER: marker counter 346 -> 351 (child running)
|
||||
LOADER: marker counter 351 -> 356 (child running)
|
||||
LOADER: marker counter 356 -> 361 (child running)
|
||||
LOADER: marker counter 361 -> 367 (child running)
|
||||
LOADER: marker counter 367 -> 372 (child running)
|
||||
LOADER: marker counter 372 -> 377 (child running)
|
||||
LOADER: marker counter 377 -> 382 (child running)
|
||||
LOADER: marker counter 382 -> 387 (child running)
|
||||
LOADER: marker counter 387 -> 392 (child running)
|
||||
LOADER: marker counter 392 -> 398 (child running)
|
||||
LOADER: marker counter 398 -> 403 (child running)
|
||||
LOADER: marker counter 403 -> 408 (child running)
|
||||
LOADER: marker counter 408 -> 413 (child running)
|
||||
LOADER: marker counter 413 -> 418 (child running)
|
||||
LOADER: marker counter 418 -> 423 (child running)
|
||||
LOADER: marker counter 423 -> 428 (child running)
|
||||
LOADER: marker counter 428 -> 434 (child running)
|
||||
LOADER: marker counter 434 -> 439 (child running)
|
||||
LOADER: marker counter 439 -> 444 (child running)
|
||||
LOADER: marker counter 444 -> 449 (child running)
|
||||
LOADER: marker counter 449 -> 454 (child running)
|
||||
LOADER: marker counter 454 -> 459 (child running)
|
||||
LOADER: marker counter 459 -> 465 (child running)
|
||||
LOADER: marker counter 465 -> 470 (child running)
|
||||
LOADER: marker counter 470 -> 475 (child running)
|
||||
LOADER: marker counter 475 -> 480 (child running)
|
||||
LOADER: marker counter 480 -> 485 (child running)
|
||||
LOADER: marker counter 485 -> 490 (child running)
|
||||
LOADER: marker counter 490 -> 495 (child running)
|
||||
LOADER: marker counter 495 -> 501 (child running)
|
||||
LOADER: marker counter 501 -> 506 (child running)
|
||||
LOADER: marker counter 506 -> 511 (child running)
|
||||
LOADER: marker counter 511 -> 516 (child running)
|
||||
LOADER: result status=0 (OK) entry=018C0000 text=018C0000/656 bits data=018D0000/64 bits bss=018D8000/64 bits relocs=0 pcb=003FFBD0 nscns=3 len=510
|
||||
LOADER: placed .text at 018C0000: 82 bytes, 0 differing
|
||||
LOADER: placed .data at 018D0000: 8 bytes, 0 differing
|
||||
LOADER: marker app: start=018C0000 data=DEADBEEF data2=12345678 bss=00000000 count=516
|
||||
LOADER: PC at inspection = 018C0260
|
||||
Average speed: 325.97% (36 seconds)
|
||||
@@ -0,0 +1,128 @@
|
||||
Warning: -video none doesn't make much sense without -seconds_to_run
|
||||
vt1200: screen_update#1 frame=0 clip_y=0..0 screen=1280x901
|
||||
LOADER: payload dwt/loader/build/loader.bin (1220 B) -> bit 01880000
|
||||
LOADER: COFF dwt/loader/build/marker.coff (510 B) -> bit 01900000
|
||||
LOADER: file magic=0090 nscns=3 opthdr=28 optmagic=0108 entry=018C0000 textstart=018C0000
|
||||
LOADER: sec .text paddr=018C0000 size=656 bits (82 B) scnptr=0xa8 flags=0x20
|
||||
LOADER: sec .data paddr=018D0000 size=64 bits (8 B) scnptr=0xfa flags=0x40
|
||||
LOADER: sec .bss paddr=018D8000 size=64 bits (8 B) scnptr=0 flags=0x80
|
||||
vt1200: screen_update#2 frame=0 clip_y=1..900 screen=1280x901
|
||||
vt1200: scanline#1 line=1 enabled=1
|
||||
vt1200: guard#1 frame=0 dump_frame=-1 dump_ram=-1
|
||||
vt1200: screen_update#3 frame=1 clip_y=0..0 screen=1280x901
|
||||
vt1200: scanline#2 line=0 enabled=1
|
||||
vt1200: screen_update#4 frame=1 clip_y=1..1 screen=1280x901
|
||||
vt1200: scanline#3 line=1 enabled=1
|
||||
vt1200: scanline#4 line=2 enabled=1
|
||||
LOADER: loader poked 610 words, readback 0 bad at 01880000
|
||||
LOADER: COFF poked 255 words, readback 0 bad at 01900000
|
||||
LOADER: pre-filled .bss 018D8000..018D8040 with A5A5
|
||||
LOADER: descriptor @01882C00 magic=4C44/5231 buf=01900000 len=510 mode=0
|
||||
LOADER: will resume at 3F579970 after create_process
|
||||
LOADER: frame 2500: entered loader at 01880000 (caller SP=007F52B0)
|
||||
LOADER: marker counter 1431655765 -> 5 (child running)
|
||||
LOADER: marker counter 5 -> 11 (child running)
|
||||
LOADER: marker counter 11 -> 16 (child running)
|
||||
LOADER: marker counter 16 -> 21 (child running)
|
||||
LOADER: marker counter 21 -> 26 (child running)
|
||||
LOADER: marker counter 26 -> 31 (child running)
|
||||
LOADER: marker counter 31 -> 36 (child running)
|
||||
LOADER: marker counter 36 -> 41 (child running)
|
||||
LOADER: marker counter 41 -> 47 (child running)
|
||||
LOADER: marker counter 47 -> 52 (child running)
|
||||
LOADER: marker counter 52 -> 57 (child running)
|
||||
LOADER: marker counter 57 -> 62 (child running)
|
||||
LOADER: marker counter 62 -> 67 (child running)
|
||||
LOADER: marker counter 67 -> 72 (child running)
|
||||
LOADER: marker counter 72 -> 77 (child running)
|
||||
LOADER: marker counter 77 -> 83 (child running)
|
||||
LOADER: marker counter 83 -> 88 (child running)
|
||||
LOADER: marker counter 88 -> 93 (child running)
|
||||
LOADER: marker counter 93 -> 98 (child running)
|
||||
LOADER: marker counter 98 -> 103 (child running)
|
||||
LOADER: marker counter 103 -> 108 (child running)
|
||||
LOADER: marker counter 108 -> 114 (child running)
|
||||
LOADER: marker counter 114 -> 119 (child running)
|
||||
LOADER: marker counter 119 -> 124 (child running)
|
||||
LOADER: marker counter 124 -> 129 (child running)
|
||||
LOADER: marker counter 129 -> 134 (child running)
|
||||
LOADER: marker counter 134 -> 139 (child running)
|
||||
LOADER: marker counter 139 -> 145 (child running)
|
||||
LOADER: marker counter 145 -> 150 (child running)
|
||||
LOADER: marker counter 150 -> 155 (child running)
|
||||
LOADER: marker counter 155 -> 160 (child running)
|
||||
LOADER: marker counter 160 -> 165 (child running)
|
||||
LOADER: marker counter 165 -> 170 (child running)
|
||||
LOADER: marker counter 170 -> 176 (child running)
|
||||
LOADER: marker counter 176 -> 181 (child running)
|
||||
LOADER: marker counter 181 -> 186 (child running)
|
||||
LOADER: marker counter 186 -> 191 (child running)
|
||||
LOADER: marker counter 191 -> 196 (child running)
|
||||
LOADER: marker counter 196 -> 201 (child running)
|
||||
LOADER: marker counter 201 -> 207 (child running)
|
||||
LOADER: marker counter 207 -> 212 (child running)
|
||||
LOADER: marker counter 212 -> 217 (child running)
|
||||
LOADER: marker counter 217 -> 222 (child running)
|
||||
LOADER: marker counter 222 -> 227 (child running)
|
||||
LOADER: marker counter 227 -> 232 (child running)
|
||||
LOADER: marker counter 232 -> 238 (child running)
|
||||
LOADER: marker counter 238 -> 243 (child running)
|
||||
LOADER: marker counter 243 -> 248 (child running)
|
||||
LOADER: marker counter 248 -> 253 (child running)
|
||||
LOADER: marker counter 253 -> 258 (child running)
|
||||
LOADER: marker counter 258 -> 263 (child running)
|
||||
LOADER: marker counter 263 -> 269 (child running)
|
||||
LOADER: marker counter 269 -> 274 (child running)
|
||||
LOADER: marker counter 274 -> 279 (child running)
|
||||
LOADER: marker counter 279 -> 284 (child running)
|
||||
LOADER: marker counter 284 -> 289 (child running)
|
||||
LOADER: marker counter 289 -> 294 (child running)
|
||||
LOADER: marker counter 294 -> 299 (child running)
|
||||
LOADER: marker counter 299 -> 305 (child running)
|
||||
LOADER: marker counter 305 -> 310 (child running)
|
||||
LOADER: marker counter 310 -> 315 (child running)
|
||||
LOADER: marker counter 315 -> 320 (child running)
|
||||
LOADER: marker counter 320 -> 325 (child running)
|
||||
LOADER: marker counter 325 -> 330 (child running)
|
||||
LOADER: marker counter 330 -> 336 (child running)
|
||||
LOADER: marker counter 336 -> 341 (child running)
|
||||
LOADER: marker counter 341 -> 346 (child running)
|
||||
LOADER: marker counter 346 -> 351 (child running)
|
||||
LOADER: marker counter 351 -> 356 (child running)
|
||||
LOADER: marker counter 356 -> 361 (child running)
|
||||
LOADER: marker counter 361 -> 367 (child running)
|
||||
LOADER: marker counter 367 -> 372 (child running)
|
||||
LOADER: marker counter 372 -> 377 (child running)
|
||||
LOADER: marker counter 377 -> 382 (child running)
|
||||
LOADER: marker counter 382 -> 387 (child running)
|
||||
LOADER: marker counter 387 -> 392 (child running)
|
||||
LOADER: marker counter 392 -> 398 (child running)
|
||||
LOADER: marker counter 398 -> 403 (child running)
|
||||
LOADER: marker counter 403 -> 408 (child running)
|
||||
LOADER: marker counter 408 -> 413 (child running)
|
||||
LOADER: marker counter 413 -> 418 (child running)
|
||||
LOADER: marker counter 418 -> 423 (child running)
|
||||
LOADER: marker counter 423 -> 428 (child running)
|
||||
LOADER: marker counter 428 -> 434 (child running)
|
||||
LOADER: marker counter 434 -> 439 (child running)
|
||||
LOADER: marker counter 439 -> 444 (child running)
|
||||
LOADER: marker counter 444 -> 449 (child running)
|
||||
LOADER: marker counter 449 -> 454 (child running)
|
||||
LOADER: marker counter 454 -> 459 (child running)
|
||||
LOADER: marker counter 459 -> 465 (child running)
|
||||
LOADER: marker counter 465 -> 470 (child running)
|
||||
LOADER: marker counter 470 -> 475 (child running)
|
||||
LOADER: marker counter 475 -> 480 (child running)
|
||||
LOADER: marker counter 480 -> 485 (child running)
|
||||
LOADER: marker counter 485 -> 490 (child running)
|
||||
LOADER: marker counter 490 -> 495 (child running)
|
||||
LOADER: marker counter 495 -> 501 (child running)
|
||||
LOADER: marker counter 501 -> 506 (child running)
|
||||
LOADER: marker counter 506 -> 511 (child running)
|
||||
LOADER: marker counter 511 -> 516 (child running)
|
||||
LOADER: result status=0 (OK) entry=018C0000 text=018C0000/656 bits data=018D0000/64 bits bss=018D8000/64 bits relocs=0 pcb=003FFBD0 nscns=3 len=510
|
||||
LOADER: placed .text at 018C0000: 82 bytes, 0 differing
|
||||
LOADER: placed .data at 018D0000: 8 bytes, 0 differing
|
||||
LOADER: marker app: start=018C0000 data=DEADBEEF data2=12345678 bss=00000000 count=516
|
||||
LOADER: PC at inspection = 018C0260
|
||||
Average speed: 333.33% (36 seconds)
|
||||
@@ -0,0 +1,104 @@
|
||||
== /home/arti/code/k-space/vt1200/dwt/loader/build/rela.obj (342 bytes)
|
||||
file hdr: magic=0x0090 nscns=3 symptr=0xb4 nsyms=9 opthdr=0 flags=0x0100
|
||||
sec 1 .text paddr=0000000000 vaddr=0000000000 size=0xa0 bits (20 B) scnptr=0x8c nreloc=2 flags=0x20 [text]
|
||||
reloc at 0x10 sym=8 type=0x11 R-RELLONG
|
||||
reloc at 0x70 sym=7 type=0x11 R-RELLONG
|
||||
sec 2 .data paddr=0000000000 vaddr=0000000000 size=0x0 bits (0 B) scnptr=0xa0 nreloc=0 flags=0x40 [data]
|
||||
sec 3 .bss paddr=0000000000 vaddr=0000000000 size=0x0 bits (0 B) scnptr=0x0 nreloc=0 flags=0x80 [bss]
|
||||
sym[0] .text value=0000000000 sec=1 class=3 naux=1
|
||||
sym[2] .data value=0000000000 sec=2 class=3 naux=1
|
||||
sym[4] .bss value=0000000000 sec=3 class=3 naux=1
|
||||
sym[6] _start value=0000000000 sec=1 class=2
|
||||
sym[7] ext_func value=0000000000 sec=0 class=2
|
||||
sym[8] ext_data value=0000000000 sec=0 class=2
|
||||
|
||||
== /home/arti/code/k-space/vt1200/dwt/loader/build/relb.obj (290 bytes)
|
||||
file hdr: magic=0x0090 nscns=3 symptr=0x92 nsyms=8 opthdr=0 flags=0x0100
|
||||
sec 1 .text paddr=0000000000 vaddr=0000000000 size=0x10 bits (2 B) scnptr=0x8c nreloc=0 flags=0x20 [text]
|
||||
sec 2 .data paddr=0000000000 vaddr=0000000000 size=0x20 bits (4 B) scnptr=0x8e nreloc=0 flags=0x40 [data]
|
||||
sec 3 .bss paddr=0000000000 vaddr=0000000000 size=0x0 bits (0 B) scnptr=0x0 nreloc=0 flags=0x80 [bss]
|
||||
sym[0] .text value=0000000000 sec=1 class=3 naux=1
|
||||
sym[2] .data value=0000000000 sec=2 class=3 naux=1
|
||||
sym[4] .bss value=0000000000 sec=3 class=3 naux=1
|
||||
sym[6] ext_func value=0000000000 sec=1 class=2
|
||||
sym[7] ext_data value=0000000000 sec=2 class=2
|
||||
|
||||
== /home/arti/code/k-space/vt1200/dwt/loader/build/relabs.out (572 bytes)
|
||||
file hdr: magic=0x0090 nscns=3 symptr=0xc2 nsyms=21 opthdr=28 flags=0x0103
|
||||
optional: magic=0x0108 vstamp=0x00c7 text=0xb0 bits data=0x20 bits bss=0x0 bits entry=0x018c0000 textstart=0x018c0000 datastart=0x018d0000
|
||||
optional: sizes in bytes text=22 data=4 bss=0; entry in bits=0x18c0000
|
||||
sec 1 .text paddr=00018c0000 vaddr=00018c0000 size=0xb0 bits (22 B) scnptr=0xa8 nreloc=0 flags=0x20 [text]
|
||||
sec 2 .data paddr=00018d0000 vaddr=00018d0000 size=0x20 bits (4 B) scnptr=0xbe nreloc=0 flags=0x40 [data]
|
||||
sec 3 .bss paddr=00018d8000 vaddr=00018d8000 size=0x0 bits (0 B) scnptr=0x0 nreloc=0 flags=0x80 [bss]
|
||||
sym[0] .text value=00018c0000 sec=1 class=3 naux=1
|
||||
sym[2] .data value=00018d0000 sec=2 class=3 naux=1
|
||||
sym[4] .bss value=00018d8000 sec=3 class=3 naux=1
|
||||
sym[6] .text value=00018c00a0 sec=1 class=3 naux=1
|
||||
sym[8] .data value=00018d0000 sec=2 class=3 naux=1
|
||||
sym[10] .bss value=00018d8000 sec=3 class=3 naux=1
|
||||
sym[12] _start value=00018c0000 sec=1 class=2
|
||||
sym[13] ext_func value=00018c00a0 sec=1 class=2
|
||||
sym[14] ext_data value=00018d0000 sec=2 class=2
|
||||
sym[15] .text value=00018c0000 sec=1 class=2
|
||||
sym[16] etext value=00018c00b0 sec=1 class=2
|
||||
sym[17] .data value=00018d0000 sec=2 class=2
|
||||
sym[18] edata value=00018d0020 sec=2 class=2
|
||||
sym[19] .bss value=00018d8000 sec=3 class=2
|
||||
sym[20] end value=00018d8000 sec=3 class=2
|
||||
|
||||
== /home/arti/code/k-space/vt1200/dwt/loader/build/relabs2.out (572 bytes)
|
||||
file hdr: magic=0x0090 nscns=3 symptr=0xc2 nsyms=21 opthdr=28 flags=0x0103
|
||||
optional: magic=0x0108 vstamp=0x00c7 text=0xb0 bits data=0x20 bits bss=0x0 bits entry=0x018e0000 textstart=0x018e0000 datastart=0x018f0000
|
||||
optional: sizes in bytes text=22 data=4 bss=0; entry in bits=0x18e0000
|
||||
sec 1 .text paddr=00018e0000 vaddr=00018e0000 size=0xb0 bits (22 B) scnptr=0xa8 nreloc=0 flags=0x20 [text]
|
||||
sec 2 .data paddr=00018f0000 vaddr=00018f0000 size=0x20 bits (4 B) scnptr=0xbe nreloc=0 flags=0x40 [data]
|
||||
sec 3 .bss paddr=00018f8000 vaddr=00018f8000 size=0x0 bits (0 B) scnptr=0x0 nreloc=0 flags=0x80 [bss]
|
||||
sym[0] .text value=00018e0000 sec=1 class=3 naux=1
|
||||
sym[2] .data value=00018f0000 sec=2 class=3 naux=1
|
||||
sym[4] .bss value=00018f8000 sec=3 class=3 naux=1
|
||||
sym[6] .text value=00018e00a0 sec=1 class=3 naux=1
|
||||
sym[8] .data value=00018f0000 sec=2 class=3 naux=1
|
||||
sym[10] .bss value=00018f8000 sec=3 class=3 naux=1
|
||||
sym[12] _start value=00018e0000 sec=1 class=2
|
||||
sym[13] ext_func value=00018e00a0 sec=1 class=2
|
||||
sym[14] ext_data value=00018f0000 sec=2 class=2
|
||||
sym[15] .text value=00018e0000 sec=1 class=2
|
||||
sym[16] etext value=00018e00b0 sec=1 class=2
|
||||
sym[17] .data value=00018f0000 sec=2 class=2
|
||||
sym[18] edata value=00018f0020 sec=2 class=2
|
||||
sym[19] .bss value=00018f8000 sec=3 class=2
|
||||
sym[20] end value=00018f8000 sec=3 class=2
|
||||
|
||||
== /home/arti/code/k-space/vt1200/dwt/loader/build/reloc.out (572 bytes)
|
||||
file hdr: magic=0x0090 nscns=3 symptr=0xc2 nsyms=21 opthdr=28 flags=0x0103
|
||||
optional: magic=0x0108 vstamp=0x00c7 text=0xb0 bits data=0x20 bits bss=0x0 bits entry=0x00000000 textstart=0x00000000 datastart=0x000000b0
|
||||
optional: sizes in bytes text=22 data=4 bss=0; entry in bits=0 (no -e global symbol)
|
||||
sec 1 .text paddr=0000000000 vaddr=0000000000 size=0xb0 bits (22 B) scnptr=0xa8 nreloc=0 flags=0x20 [text]
|
||||
sec 2 .data paddr=00000000b0 vaddr=00000000b0 size=0x20 bits (4 B) scnptr=0xbe nreloc=0 flags=0x40 [data]
|
||||
sec 3 .bss paddr=00000000d0 vaddr=00000000d0 size=0x0 bits (0 B) scnptr=0x0 nreloc=0 flags=0x80 [bss]
|
||||
sym[0] .text value=0000000000 sec=1 class=3 naux=1
|
||||
sym[2] .data value=00000000b0 sec=2 class=3 naux=1
|
||||
sym[4] .bss value=00000000d0 sec=3 class=3 naux=1
|
||||
sym[6] .text value=00000000a0 sec=1 class=3 naux=1
|
||||
sym[8] .data value=00000000b0 sec=2 class=3 naux=1
|
||||
sym[10] .bss value=00000000d0 sec=3 class=3 naux=1
|
||||
sym[12] _start value=0000000000 sec=1 class=2
|
||||
sym[13] ext_func value=00000000a0 sec=1 class=2
|
||||
sym[14] ext_data value=00000000b0 sec=2 class=2
|
||||
sym[15] .text value=0000000000 sec=1 class=2
|
||||
sym[16] etext value=00000000b0 sec=1 class=2
|
||||
sym[17] .data value=00000000b0 sec=2 class=2
|
||||
sym[18] edata value=00000000d0 sec=2 class=2
|
||||
sym[19] .bss value=00000000d0 sec=3 class=2
|
||||
sym[20] end value=00000000d0 sec=3 class=2
|
||||
|
||||
|
||||
== .text: 22 vs 22 bytes
|
||||
differing bytes: 2
|
||||
0x0004: 8d -> 8f
|
||||
0x0010: 8c -> 8e
|
||||
== .data: 4 vs 4 bytes
|
||||
differing bytes: 0
|
||||
== .bss: 0 vs 0 bytes
|
||||
differing bytes: 0
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
Warning: -video none doesn't make much sense without -seconds_to_run
|
||||
vt1200: screen_update#1 frame=0 clip_y=0..0 screen=1280x901
|
||||
LOADER: payload dwt/loader/build/loader.bin (1220 B) -> bit 01880000
|
||||
LOADER: COFF dwt/loader/build/rela.obj (342 B) -> bit 01900000
|
||||
LOADER: file magic=0090 nscns=3 opthdr=0 optmagic=none entry=00000000 textstart=00000000
|
||||
LOADER: sec .text paddr=00000000 size=160 bits (20 B) scnptr=0x8c flags=0x20
|
||||
LOADER: sec .data paddr=00000000 size=0 bits (0 B) scnptr=0xa0 flags=0x40
|
||||
LOADER: sec .bss paddr=00000000 size=0 bits (0 B) scnptr=0 flags=0x80
|
||||
vt1200: screen_update#2 frame=0 clip_y=1..900 screen=1280x901
|
||||
vt1200: scanline#1 line=1 enabled=1
|
||||
vt1200: guard#1 frame=0 dump_frame=-1 dump_ram=-1
|
||||
vt1200: screen_update#3 frame=1 clip_y=0..0 screen=1280x901
|
||||
vt1200: scanline#2 line=0 enabled=1
|
||||
vt1200: screen_update#4 frame=1 clip_y=1..1 screen=1280x901
|
||||
vt1200: scanline#3 line=1 enabled=1
|
||||
vt1200: scanline#4 line=2 enabled=1
|
||||
LOADER: loader poked 610 words, readback 0 bad at 01880000
|
||||
LOADER: COFF poked 171 words, readback 0 bad at 01900000
|
||||
LOADER: pre-filled .bss 00000000..00000000 with A5A5
|
||||
LOADER: descriptor @01882C00 magic=4C44/5231 buf=01900000 len=342 mode=0
|
||||
LOADER: will resume at 3F579970 after create_process
|
||||
LOADER: frame 2500: entered loader at 01880000 (caller SP=007F52B0)
|
||||
LOADER: result status=7 (relocation records present (unsupported)) entry=00000000 text=00000000/0 bits data=00000000/0 bits bss=00000000/0 bits relocs=2 pcb=00000000 nscns=3 len=342
|
||||
LOADER: placed .text at 00000000: 20 bytes, 5 differing
|
||||
LOADER: PC at inspection = 3F5799D0
|
||||
Average speed: 335.05% (35 seconds)
|
||||
@@ -0,0 +1,28 @@
|
||||
Warning: -video none doesn't make much sense without -seconds_to_run
|
||||
vt1200: screen_update#1 frame=0 clip_y=0..0 screen=1280x901
|
||||
LOADER: payload dwt/loader/build/loader.bin (1220 B) -> bit 01880000
|
||||
LOADER: COFF dwt/loader/build/xhello.coff (774 B) -> bit 01900000
|
||||
LOADER: file magic=0090 nscns=3 opthdr=28 optmagic=0108 entry=00000000 textstart=01840000
|
||||
LOADER: sec .data paddr=00000000 size=0 bits (0 B) scnptr=0xa8 flags=0x40
|
||||
LOADER: sec .bss paddr=00000000 size=0 bits (0 B) scnptr=0 flags=0x80
|
||||
LOADER: sec .text paddr=01840000 size=3120 bits (390 B) scnptr=0xa8 flags=0x20
|
||||
vt1200: screen_update#2 frame=0 clip_y=1..900 screen=1280x901
|
||||
vt1200: scanline#1 line=1 enabled=1
|
||||
vt1200: guard#1 frame=0 dump_frame=-1 dump_ram=-1
|
||||
vt1200: screen_update#3 frame=1 clip_y=0..0 screen=1280x901
|
||||
vt1200: scanline#2 line=0 enabled=1
|
||||
vt1200: screen_update#4 frame=1 clip_y=1..1 screen=1280x901
|
||||
vt1200: scanline#3 line=1 enabled=1
|
||||
vt1200: scanline#4 line=2 enabled=1
|
||||
LOADER: loader poked 610 words, readback 0 bad at 01880000
|
||||
LOADER: COFF poked 387 words, readback 0 bad at 01900000
|
||||
LOADER: pre-filled .bss 00000000..00000000 with A5A5
|
||||
LOADER: descriptor @01882C00 magic=4C44/5231 buf=01900000 len=774 mode=0
|
||||
LOADER: will resume at 3F579970 after create_process
|
||||
LOADER: frame 2500: entered loader at 01880000 (caller SP=007F52B0)
|
||||
LOADER: result status=0 (OK) entry=01840000 text=01840000/3120 bits data=00000000/0 bits bss=00000000/0 bits relocs=0 pcb=003FFBD0 nscns=3 len=774
|
||||
LOADER: placed .text at 01840000: 390 bytes, 0 differing
|
||||
LOADER: xhello: stage=6 strlen=4 display=006BC910 root=0001006B window=00010001 sync=00060001
|
||||
LOADER: PC at inspection = 3F579970
|
||||
LOADER: snapshot /home/arti/code/k-space/vt1200/dwt/loader/evidence/loader_frame2650.png ok=true
|
||||
Average speed: 344.05% (36 seconds)
|
||||
@@ -0,0 +1,496 @@
|
||||
; loader.asm -- COFF loader for the VT1200 / TMS34010.
|
||||
;
|
||||
; Input: a TI GSP COFF image (GSPLNK `-a` output) already in RAM, and a
|
||||
; 16-byte descriptor (offsets in BITS, since all pointers here are bit
|
||||
; addresses; the byte offsets are 0, 2, 4, 8 and 12):
|
||||
;
|
||||
; DESC + 0x00 bits u16 0x4C44 "LD" ) magic; both words must match
|
||||
; DESC + 0x10 bits u16 0x5231 "R1" )
|
||||
; DESC + 0x20 bits u32 buf bit address of the COFF image
|
||||
; DESC + 0x40 bits u32 len length in bytes
|
||||
; DESC + 0x60 bits u32 mode 1 = return to the caller (rets)
|
||||
; 0 = debug resume at LD_ORIG_PC
|
||||
;
|
||||
; The descriptor pointer is A8. If A8 is zero, or does not point at a valid
|
||||
; descriptor, the fixed descriptor at 0x01882C00 is used. A transport that
|
||||
; receives a COFF over the network only has to write {buf,len,mode} there and
|
||||
; call the loader entry; it does not choose a load address. The loader takes
|
||||
; the addresses from the COFF section headers.
|
||||
;
|
||||
; Result block at 0x01882D00 (32-bit cells, bit addresses):
|
||||
;
|
||||
; +0x000 status 0 ok, nonzero = error (see the ld_err_* labels)
|
||||
; +0x020 entry bit address passed to create_process
|
||||
; +0x040 text addr .text paddr from the COFF (bits)
|
||||
; +0x060 text size .text size (bits)
|
||||
; +0x080 data addr .data paddr
|
||||
; +0x0A0 data size .data size (bits)
|
||||
; +0x0C0 bss addr .bss paddr
|
||||
; +0x0E0 bss size .bss size (bits)
|
||||
; +0x100 relocs relocation entries seen in the output COFF
|
||||
; +0x120 pcb create_process() return value (0 on failure)
|
||||
; +0x140 nscns section count from the file header
|
||||
; +0x160 coflen length from the descriptor (bytes)
|
||||
; +0x180 version loader base address, 0x01880000
|
||||
;
|
||||
; The image is POSITION-DEPENDENT: GSPLNK resolves every reference and emits
|
||||
; nreloc = 0, so each section is copied to the bit address in its header and
|
||||
; no relocation is applied. A COFF that still carries relocation records is
|
||||
; refused (status 7) rather than guessed at.
|
||||
;
|
||||
; Safety checks before any copy:
|
||||
; * size is a whole number of 16-bit words;
|
||||
; * the section bytes lie inside the descriptor's (buf,len);
|
||||
; * paddr..paddr+size is inside main RAM (bits 0x100..0x2000000);
|
||||
; * it does not overlap the loader page [01880000,01883200) or the COFF
|
||||
; buffer;
|
||||
; * it lies inside one block of the firmware's global free list
|
||||
; (head at bit 0x1E8AC0, block header {u32 size_bits; ...; u32 next@+0x20},
|
||||
; user data at block+0x40). This is a check, not a reservation: the
|
||||
; loader cannot make malloc hand out a chosen address.
|
||||
;
|
||||
; Delivered debugger-assisted for now: poke the raw .bin at 0x01880000, write
|
||||
; the COFF at buf, write the descriptor, then set PC = 0x01880000 (A8 = 0 is
|
||||
; fine). mode = 0 resumes at LD_ORIG_PC (the harness saves the interrupted
|
||||
; PC); mode = 1 returns to the caller and passes the status in A8.
|
||||
;
|
||||
; Linked at bit 0x01880000; position-dependent itself.
|
||||
|
||||
.def _start
|
||||
|
||||
LOADER_BASE equ 01880000h
|
||||
LD_SCRATCH equ 01882800h
|
||||
DESC_ADDR equ 01882C00h
|
||||
RESULT_BASE equ 01882D00h
|
||||
ARG_AREA equ 01882B00h
|
||||
RETURN_STUB equ 01883100h
|
||||
|
||||
LD_SP_AFTER equ LD_SCRATCH+000h
|
||||
LD_A14 equ LD_SCRATCH+020h
|
||||
LD_ENTRY equ LD_SCRATCH+040h
|
||||
LD_BUF equ LD_SCRATCH+060h
|
||||
LD_LEN equ LD_SCRATCH+080h
|
||||
LD_MODE equ LD_SCRATCH+0A0h
|
||||
LD_NSCNS equ LD_SCRATCH+0C0h
|
||||
LD_RELOCS equ LD_SCRATCH+0E0h
|
||||
LD_SEC_PADDR equ LD_SCRATCH+100h
|
||||
LD_SEC_SIZE equ LD_SCRATCH+120h
|
||||
LD_SEC_SCNPTR equ LD_SCRATCH+140h
|
||||
LD_TEXT_ADDR equ LD_SCRATCH+160h
|
||||
LD_TEXT_SIZE equ LD_SCRATCH+180h
|
||||
LD_DATA_ADDR equ LD_SCRATCH+1A0h
|
||||
LD_DATA_SIZE equ LD_SCRATCH+1C0h
|
||||
LD_BSS_ADDR equ LD_SCRATCH+1E0h
|
||||
LD_BSS_SIZE equ LD_SCRATCH+200h
|
||||
LD_ORIG_PC equ LD_SCRATCH+220h
|
||||
|
||||
RESULT_STATUS equ RESULT_BASE+000h
|
||||
RESULT_ENTRY equ RESULT_BASE+020h
|
||||
RESULT_TEXT_A equ RESULT_BASE+040h
|
||||
RESULT_TEXT_S equ RESULT_BASE+060h
|
||||
RESULT_DATA_A equ RESULT_BASE+080h
|
||||
RESULT_DATA_S equ RESULT_BASE+0A0h
|
||||
RESULT_BSS_A equ RESULT_BASE+0C0h
|
||||
RESULT_BSS_S equ RESULT_BASE+0E0h
|
||||
RESULT_RELOCS equ RESULT_BASE+100h
|
||||
RESULT_PCB equ RESULT_BASE+120h
|
||||
RESULT_NSCNS equ RESULT_BASE+140h
|
||||
RESULT_LEN equ RESULT_BASE+160h
|
||||
RESULT_VERSION equ RESULT_BASE+180h
|
||||
|
||||
.text
|
||||
_start:
|
||||
mmtm sp, a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13
|
||||
move sp, @LD_SP_AFTER, 1
|
||||
move a14, @LD_A14, 1
|
||||
setf 16, 0, 0
|
||||
setf 32, 0, 1
|
||||
|
||||
; ---- descriptor -----------------------------------------------------
|
||||
; A8 points at it only if both magic words match; else use the fixed one.
|
||||
move a8, a6
|
||||
move a8, a8
|
||||
jreq ld_fixed_desc
|
||||
move *a6, a0, 0
|
||||
cmpi 4C44h, a0
|
||||
jrne ld_fixed_desc
|
||||
move *a6(10h), a0, 0
|
||||
cmpi 5231h, a0
|
||||
jreq ld_have_desc
|
||||
ld_fixed_desc:
|
||||
movi DESC_ADDR, a6, L
|
||||
move *a6, a0, 0
|
||||
cmpi 4C44h, a0
|
||||
jrne ld_bad_desc
|
||||
move *a6(10h), a0, 0
|
||||
cmpi 5231h, a0
|
||||
jrne ld_bad_desc
|
||||
ld_have_desc:
|
||||
move *a6(20h), a7, 1 ; buf
|
||||
move *a6(40h), a8, 1 ; len
|
||||
move *a6(60h), a12, 1 ; mode
|
||||
move a7, @LD_BUF, 1
|
||||
move a8, @LD_LEN, 1
|
||||
move a12, @LD_MODE, 1
|
||||
move a12, @RESULT_VERSION, 1 ; harmless; overwritten below
|
||||
movi LOADER_BASE, a0, L
|
||||
move a0, @RESULT_VERSION, 1
|
||||
|
||||
; clear the counters we report; status stays FF until this loader writes it
|
||||
movi 0FFFFFFFFh, a0, L
|
||||
move a0, @RESULT_STATUS, 1
|
||||
sub a0, a0
|
||||
move a0, @LD_RELOCS, 1
|
||||
move a0, @LD_TEXT_ADDR, 1
|
||||
move a0, @LD_TEXT_SIZE, 1
|
||||
move a0, @LD_DATA_ADDR, 1
|
||||
move a0, @LD_DATA_SIZE, 1
|
||||
move a0, @LD_BSS_ADDR, 1
|
||||
move a0, @LD_BSS_SIZE, 1
|
||||
move a0, @RESULT_ENTRY, 1
|
||||
move a0, @RESULT_TEXT_A, 1
|
||||
move a0, @RESULT_TEXT_S, 1
|
||||
move a0, @RESULT_DATA_A, 1
|
||||
move a0, @RESULT_DATA_S, 1
|
||||
move a0, @RESULT_BSS_A, 1
|
||||
move a0, @RESULT_BSS_S, 1
|
||||
move a0, @RESULT_RELOCS, 1
|
||||
move a0, @RESULT_PCB, 1
|
||||
|
||||
; ---- file header ----------------------------------------------------
|
||||
movi 20, a0, L
|
||||
cmp a0, a8
|
||||
jrlo ld_err_short
|
||||
move *a7, a0, 0 ; magic
|
||||
cmpi 0090h, a0
|
||||
jrne ld_err_magic
|
||||
move *a7(10h), a9, 0 ; nscns (+2 bytes)
|
||||
move a9, @LD_NSCNS, 1
|
||||
move *a7(10h), a0, 0
|
||||
move a9, @RESULT_NSCNS, 1
|
||||
move a8, @RESULT_LEN, 1
|
||||
|
||||
; section headers = buf + (20 + opthdr + nscns*40) bytes; must fit in len
|
||||
move *a7(80h), a1, 0 ; opthdr (+16 bytes)
|
||||
move a9, a2
|
||||
sll 5, a2 ; nscns*32
|
||||
move a9, a3
|
||||
sll 3, a3 ; nscns*8
|
||||
add a3, a2 ; nscns*40
|
||||
add a1, a2
|
||||
addi 20, a2 ; byte offset of section headers end
|
||||
cmp a2, a8 ; a8 - a2
|
||||
jrlo ld_err_short
|
||||
|
||||
; secbase = buf + (20 + opthdr)*8 bits
|
||||
sll 3, a1 ; opthdr in bits
|
||||
addi 160, a1 ; 20 bytes in bits
|
||||
add a7, a1
|
||||
move a1, a10
|
||||
|
||||
; ---- entry point ----------------------------------------------------
|
||||
; optional header at buf+20 bytes (0x0A0 bits): magic 0x0108; entry at
|
||||
; +16 bytes (0x080 bits further); textstart at +20 bytes.
|
||||
move *a7(0A0h), a0, 0
|
||||
cmpi 0108h, a0
|
||||
jrne ld_no_opt
|
||||
move *a7(120h), a5, 1 ; entry (bits)
|
||||
move a5, a5
|
||||
jrne ld_entry_set
|
||||
move *a7(140h), a5, 1 ; textstart (bits)
|
||||
jruc ld_entry_set
|
||||
ld_no_opt:
|
||||
sub a5, a5
|
||||
|
||||
ld_entry_set:
|
||||
move a5, @LD_ENTRY, 1
|
||||
move a5, @RESULT_ENTRY, 1
|
||||
|
||||
; ---- section loop ---------------------------------------------------
|
||||
sub a11, a11 ; section index
|
||||
ld_sec_loop:
|
||||
cmp a9, a11 ; a11 - a9
|
||||
jrhs ld_sec_done
|
||||
move *a10(40h), a0, 1 ; paddr (bits) +8 bytes
|
||||
move *a10(80h), a1, 1 ; size (bits) +16
|
||||
move *a10(0A0h), a2, 1 ; scnptr (bytes) +20
|
||||
move *a10(100h), a3, 0 ; nreloc +32
|
||||
move *a10(120h), a4, 1 ; flags +36
|
||||
move a0, @LD_SEC_PADDR, 1
|
||||
move a1, @LD_SEC_SIZE, 1
|
||||
move a2, @LD_SEC_SCNPTR, 1
|
||||
|
||||
; record the first text/data/bss section for the result block
|
||||
move a4, a5
|
||||
andi 20h, a5
|
||||
move a5, a5
|
||||
jreq ld_not_text
|
||||
move @LD_TEXT_ADDR, a5, 1
|
||||
move a5, a5
|
||||
jrne ld_not_text
|
||||
move a0, @LD_TEXT_ADDR, 1
|
||||
move a1, @LD_TEXT_SIZE, 1
|
||||
ld_not_text:
|
||||
move a4, a5
|
||||
andi 40h, a5
|
||||
move a5, a5
|
||||
jreq ld_not_data
|
||||
move @LD_DATA_ADDR, a5, 1
|
||||
move a5, a5
|
||||
jrne ld_not_data
|
||||
move a0, @LD_DATA_ADDR, 1
|
||||
move a1, @LD_DATA_SIZE, 1
|
||||
ld_not_data:
|
||||
move a4, a5
|
||||
andi 80h, a5
|
||||
move a5, a5
|
||||
jreq ld_not_bss
|
||||
move @LD_BSS_ADDR, a5, 1
|
||||
move a5, a5
|
||||
jrne ld_not_bss
|
||||
move a0, @LD_BSS_ADDR, 1
|
||||
move a1, @LD_BSS_SIZE, 1
|
||||
ld_not_bss:
|
||||
|
||||
; relocation records: count, then refuse (the linked image has none)
|
||||
move a3, a3
|
||||
jreq ld_no_reloc
|
||||
move @LD_RELOCS, a5, 1
|
||||
add a3, a5
|
||||
move a5, @LD_RELOCS, 1
|
||||
jruc ld_err_reloc
|
||||
ld_no_reloc:
|
||||
|
||||
; size 0: nothing to place; size must be whole 16-bit words
|
||||
move a1, a1
|
||||
jreq ld_sec_next
|
||||
move a1, a5
|
||||
andi 0Fh, a5
|
||||
move a5, a5
|
||||
jrne ld_err_size
|
||||
|
||||
; source range: scnptr + size/8 <= len (when there are bytes)
|
||||
move a2, a2
|
||||
jreq ld_no_src
|
||||
move a1, a5
|
||||
srl 3, a5 ; size in bytes
|
||||
add a5, a2 ; scnptr + nbytes
|
||||
cmp a8, a2 ; a8 - a2
|
||||
jrhi ld_err_short
|
||||
ld_no_src:
|
||||
|
||||
; target range: 0x100 <= paddr and paddr+size <= 0x2000000 bits
|
||||
move @LD_SEC_PADDR, a0, 1
|
||||
cmpi 100h, a0
|
||||
jrlo ld_err_bounds
|
||||
move @LD_SEC_SIZE, a1, 1
|
||||
move a0, a3
|
||||
add a1, a3 ; target end
|
||||
movi 2000000h, a5, L
|
||||
cmp a5, a3
|
||||
jrhi ld_err_bounds
|
||||
|
||||
; overlap with the loader page [01880000,01883200)
|
||||
movi 01883200h, a5, L
|
||||
cmp a5, a0
|
||||
jrhs ld_ov1_done
|
||||
movi 01880000h, a5, L
|
||||
cmp a3, a5
|
||||
jrhs ld_ov1_done
|
||||
jruc ld_err_overlap
|
||||
ld_ov1_done:
|
||||
|
||||
; overlap with the COFF buffer [buf, buf+len*8)
|
||||
move a8, a5
|
||||
sll 3, a5
|
||||
add a7, a5 ; buffer end in bits
|
||||
cmp a5, a0
|
||||
jrhs ld_ov2_done
|
||||
cmp a3, a7
|
||||
jrhs ld_ov2_done
|
||||
jruc ld_err_overlap
|
||||
ld_ov2_done:
|
||||
|
||||
; ---- global free-list check ----------------------------------------
|
||||
; a block is {u32 size_bits; ...; u32 next@+0x20}; data at block+0x40.
|
||||
move a0, @LD_SEC_PADDR, 1 ; (unchanged, kept for clarity)
|
||||
move a3, @LD_SEC_SIZE, 1 ; temporarily hold target end
|
||||
move @1E8AC0h, a6, 1 ; global free-list head (block address)
|
||||
movi 64, a5, L
|
||||
ld_free_walk:
|
||||
move a6, a6
|
||||
jreq ld_err_notfree
|
||||
move *a6, a1, 1 ; block size in bits
|
||||
move *a6(20h), a2, 1 ; next block
|
||||
move a6, a0
|
||||
addi 40h, a0 ; user start
|
||||
move @LD_SEC_PADDR, a3, 1
|
||||
cmp a0, a3
|
||||
jrlo ld_free_next
|
||||
move a6, a4
|
||||
add a1, a4 ; block end
|
||||
move @LD_SEC_SIZE, a1, 1 ; target end (stashed above)
|
||||
cmp a4, a1
|
||||
jrhi ld_free_next
|
||||
jruc ld_free_ok
|
||||
ld_free_next:
|
||||
move a2, a6
|
||||
dsjs a5, ld_free_walk
|
||||
jruc ld_err_notfree
|
||||
ld_free_ok:
|
||||
|
||||
; restore size in LD_SEC_SIZE (the stash overwrote it)
|
||||
; target end - paddr = size
|
||||
move @LD_SEC_SIZE, a1, 1
|
||||
move @LD_SEC_PADDR, a0, 1
|
||||
sub a0, a1 ; a1 = size again
|
||||
move a1, @LD_SEC_SIZE, 1
|
||||
|
||||
; ---- place the section ---------------------------------------------
|
||||
move @LD_SEC_SCNPTR, a0, 1
|
||||
move a0, a0
|
||||
jreq ld_zero_sec
|
||||
sll 3, a0 ; file offset -> bit offset
|
||||
add a7, a0 ; source address
|
||||
move @LD_SEC_PADDR, a2, 1
|
||||
move @LD_SEC_SIZE, a1, 1
|
||||
srl 4, a1 ; number of 16-bit words
|
||||
ld_copy_words:
|
||||
move *a0+, a4, 0
|
||||
move a4, *a2+, 0
|
||||
dsjs a1, ld_copy_words
|
||||
jruc ld_sec_next
|
||||
|
||||
ld_zero_sec:
|
||||
move @LD_SEC_PADDR, a2, 1
|
||||
move @LD_SEC_SIZE, a1, 1
|
||||
srl 4, a1
|
||||
sub a4, a4
|
||||
ld_zero_words:
|
||||
move a4, *a2+, 0
|
||||
dsjs a1, ld_zero_words
|
||||
|
||||
ld_sec_next:
|
||||
addi 140h, a10 ; 40-byte section header = 320 bits
|
||||
addi 1, a11
|
||||
jruc ld_sec_loop
|
||||
|
||||
ld_sec_done:
|
||||
move @LD_TEXT_ADDR, a0, 1
|
||||
move a0, @RESULT_TEXT_A, 1
|
||||
move @LD_TEXT_SIZE, a1, 1
|
||||
move a1, @RESULT_TEXT_S, 1
|
||||
move @LD_DATA_ADDR, a0, 1
|
||||
move a0, @RESULT_DATA_A, 1
|
||||
move @LD_DATA_SIZE, a1, 1
|
||||
move a1, @RESULT_DATA_S, 1
|
||||
move @LD_BSS_ADDR, a0, 1
|
||||
move a0, @RESULT_BSS_A, 1
|
||||
move @LD_BSS_SIZE, a1, 1
|
||||
move a1, @RESULT_BSS_S, 1
|
||||
move @LD_RELOCS, a0, 1
|
||||
move a0, @RESULT_RELOCS, 1
|
||||
|
||||
; ---- create_process(entry, name, stack, 1, arg) --------------------
|
||||
move @LD_ENTRY, a0, 1
|
||||
move a0, a0
|
||||
jrne ld_have_entry
|
||||
jruc ld_err_noentry
|
||||
ld_have_entry:
|
||||
move @LD_A14, a14, 1
|
||||
move @LD_SP_AFTER, sp, 1
|
||||
move a14, -*sp, 1 ; the slot the firmware callee restores
|
||||
movi ARG_AREA, a14, L
|
||||
movi 0, a0, L
|
||||
move a0, *a14+, 1 ; arg4 = 0
|
||||
movi 1, a0, L
|
||||
move a0, *a14+, 1 ; arg3 = 1
|
||||
movi 6000h, a0, L
|
||||
move a0, *a14+, 1 ; arg2 = stack bytes
|
||||
movi ld_appname, a0, L
|
||||
move a0, *a14+, 1 ; arg1 = name string
|
||||
move @LD_ENTRY, a0, 1
|
||||
move a0, *a14+, 1 ; arg0 = entry (bit address)
|
||||
calla 3F706A40h ; create_process
|
||||
move @LD_SP_AFTER, sp, 1
|
||||
move @LD_A14, a14, 1
|
||||
setf 16, 0, 0
|
||||
setf 32, 0, 1
|
||||
move a8, @RESULT_PCB, 1
|
||||
move a8, a8
|
||||
jreq ld_err_create
|
||||
|
||||
sub a0, a0
|
||||
move a0, @RESULT_STATUS, 1
|
||||
jruc ld_finish
|
||||
|
||||
; ---- errors ---------------------------------------------------------
|
||||
ld_bad_desc:
|
||||
movi 1, a0, L
|
||||
jruc ld_error
|
||||
ld_err_short:
|
||||
movi 2, a0, L
|
||||
jruc ld_error
|
||||
ld_err_magic:
|
||||
movi 3, a0, L
|
||||
jruc ld_error
|
||||
ld_err_size:
|
||||
movi 4, a0, L
|
||||
jruc ld_error
|
||||
ld_err_bounds:
|
||||
movi 5, a0, L
|
||||
jruc ld_error
|
||||
ld_err_overlap:
|
||||
movi 6, a0, L
|
||||
jruc ld_error
|
||||
ld_err_reloc:
|
||||
movi 7, a0, L
|
||||
jruc ld_error
|
||||
ld_err_notfree:
|
||||
movi 8, a0, L
|
||||
jruc ld_error
|
||||
ld_err_noentry:
|
||||
movi 9, a0, L
|
||||
jruc ld_error
|
||||
ld_err_create:
|
||||
movi 10, a0, L
|
||||
ld_error:
|
||||
move a0, @RESULT_STATUS, 1
|
||||
move @LD_NSCNS, a0, 1
|
||||
move a0, @RESULT_NSCNS, 1
|
||||
move @LD_RELOCS, a0, 1
|
||||
move a0, @RESULT_RELOCS, 1
|
||||
|
||||
ld_finish:
|
||||
move @LD_ENTRY, a0, 1
|
||||
move a0, @RESULT_ENTRY, 1
|
||||
move @LD_NSCNS, a0, 1
|
||||
move a0, @RESULT_NSCNS, 1
|
||||
move @LD_LEN, a0, 1
|
||||
move a0, @RESULT_LEN, 1
|
||||
movi LOADER_BASE, a0, L
|
||||
move a0, @RESULT_VERSION, 1
|
||||
|
||||
; ---- return or spin -------------------------------------------------
|
||||
move @LD_MODE, a0, 1
|
||||
move a0, a0
|
||||
jrne ld_return
|
||||
; mode 0 (debugger entry): restore the interrupted state and resume at
|
||||
; the PC the harness hijacked. Returning to the OS idle loop lets the
|
||||
; scheduler run the created child.
|
||||
move @LD_SP_AFTER, sp, 1
|
||||
move @LD_A14, a14, 1
|
||||
mmfm sp, a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13
|
||||
move @LD_ORIG_PC, a0, 1
|
||||
jump a0
|
||||
|
||||
ld_return:
|
||||
move @LD_SP_AFTER, sp, 1
|
||||
move @LD_A14, a14, 1
|
||||
mmfm sp, a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13
|
||||
move @RESULT_STATUS, a8, 1 ; 0 = ok, else the error code
|
||||
rets
|
||||
|
||||
ld_appname:
|
||||
.byte "LOADER", 0
|
||||
.end
|
||||
@@ -0,0 +1,338 @@
|
||||
-- loader.lua -- debugger-assisted COFF loader acceptance harness.
|
||||
--
|
||||
-- Boots the firmware with VT1200_SKIP_LEVEL1=1 (the documented divergence) to
|
||||
-- the OS, then at frame LOADER_AT pokes:
|
||||
-- * the loader payload at bit 0x01880000 (raw dwt/loader/build/loader.bin)
|
||||
-- * a GSPLNK COFF image at LOADER_BUF (default bit 0x01900000)
|
||||
-- * the loader descriptor at 0x01882C00
|
||||
-- and sets PC = 0x01880000. It does not use the network, the rdebug service
|
||||
-- or any firmware transport: this is the debugger-assisted milestone.
|
||||
--
|
||||
-- The loader itself copies the COFF sections to their linked bit addresses and
|
||||
-- calls create_process(entry, "LOADER", 0x6000, 1, 0). This script only pokes
|
||||
-- the input and reads the result; it never writes the app's code or markers.
|
||||
--
|
||||
-- Env:
|
||||
-- LOADER_BIN loader payload (default dwt/loader/build/loader.bin)
|
||||
-- LOADER_COFF app COFF (default dwt/loader/build/marker.coff)
|
||||
-- LOADER_BUF COFF buffer bit address (default 0x01900000)
|
||||
-- LOADER_AT injection frame (default 2500)
|
||||
-- LOADER_END inspection/exit frame (default 2700)
|
||||
-- LOADER_OUT evidence directory (default dwt/loader/evidence)
|
||||
-- LOADER_SNAP 1 = write a PNG at LOADER_END (default 0)
|
||||
-- LOADER_VERBOSE 1 = print the result block every 25 frames
|
||||
|
||||
local function hex(v, w) return string.format("%0" .. (w or 8) .. "X", v) end
|
||||
|
||||
local machine = manager.machine
|
||||
local cpu = machine.devices[':maincpu']
|
||||
local dbg = machine.debugger
|
||||
local prog = cpu.spaces['program']
|
||||
|
||||
if not dbg then
|
||||
print("LOADER: debugger not enabled; pass -debug")
|
||||
machine:exit()
|
||||
return
|
||||
end
|
||||
|
||||
local AT = tonumber(os.getenv("LOADER_AT") or "2500")
|
||||
local ENDF = tonumber(os.getenv("LOADER_END") or "2700")
|
||||
local BIN = os.getenv("LOADER_BIN") or "dwt/loader/build/loader.bin"
|
||||
local COFF = os.getenv("LOADER_COFF") or "dwt/loader/build/marker.coff"
|
||||
local BUF = tonumber(os.getenv("LOADER_BUF") or "0x01900000")
|
||||
local OUT = os.getenv("LOADER_OUT") or "dwt/loader/evidence"
|
||||
local SNAP = os.getenv("LOADER_SNAP") == "1"
|
||||
local MODE = tonumber(os.getenv("LOADER_MODE") or "0")
|
||||
local A8DESC = os.getenv("LOADER_A8_DESC") == "1"
|
||||
local VERBOSE = os.getenv("LOADER_VERBOSE") == "1"
|
||||
|
||||
local LOADER_BASE = 0x01880000
|
||||
local DESC = 0x01882C00
|
||||
local RESULT = 0x01882D00
|
||||
local RETURN_STUB = 0x01883100
|
||||
local RETURN_SP = 0x01883110
|
||||
|
||||
local function rd(p) return io.open(p, "rb") end
|
||||
local function slurp(p)
|
||||
local f, err = rd(p)
|
||||
if not f then error("cannot open " .. p .. ": " .. tostring(err)) end
|
||||
local s = f:read("*a")
|
||||
f:close()
|
||||
return s
|
||||
end
|
||||
|
||||
local function u16(s, o)
|
||||
return s:byte(o + 1) + s:byte(o + 2) * 256
|
||||
end
|
||||
|
||||
local function u32(s, o)
|
||||
return s:byte(o + 1) + s:byte(o + 2) * 256
|
||||
+ s:byte(o + 3) * 65536 + s:byte(o + 4) * 16777216
|
||||
end
|
||||
|
||||
local function parse_coff(d)
|
||||
local c = { data = d }
|
||||
c.magic = u16(d, 0)
|
||||
c.nscns = u16(d, 2)
|
||||
c.opthdr = u16(d, 16)
|
||||
c.sections = {}
|
||||
if c.opthdr > 0 then
|
||||
c.optmagic = u16(d, 20)
|
||||
c.entry = u32(d, 20 + 16)
|
||||
c.textstart = u32(d, 20 + 20)
|
||||
c.datastart = u32(d, 20 + 24)
|
||||
end
|
||||
local base = 20 + c.opthdr
|
||||
for i = 0, c.nscns - 1 do
|
||||
local o = base + i * 40
|
||||
local name = d:sub(o + 1, o + 8):gsub("%z", "")
|
||||
c.sections[#c.sections + 1] = {
|
||||
name = name,
|
||||
paddr = u32(d, o + 8),
|
||||
size = u32(d, o + 16), -- bits
|
||||
scnptr = u32(d, o + 20),
|
||||
flags = u32(d, o + 36),
|
||||
}
|
||||
end
|
||||
return c
|
||||
end
|
||||
|
||||
local function poke_bytes(bitaddr, data)
|
||||
local n = math.floor((#data + 1) / 2)
|
||||
for i = 0, n - 1 do
|
||||
local lo = data:byte(i * 2 + 1) or 0
|
||||
local hi = data:byte(i * 2 + 2) or 0
|
||||
prog:write_u16(bitaddr + i * 16, lo + hi * 256)
|
||||
end
|
||||
return n
|
||||
end
|
||||
|
||||
local function verify_bytes(bitaddr, data)
|
||||
local n = math.floor((#data + 1) / 2)
|
||||
local bad = 0
|
||||
for i = 0, n - 1 do
|
||||
local lo = data:byte(i * 2 + 1) or 0
|
||||
local hi = data:byte(i * 2 + 2) or 0
|
||||
if prog:read_u16(bitaddr + i * 16) ~= lo + hi * 256 then
|
||||
bad = bad + 1
|
||||
end
|
||||
end
|
||||
return n, bad
|
||||
end
|
||||
|
||||
local function w32(a, v) prog:write_u32(a, v) end
|
||||
local function r32(a)
|
||||
local ok, v = pcall(function() return prog:read_u32(a) end)
|
||||
if ok then return v end
|
||||
return 0xDEADBEEF
|
||||
end
|
||||
|
||||
local loader = slurp(BIN)
|
||||
local coff = slurp(COFF)
|
||||
local app = parse_coff(coff)
|
||||
|
||||
print(string.format("LOADER: payload %s (%d B) -> bit %s", BIN, #loader, hex(LOADER_BASE)))
|
||||
print(string.format("LOADER: COFF %s (%d B) -> bit %s", COFF, #coff, hex(BUF)))
|
||||
print(string.format("LOADER: file magic=%04X nscns=%d opthdr=%d optmagic=%s entry=%s textstart=%s",
|
||||
app.magic, app.nscns, app.opthdr,
|
||||
app.optmagic and string.format("%04X", app.optmagic) or "none",
|
||||
hex(app.entry or 0), hex(app.textstart or 0)))
|
||||
for _, s in ipairs(app.sections) do
|
||||
print(string.format("LOADER: sec %-8s paddr=%s size=%d bits (%d B) scnptr=%#x flags=%#x",
|
||||
s.name, hex(s.paddr), s.size, math.floor(s.size / 8), s.scnptr, s.flags))
|
||||
end
|
||||
|
||||
local TRACE = os.getenv("LOADER_TRACE") == "1"
|
||||
|
||||
local frames = 0
|
||||
local injected = false
|
||||
local done = false
|
||||
local last_count = -1
|
||||
|
||||
local function status_name(v)
|
||||
local t = {
|
||||
[0] = "OK",
|
||||
[1] = "bad descriptor",
|
||||
[2] = "truncated COFF / section headers",
|
||||
[3] = "bad COFF magic",
|
||||
[4] = "section size not whole words",
|
||||
[5] = "target outside RAM",
|
||||
[6] = "target overlaps loader page or COFF buffer",
|
||||
[7] = "relocation records present (unsupported)",
|
||||
[8] = "target not in a free-list block",
|
||||
[9] = "no entry point",
|
||||
}
|
||||
return t[v] or ("error " .. tostring(v))
|
||||
end
|
||||
|
||||
local function result_dump()
|
||||
local st = r32(RESULT + 0x000)
|
||||
print(string.format(
|
||||
"LOADER: result status=%d (%s) entry=%s text=%s/%d bits data=%s/%d bits bss=%s/%d bits relocs=%d pcb=%s nscns=%d len=%d",
|
||||
st, status_name(st), hex(r32(RESULT + 0x020)),
|
||||
hex(r32(RESULT + 0x040)), r32(RESULT + 0x060),
|
||||
hex(r32(RESULT + 0x080)), r32(RESULT + 0x0A0),
|
||||
hex(r32(RESULT + 0x0C0)), r32(RESULT + 0x0E0),
|
||||
r32(RESULT + 0x100), hex(r32(RESULT + 0x120)),
|
||||
r32(RESULT + 0x140), r32(RESULT + 0x160)))
|
||||
end
|
||||
|
||||
local function inject()
|
||||
-- 1. loader itself
|
||||
local n, bad = 0, 0
|
||||
poke_bytes(LOADER_BASE, loader)
|
||||
n, bad = verify_bytes(LOADER_BASE, loader)
|
||||
print(string.format("LOADER: loader poked %d words, readback %d bad at %s",
|
||||
n, bad, hex(LOADER_BASE)))
|
||||
|
||||
-- 2. COFF image
|
||||
poke_bytes(BUF, coff)
|
||||
n, bad = verify_bytes(BUF, coff)
|
||||
print(string.format("LOADER: COFF poked %d words, readback %d bad at %s",
|
||||
n, bad, hex(BUF)))
|
||||
|
||||
-- 3. pre-fill every .bss section with A5A5, so a loaded zero is meaningful
|
||||
for _, s in ipairs(app.sections) do
|
||||
if s.flags & 0x80 ~= 0 then
|
||||
for i = 0, math.floor(s.size / 16) - 1 do
|
||||
prog:write_u16(s.paddr + i * 16, 0xA5A5)
|
||||
end
|
||||
print(string.format("LOADER: pre-filled .bss %s..%s with A5A5",
|
||||
hex(s.paddr), hex(s.paddr + s.size)))
|
||||
end
|
||||
end
|
||||
|
||||
-- 4. descriptor: magic "LD" "R1", buf, len, mode=0 (spin)
|
||||
w32(DESC + 0x00, 0)
|
||||
prog:write_u16(DESC + 0x00, 0x4C44)
|
||||
prog:write_u16(DESC + 0x10, 0x5231)
|
||||
w32(DESC + 0x20, BUF)
|
||||
w32(DESC + 0x40, #coff)
|
||||
w32(DESC + 0x60, MODE)
|
||||
print(string.format("LOADER: descriptor @%s magic=%04X/%04X buf=%s len=%d mode=%d",
|
||||
hex(DESC), prog:read_u16(DESC + 0x00), prog:read_u16(DESC + 0x10),
|
||||
hex(r32(DESC + 0x20)), r32(DESC + 0x40), r32(DESC + 0x60)))
|
||||
|
||||
-- 5. return stub. mode 0 ignores it (the loader jumps to ORIG_PC
|
||||
-- itself); mode 1 returns here, and the stub resumes the interrupted
|
||||
-- PC so the caller yields and the scheduler can run the child.
|
||||
local orig_pc = cpu.state['PC'].value
|
||||
if MODE == 1 then
|
||||
prog:write_u16(RETURN_STUB, 0xC080) -- jauc <orig_pc>
|
||||
prog:write_u16(RETURN_STUB + 0x10, orig_pc & 0xFFFF)
|
||||
prog:write_u16(RETURN_STUB + 0x20, math.floor(orig_pc / 0x10000) & 0xFFFF)
|
||||
else
|
||||
prog:write_u16(RETURN_STUB, 0xC0FF) -- jruc self
|
||||
end
|
||||
|
||||
-- 6. enter the loader. A8=0 selects the fixed descriptor; SP points at
|
||||
-- the return slot so mode=1 would return to the spin stub.
|
||||
-- Leave SP alone for mode 0: the loader pushes onto the current
|
||||
-- process stack, then restores it and resumes at ORIG_PC. (mode 1
|
||||
-- would use the return stub.)
|
||||
w32(0x01882A20, orig_pc) -- LD_ORIG_PC
|
||||
print(string.format("LOADER: will resume at %s after create_process", hex(orig_pc)))
|
||||
cpu.state['A8'].value = A8DESC and DESC or 0
|
||||
if MODE == 1 then
|
||||
-- Simulate a CALLA from the current process: push the return
|
||||
-- address on the *firmware* stack (a real transport would do this).
|
||||
local sp = cpu.state['SP'].value - 0x20
|
||||
w32(sp, RETURN_STUB)
|
||||
cpu.state['SP'].value = sp
|
||||
end
|
||||
cpu.state['PC'].value = LOADER_BASE
|
||||
injected = true
|
||||
print(string.format("LOADER: frame %d: entered loader at %s (caller SP=%s)",
|
||||
frames, hex(LOADER_BASE), hex(cpu.state['SP'].value)))
|
||||
end
|
||||
|
||||
local function inspect()
|
||||
result_dump()
|
||||
|
||||
-- Verify the placement from RAM: .text/.data must equal the file bytes.
|
||||
for _, s in ipairs(app.sections) do
|
||||
if s.scnptr ~= 0 and s.size > 0 then
|
||||
local nb = math.floor(s.size / 8)
|
||||
local bytes = coff:sub(s.scnptr + 1, s.scnptr + nb)
|
||||
local _, bad = verify_bytes(s.paddr, bytes)
|
||||
print(string.format("LOADER: placed %s at %s: %d bytes, %d differing",
|
||||
s.name, hex(s.paddr), nb, bad))
|
||||
end
|
||||
end
|
||||
|
||||
local base = COFF:match("([^/]+)$") or COFF
|
||||
if base:find("marker") then
|
||||
print(string.format("LOADER: marker app: start=%s data=%s data2=%s bss=%s count=%d",
|
||||
hex(r32(0x018E0000)), hex(r32(0x018E0020)), hex(r32(0x018E0040)),
|
||||
hex(r32(0x018E0060)), r32(0x018E0080)))
|
||||
elseif base:find("xhello") then
|
||||
print(string.format("LOADER: xhello: stage=%d strlen=%d display=%s root=%s window=%s sync=%s",
|
||||
r32(0x01890140), r32(0x01890160), hex(r32(0x01890100)),
|
||||
hex(r32(0x01890110)), hex(r32(0x01890120)), hex(r32(0x01890130))))
|
||||
end
|
||||
print(string.format("LOADER: PC at inspection = %s", hex(cpu.state['PC'].value)))
|
||||
end
|
||||
|
||||
emu.register_frame_done(function()
|
||||
frames = frames + 1
|
||||
if frames == AT and not injected then
|
||||
inject()
|
||||
if TRACE then dbg:command("trace /tmp/opencode/ld1.tr") end
|
||||
end
|
||||
if injected and TRACE and frames == AT + 1 then
|
||||
dbg:command("trace off")
|
||||
print("LOADER: trace written to /tmp/opencode/ld.tr")
|
||||
end
|
||||
if injected and not done then
|
||||
if TRACE and frames <= AT + 40 then
|
||||
print(string.format("LOADER: trace f=%d PC=%s SP=%s A14=%s status=%s entry=%s",
|
||||
frames, hex(cpu.state['PC'].value), hex(cpu.state['SP'].value),
|
||||
hex(cpu.state['A14'].value), hex(r32(RESULT + 0x000)),
|
||||
hex(r32(RESULT + 0x020))))
|
||||
end
|
||||
local st = r32(RESULT + 0x000)
|
||||
-- status 0 means OK; nonzero is final too once parsing has begun
|
||||
if st ~= 0xFFFFFFFF and not done then
|
||||
-- The loader writes 0 on success. A nonzero status is final
|
||||
-- only after it has been written once (it is 0 from power-on,
|
||||
-- so require the loader to have run: PC no longer at entry or
|
||||
-- the app counter moved).
|
||||
end
|
||||
if VERBOSE and frames % 25 == 0 then
|
||||
result_dump()
|
||||
end
|
||||
if base_contains_marker then
|
||||
local c = r32(0x018E0080)
|
||||
if c ~= last_count then
|
||||
if last_count ~= -1 then
|
||||
print(string.format("LOADER: marker counter %d -> %d (child running)",
|
||||
last_count, c))
|
||||
end
|
||||
last_count = c
|
||||
end
|
||||
end
|
||||
end
|
||||
if frames >= ENDF then
|
||||
if injected then
|
||||
done = true
|
||||
inspect()
|
||||
if SNAP then
|
||||
local screen = nil
|
||||
for _, s in pairs(machine.screens) do screen = s break end
|
||||
if screen then
|
||||
local out = OUT .. "/loader_frame" .. frames .. ".png"
|
||||
local ok, err = pcall(function() return screen:snapshot(out) end)
|
||||
print(string.format("LOADER: snapshot %s ok=%s %s",
|
||||
out, tostring(ok), tostring(err or "")))
|
||||
end
|
||||
end
|
||||
end
|
||||
machine:exit()
|
||||
end
|
||||
end, "vt1200-loader")
|
||||
|
||||
-- (Lua has no forward use of a name defined later; set a small flag here.)
|
||||
base_contains_marker = (COFF:match("([^/]+)$") or ""):find("marker") ~= nil
|
||||
|
||||
dbg.visible_cpu = cpu
|
||||
dbg.execution_state = 'run'
|
||||
@@ -0,0 +1,66 @@
|
||||
; marker.asm -- loader acceptance app.
|
||||
;
|
||||
; Built by dwt/loader/build.sh with three separate section origins:
|
||||
; .text 018C0000h (byte 0x318000)
|
||||
; .data 018D0000h (byte 0x31A000)
|
||||
; .bss 018D8000h (byte 0x31B000)
|
||||
;
|
||||
; It is the *COFF image* that the loader must place; it is never poked as a
|
||||
; raw blob. The loader parses the COFF, copies .text and .data, zeroes .bss,
|
||||
; and calls create_process() with the image's entry point.
|
||||
;
|
||||
; Evidence cells (32-bit, bit addresses; outside every app section):
|
||||
; 018E0000 _start address at run time (must be 018C0000)
|
||||
; 018E0020 d_magic read from .data (must be DEADBEEF)
|
||||
; 018E0040 d_two read from .data (must be 12345678)
|
||||
; 018E0060 b_zero read from .bss (must be 0; the harness pre-fills A5)
|
||||
; 018E0080 b_counter, incremented forever (proves the child is scheduled)
|
||||
;
|
||||
; The harness pre-fills the whole .bss range with A5A5A5A5 before the load, so
|
||||
; a zero at 018E0060 is the loader's zero-fill, not a fresh-RAM accident.
|
||||
|
||||
.def _start
|
||||
.text
|
||||
_start:
|
||||
setf 16, 0, 0
|
||||
setf 32, 0, 1
|
||||
|
||||
; Run-time address of this code: position dependence, made visible.
|
||||
movi _start, a2, L
|
||||
move a2, @018E0000h, 1
|
||||
|
||||
; Initialised .data must have been copied by the loader.
|
||||
move @d_magic, a0, 1
|
||||
move a0, @018E0020h, 1
|
||||
|
||||
move @d_two, a1, 1
|
||||
move a1, @018E0040h, 1
|
||||
|
||||
; .bss must have been zeroed by the loader (harness pre-fills A5).
|
||||
move @b_zero, a3, 1
|
||||
move a3, @018E0060h, 1
|
||||
|
||||
; A live counter: a created process, not a one-shot jump.
|
||||
sub a4, a4
|
||||
loop:
|
||||
addi 1, a4
|
||||
move a4, @b_counter, 1
|
||||
move a4, @018E0080h, 1
|
||||
movi 2000h, a5, L
|
||||
delay:
|
||||
dsjs a5, delay
|
||||
jruc loop
|
||||
|
||||
; Kept to leave a call in the image (and a relocation in the .obj).
|
||||
.global sub
|
||||
sub:
|
||||
rets
|
||||
|
||||
.data
|
||||
d_magic: .long 0DEADBEEFh
|
||||
d_two: .long 012345678h
|
||||
|
||||
.bss b_zero, 32, 1
|
||||
.bss b_counter, 32, 1
|
||||
|
||||
.end
|
||||
@@ -0,0 +1,85 @@
|
||||
-- probe_os.lua -- private probe for the COFF loader work.
|
||||
--
|
||||
-- Prints the OS-phase heap free list (global list only, as HEAP.md advises),
|
||||
-- and tests whether the CPU registers can be written from a frame hook while
|
||||
-- the machine is running (the debugger is attached with -debug -debugger none).
|
||||
--
|
||||
-- VT1200_SKIP_LEVEL1=1 <mame> vt1200 ... -autoboot_script dwt/loader/probe_os.lua
|
||||
--
|
||||
-- Env: PROBE_AT (frame to sample, default 2500), PROBE_END (exit frame, 2520)
|
||||
|
||||
local function hex(v, w) return string.format("%0" .. (w or 8) .. "X", v) end
|
||||
|
||||
local machine = manager.machine
|
||||
local cpu = machine.devices[':maincpu']
|
||||
local dbg = machine.debugger
|
||||
local prog = cpu.spaces['program']
|
||||
|
||||
if not dbg then
|
||||
print("PROBE: no debugger")
|
||||
machine:exit()
|
||||
return
|
||||
end
|
||||
|
||||
local AT = tonumber(os.getenv("PROBE_AT") or "2500")
|
||||
local ENDF = tonumber(os.getenv("PROBE_END") or "2520")
|
||||
local frames = 0
|
||||
local tested = false
|
||||
|
||||
local function u32(a)
|
||||
local ok, v = pcall(function() return prog:read_u32(a) end)
|
||||
if ok then return v end
|
||||
return 0xdeadbeef
|
||||
end
|
||||
|
||||
local function heap()
|
||||
print(string.format("PROBE: free counter @1E8BA0 = %d bits (%d bytes)",
|
||||
u32(0x1E8BA0), math.floor(u32(0x1E8BA0) / 8)))
|
||||
local head = u32(0x1E8AC0)
|
||||
print(string.format("PROBE: global free-list head @1E8AC0 = %s", hex(head)))
|
||||
local b = head
|
||||
for i = 0, 15 do
|
||||
if b == 0 then break end
|
||||
local size = u32(b)
|
||||
local nextp = u32(b + 0x20)
|
||||
print(string.format("PROBE: block[%d] hdr=%s size=%d bits (%d B) user=%s..%s next=%s",
|
||||
i, hex(b), size, math.floor(size / 8), hex(b + 0x40),
|
||||
hex(b + size), hex(nextp)))
|
||||
if nextp == head then break end
|
||||
b = nextp
|
||||
end
|
||||
end
|
||||
|
||||
emu.register_frame_done(function()
|
||||
frames = frames + 1
|
||||
if frames == AT then
|
||||
print(string.format("PROBE: frame %d PC=%s SP=%s A8=%s A14=%s",
|
||||
frames, hex(cpu.state['PC'].value), hex(cpu.state['SP'].value),
|
||||
hex(cpu.state['A8'].value), hex(cpu.state['A14'].value)))
|
||||
heap()
|
||||
-- Scratch return stub test: write jruc self at 01880F00, return address
|
||||
-- at 01880F10, then set SP/PC from the frame hook.
|
||||
prog:write_u16(0x01880F00, 0xC0FF) -- jruc 01880F00 (short, -1 word)
|
||||
prog:write_u32(0x01880F10, 0x01880F00)
|
||||
prog:write_u32(0x01880F20, 0xDEADBEEF)
|
||||
print(string.format("PROBE: spin word readback=%04X ret=%s",
|
||||
prog:read_u16(0x01880F00), hex(prog:read_u32(0x01880F10))))
|
||||
cpu.state['SP'].value = 0x01880F10
|
||||
cpu.state['A8'].value = 0x01880E00
|
||||
cpu.state['PC'].value = 0x01880F00
|
||||
tested = true
|
||||
end
|
||||
if tested and frames == AT + 2 then
|
||||
print(string.format("PROBE: after 2 frames PC=%s SP=%s A8=%s",
|
||||
hex(cpu.state['PC'].value), hex(cpu.state['SP'].value),
|
||||
hex(cpu.state['A8'].value)))
|
||||
end
|
||||
if frames >= ENDF then
|
||||
print(string.format("PROBE: marker 01880F20=%s (should be DEADBEEF, untouched)",
|
||||
hex(u32(0x01880F20))))
|
||||
machine:exit()
|
||||
end
|
||||
end, "vt1200-loader-probe")
|
||||
|
||||
dbg.visible_cpu = cpu
|
||||
dbg.execution_state = 'run'
|
||||
@@ -0,0 +1,12 @@
|
||||
; rel_a.asm -- reldemo caller: has a 32-bit data reference and an absolute call
|
||||
; to a symbol defined in rel_b.asm.
|
||||
.def _start
|
||||
.ref ext_func
|
||||
.ref ext_data
|
||||
.text
|
||||
_start:
|
||||
movi ext_data, a0, L ; 32-bit direct reference (R-RELLONG)
|
||||
move a0, @018F0000h, 1 ; fixed marker (not a relocation)
|
||||
calla ext_func ; 32-bit absolute call
|
||||
rets
|
||||
.end
|
||||
@@ -0,0 +1,10 @@
|
||||
; rel_b.asm -- reldemo callee/data: ext_func and ext_data are defined here.
|
||||
.def ext_func
|
||||
.def ext_data
|
||||
.text
|
||||
ext_func:
|
||||
rets
|
||||
.data
|
||||
ext_data:
|
||||
.long 0CAFEBABEh
|
||||
.end
|
||||
Executable
+79
@@ -0,0 +1,79 @@
|
||||
#!/bin/sh
|
||||
# reldemo.sh -- prove what GSPLNK does with relocations, and that the linked
|
||||
# image is position-dependent.
|
||||
#
|
||||
# 1. assemble two objects that reference each other's symbols (ext_func,
|
||||
# ext_data); the .obj files carry relocation records.
|
||||
# 2. link them with `-a` (the normal app flow): the output COFF must have
|
||||
# nreloc = 0 -- the image is fully resolved.
|
||||
# 3. link the *same* objects at two different origin sets and diff the .text
|
||||
# bytes: they differ, so the image is position-dependent.
|
||||
# 4. link without `-a`: report whether GSPLNK emits a relocatable COFF.
|
||||
#
|
||||
# All scratch/output stays under dwt/loader/reldemo/.
|
||||
set -eu
|
||||
|
||||
ROOT=$(cd "$(dirname "$0")/../.." && pwd)
|
||||
DIR=$(cd "$(dirname "$0")" && pwd)
|
||||
WORK="$DIR/work"
|
||||
OUT="$DIR/build"
|
||||
IMG="$ROOT/tools/tms34010-sdk/1987-05 TMS34010 SDK/1987-11-06 TMS34010 Simulator-C Tools-ASM Tools.img"
|
||||
DOSBOX_CONF="$ROOT/harness/sdk-scratch/dosbox-bench.conf"
|
||||
|
||||
mkdir -p "$WORK" "$OUT"
|
||||
if [ ! -x "$WORK/GSPA.EXE" ]; then
|
||||
mcopy -s -n -i "$IMG" "::/A2/*" "$WORK/"
|
||||
mcopy -s -n -i "$IMG" "::/C2/*" "$WORK/"
|
||||
fi
|
||||
|
||||
cp "$DIR/rel_a.asm" "$WORK/RELA.ASM"
|
||||
cp "$DIR/rel_b.asm" "$WORK/RELB.ASM"
|
||||
|
||||
run_dos() {
|
||||
SDL_VIDEODRIVER=dummy SDL_AUDIODRIVER=dummy \
|
||||
timeout 180 dosbox -conf "$DOSBOX_CONF" -noprimaryconf -nolocalconf \
|
||||
-c "mount c $WORK" -c "c:" "$@" -c "exit" -exit >/dev/null 2>&1
|
||||
}
|
||||
|
||||
printf '%s\n' \
|
||||
'-a' '-o RELABS.out' '-m RELABS.map' '-e _start' \
|
||||
'RELA.obj RELB.obj' \
|
||||
'SECTIONS' '{' \
|
||||
' .text 018C0000h: {}' \
|
||||
' .data 018D0000h: {}' \
|
||||
' .bss 018D8000h: {}' \
|
||||
'}' > "$WORK/RELABS.CMD"
|
||||
printf '%s\n' \
|
||||
'-a' '-o RELABS2.out' '-m RELABS2.map' '-e _start' \
|
||||
'RELA.obj RELB.obj' \
|
||||
'SECTIONS' '{' \
|
||||
' .text 018E0000h: {}' \
|
||||
' .data 018F0000h: {}' \
|
||||
' .bss 018F8000h: {}' \
|
||||
'}' > "$WORK/RELABS2.CMD"
|
||||
printf '%s\n' \
|
||||
'-o RELOC.out' '-m RELOC.map' '-e _start' \
|
||||
'RELA.obj RELB.obj' > "$WORK/RELOC.CMD"
|
||||
sed -i 's/$/\r/' "$WORK"/*.CMD
|
||||
|
||||
rm -f "$WORK"/REL*.OBJ "$WORK"/REL*.OUT "$WORK"/REL*.LST \
|
||||
"$WORK"/REL*.MAP "$WORK"/REL*.HI "$WORK"/REL*.LO
|
||||
run_dos \
|
||||
-c "gspa rela rela.obj -q" \
|
||||
-c "gspa relb relb.obj -q" \
|
||||
-c "gsplnk relabs.cmd" \
|
||||
-c "gsplnk relabs2.cmd"
|
||||
# A missing relocatable output is itself a result; do not fail the script.
|
||||
run_dos -c "gsplnk reloc.cmd" || true
|
||||
|
||||
for f in "$WORK"/REL*.OUT; do
|
||||
[ -f "$f" ] && cp "$f" "$OUT/$(basename "$f" | tr 'A-Z' 'a-z')"
|
||||
done
|
||||
for f in "$WORK"/REL*.OBJ; do
|
||||
[ -f "$f" ] && cp "$f" "$OUT/$(basename "$f" | tr 'A-Z' 'a-z')"
|
||||
done
|
||||
|
||||
python3 "$DIR/coff.py" summary "$OUT/rela.obj" "$OUT/relb.obj" \
|
||||
"$OUT/relabs.out" "$OUT/relabs2.out" "$OUT/reloc.out"
|
||||
echo
|
||||
python3 "$DIR/coff.py" raw "$OUT/relabs.out" "$OUT/relabs2.out"
|
||||
Reference in new issue
Block a user