1#!/bin/bash 2 3# SPDX-License-Identifier: MIT 4# 5# Copyright (c) 2020 Eldred Habert 6# 7# Permission is hereby granted, free of charge, to any person obtaining a copy 8# of this software and associated documentation files (the "Software"), to deal 9# in the Software without restriction, including without limitation the rights 10# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11# copies of the Software, and to permit persons to whom the Software is 12# furnished to do so, subject to the following conditions: 13# 14# The above copyright notice and this permission notice shall be included in all 15# copies or substantial portions of the Software. 16# 17# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23# SOFTWARE. 24 25STATE=0 26diff <(xxd $1) <(xxd $2) | while read -r LINE; do 27 if [ $STATE -eq 0 ]; then 28 # Discard first line (line info) 29 STATE=1 30 elif [ "$LINE" = '---' ]; then 31 # Separator between files switches states 32 echo $LINE 33 STATE=3 34 elif grep -Eq '^[0-9]+(,[0-9]+)?[cd][0-9]+(,[0-9]+)?' <<< "$LINE"; then 35 # Line info resets the whole thing 36 STATE=1 37 elif [ $STATE -eq 1 -o $STATE -eq 3 ]; then 38 # Compute the GB address from the ROM offset 39 OFS=$(cut -d ' ' -f 2 <<< "$LINE" | tr -d ':') 40 BANK=$((0x$OFS / 0x4000)) 41 ADDR=$((0x$OFS % 0x4000 + ($BANK != 0) * 0x4000)) 42 # Try finding the preceding symbol closest to the diff 43 if [ $STATE -eq 1 ]; then 44 STATE=2 45 SYMFILE=${1%.*}.sym 46 else 47 STATE=4 48 SYMFILE=${2%.*}.sym 49 fi 50 EXTRA=$(if [ -f "$SYMFILE" ]; then 51 # Read the sym file for such a symbol 52 # Ignore comment lines, only pick matching bank 53 # (The bank regex ignores comments already, make `cut` and `tr` process less lines) 54 grep -Ei $(printf "^%02x:" $BANK) "$SYMFILE" | 55 cut -d ';' -f 1 | 56 tr -d "\r" | 57 while read -r SYMADDR SYM; do 58 SYMADDR=$((0x${SYMADDR#*:})) 59 if [ $SYMADDR -le $ADDR ]; then 60 printf " (%s+%#x)\n" "$SYM" $(($ADDR - $SYMADDR)) 61 fi 62 # TODO: assumes sorted sym files 63 done | tail -n 1 64 fi) 65 printf "%02x:%04x %s\n" $BANK $ADDR $EXTRA 66 fi 67 if [ $STATE -eq 2 -o $STATE -eq 4 ]; then 68 OFS=$(cut -d ' ' -f 2 <<< "$LINE" | tr -d ':') 69 BANK=$((0x$OFS / 0x4000)) 70 ADDR=$((0x$OFS % 0x4000 + ($BANK != 0) * 0x4000)) 71 printf "%s %02x:%04x: %s\n" "${LINE:0:1}" $BANK $ADDR "${LINE#*: }" 72 fi 73done 74