#!/bin/bash
#########################################################################################################
##
## Name:            disassemble_mz2z009e.sh
## Created:         March 2026
## Author(s):       Philip Smart
## Description:     MZ-2Z009E Disk BASIC disassembly and re-assembly tool
##                  This script performs a full round-trip:
##                    1. Disassembles mz2z009e.bin using dz80
##                    2. Post-processes the output for GLASS assembler compatibility
##                       (fixes undefined label references, compacts repeated DB into DS,
##                        reformats keyword tables)
##                    3. Re-assembles with the GLASS Z80 assembler
##                    4. Verifies the re-assembled binary is identical to the original
##
## Credits:
## Copyright:       (c) 2026 Philip Smart <philip.smart@net2net.org>
##
## History:         March 2026 - Initial script (based on MZ-5Z009 version).
##
#########################################################################################################
## This source file is free software: you can redistribute it and#or modify
## it under the terms of the GNU General Public License as published
## by the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## This source file is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program.  If not, see <http://www.gnu.org/licenses/>.
#########################################################################################################

DISDIR="$(cd "$(dirname "$0")" && pwd)"
OUTDIR="${DISDIR}/tmp"

# Tools
DZ80="/srv/dvlp/Projects/RFS/tools/dz80"
POSTPROCESS="${DISDIR}/postprocess_dz80.py"

# Use glass.jar from the RFS project if available.
GLASS_JAR=""
for candidate in \
    "${DISDIR}/glass.jar" \
    "/srv/dvlp/Projects/RFS/tools/glass.jar" \
    "$(which glass.jar 2>/dev/null)"; do
    if [ -f "$candidate" ]; then
        GLASS_JAR="$candidate"
        break
    fi
done

if [ -z "$GLASS_JAR" ]; then
    echo "ERROR: glass.jar not found."
    exit 1
fi

ORIGINAL_BIN="${DISDIR}/mz2z009e.bin"
DZ80_INI="${DISDIR}/mz2z009e.ini"

# Verify prerequisites exist
if [ ! -f "${ORIGINAL_BIN}" ]; then
    echo "ERROR: Original binary not found at ${ORIGINAL_BIN}"
    echo "       This is the raw MZ-2Z009E Disk BASIC binary (36864 bytes)."
    exit 1
fi

if [ ! -f "${DZ80_INI}" ]; then
    echo "ERROR: dz80 configuration not found at ${DZ80_INI}"
    exit 1
fi

if [ ! -x "${DZ80}" ]; then
    echo "ERROR: dz80 disassembler not found at ${DZ80}"
    exit 1
fi

if [ ! -f "${POSTPROCESS}" ]; then
    echo "ERROR: Post-processor not found at ${POSTPROCESS}"
    exit 1
fi

mkdir -p "${OUTDIR}"

echo "MZ-2Z009E Disk BASIC Disassembly & Re-assembly Tool"
echo "===================================================="
echo "  Source binary: ${ORIGINAL_BIN}"
echo "  dz80 config:  ${DZ80_INI}"
echo "  Glass:        ${GLASS_JAR}"
echo "  Output dir:   ${OUTDIR}"
echo ""

# ---- Step 1: Disassemble with dz80 ----
echo "--- Step 1: Disassembling with dz80 ---"
# dz80 uses dz80.ini from CWD (symlink -> mz2z009e.ini), so we cd to the dis dir
SAVEDCWD="$(pwd)"
cd "${DISDIR}"
${DZ80} -l mz2z009e.bin mz2z009e_dz80.asm
DZ80_RC=$?
cd "${SAVEDCWD}"

if [ ${DZ80_RC} -ne 0 ]; then
    echo "ERROR: dz80 disassembly failed (exit code ${DZ80_RC})."
    exit 1
fi
echo "  dz80 output: ${DISDIR}/mz2z009e_dz80.asm"
echo ""

# ---- Step 2: Post-process for GLASS compatibility ----
echo "--- Step 2: Post-processing for GLASS compatibility ---"
# Post-process in-place so dis/mz2z009e_dz80.asm is the final compacted version,
# and also copy to tmp/ for assembly.
python3 "${POSTPROCESS}" "${DISDIR}/mz2z009e_dz80.asm"
if [ $? -ne 0 ]; then
    echo "ERROR: Post-processing failed."
    exit 1
fi
cp "${DISDIR}/mz2z009e_dz80.asm" "${OUTDIR}/mz2z009e_dz80.asm"
echo ""

# ---- Step 3: Assemble with GLASS ----
echo "--- Step 3: Assembling with GLASS Z80 assembler ---"
java -jar "${GLASS_JAR}" "${OUTDIR}/mz2z009e_dz80.asm" "${OUTDIR}/mz2z009e.bin" "${OUTDIR}/mz2z009e.sym"

if [ $? -ne 0 ]; then
    echo ""
    echo "ERROR: Assembly failed. Fix errors above and retry."
    exit 1
fi
echo "  Binary:  ${OUTDIR}/mz2z009e.bin"
echo "  Symbols: ${OUTDIR}/mz2z009e.sym"
echo ""

# ---- Step 4: Verify binary match ----
echo "--- Step 4: Verifying binary match ---"
if cmp -s "${ORIGINAL_BIN}" "${OUTDIR}/mz2z009e.bin"; then
    echo "  PASS: Re-assembled binary is identical to original."
else
    ORIG_SIZE=$(wc -c < "${ORIGINAL_BIN}")
    ASM_SIZE=$(wc -c < "${OUTDIR}/mz2z009e.bin")
    echo "  FAIL: Re-assembled binary differs from original!"
    echo "    Original size:  ${ORIG_SIZE} bytes"
    echo "    Assembled size: ${ASM_SIZE} bytes"
    echo ""
    echo "  Run 'cmp -l ${ORIGINAL_BIN} ${OUTDIR}/mz2z009e.bin' for details."
    exit 1
fi
echo ""

echo "===================================================="
echo "Complete. Output files in ${OUTDIR}/"
ls -la "${OUTDIR}"/mz2z009e*
