#!/bin/python

''''
Script to convert some TRS-80 CMD files to binary. The result
may be input to a generic Z80 disassembler. 
Testing: no binary output yet, 

fjkraan@electrickery.nl, 2025-05-06

also see: https://www.trs-80.com/wordpress/tips/formats/#cmdfile
and: https://jimlawless.net/blog/posts/trs80-cmd/

01 record (for data transfer):
  01LLAAAANNNNNNNN...NN
  | | |   |
  | | |   data bytes
  | | two address bytes (lsb first)
  | length byte, (2 address bytes + the number of data bytes)
  record type

02 record (for control transfer):
  02LLAAAA
  | | |   
  | | two address bytes (lsb first)
  | length byte, (2 address bytes + the number of data bytes)
  |  for length < 3, add 256
  record type
  
  
05 program name:
 05LLNNNN....
 | | |
 | | program name in ASCII
 | length byte, (2 address bytes + the number of data bytes)
 record type
 
Values up to 0x1F are valid, see the LDOSQ1-4.PDF for a (more) complete
list (https://tim-mann.org/trs80/doc/ldosq1-4.pdf).

'''

import sys


if len(sys.argv) > 1:
    binFile = sys.argv[1]
else:
    print("Usage: python cmdDecode.py <asmFile>")
    sys.exit()

f = sys.argv[1]

def printHex(bin):
    print("0x%02x " % bin, end='')
def printHexAddr(bin):
    print("0x%04x " % bin, end='')
    
def printChar(bin):
    print(bin.decode("utf-8"), end='')

def processData():
    recLen = ord(f.read(1))
    if recLen < 3: recLen += 0x100
    print("[", end='')
    printHex(recLen)
    print("] {", end='')
    addrLsb = ord(f.read(1))
    addrMsb = ord(f.read(1))
    printHexAddr(addrLsb + addrMsb * 256)
    print("} ", end='')
    
    for i in range(recLen - 2):
        printHex(ord(f.read(1)))
    print()

def processTransfer():
    recLen = ord(f.read(1))
    print("[", end='')
    printHex(recLen)
    print("] ", end='')
    addrMsb = ord(f.read(1))
    addrLsb = ord(f.read(1))
    print("{", end='')
    printHexAddr(addrLsb + addrMsb * 256)
    print("} ", end='')
    print()

def processName():
    recLen = ord(f.read(1))
    print("[", end='')
    printHex(recLen)
    print("] ", end='')
    print("'", end='')
    for i in range(recLen):
        printChar(f.read(1))
    print("'")


with open(f, "rb") as f:
    while(1):
        recHeader = f.read(1)
        if len(recHeader) == 0:
            break
        if ord(recHeader) == 0x01:
            print("Data: ", end='')
            processData()
        elif ord(recHeader) == 0x02:
            print("Transfer: ", end='')
            processTransfer()
            break
        elif ord(recHeader) == 0x05:
            print("Name: ", end='')
            processName()
        else:
            print("Unk: " + str(printHex(ord(recHeader))))
            byte = f.read(1)
            if len(byte) == 0:
                print("Done.")
                break
            recLen = ord(byte)
            dummy = f.read(recLen)

f.close()



'''

'''
