Emily's Z80 assembler for the Gameboy.
Revision | 7664ab3d2931081abe12f7f9a773fa7a678673eb (tree) |
---|---|
Time | 2021-03-05 14:37:00 |
Author | AlaskanEmily <emily@alas...> |
Commiter | AlaskanEmily |
Add arguments for romsize and bank count.
@@ -835,7 +835,81 @@ def assembleFile(block, path): | ||
835 | 835 | if len(block.data) & 1: |
836 | 836 | block.pushByte(0xFF) |
837 | 837 | |
838 | -for p in sys.argv[1:]: | |
838 | +# Default rom size. | |
839 | +romsize = 0x8000 | |
840 | +def setRomSize(n): | |
841 | + romsize = int(n, 0) | |
842 | + | |
843 | +num_banks = None | |
844 | +def setNumBanks(n): | |
845 | + num_banks = int(n, 0) | |
846 | + | |
847 | +i = 1 | |
848 | +num_args = len(sys.argv) | |
849 | + | |
850 | +OPTIONS=( | |
851 | + ("-s", "--size", setRomSize, "Sets the rom size."), | |
852 | + ("-b", "--banks", setNumBanks, "Sets the number of banks.") | |
853 | +) | |
854 | + | |
855 | +def MaybeParseArgument(short, long, proc, _help): | |
856 | + global i | |
857 | + assert i < num_args | |
858 | + opt = sys.argv[i] | |
859 | + if opt == short or opt == long: | |
860 | + i += 1 | |
861 | + if i >= num_args: | |
862 | + val = None | |
863 | + else: | |
864 | + val = sys.argv[i] | |
865 | + elif opt.startswith(short + "="): | |
866 | + val = sys.argv[len(short)+1:] | |
867 | + elif opt.startswith(long + "="): | |
868 | + val = sys.argv[len(long)+1:] | |
869 | + else: | |
870 | + return False | |
871 | + | |
872 | + if not val: | |
873 | + print(val + " requires an argument") | |
874 | + else: | |
875 | + try: | |
876 | + proc(val) | |
877 | + except: | |
878 | + return False | |
879 | + return True | |
880 | + | |
881 | +def usage(): | |
882 | + print("Emily's Gameboy Assembler") | |
883 | + print("USAGE: " + sys.argv[0] + " [options] <files>") | |
884 | + print("OPTIONS:") | |
885 | + print(" --help|-h\tDisplays this message then exits.") | |
886 | + for opt in OPTIONS: | |
887 | + print(" " + opt[0] + "|" + opt[1] + "\t" + opt[3]) | |
888 | + | |
889 | +while i < num_args: | |
890 | + if sys.argv[i] == "--" or not sys.argv[i].startswith("-"): | |
891 | + break | |
892 | + | |
893 | + arg = sys.argv[i] | |
894 | + if arg in ("--help", "-h"): | |
895 | + usage() | |
896 | + sys.exit(0) | |
897 | + | |
898 | + found = False | |
899 | + for opt in OPTIONS: | |
900 | + found = MaybeParseArgument(*opt) | |
901 | + if found: | |
902 | + break | |
903 | + | |
904 | + if not found: | |
905 | + print("Error in option '" + arg + "'") | |
906 | + usage() | |
907 | + sys.exit(1) | |
908 | + | |
909 | + i += 1 | |
910 | + | |
911 | +while i < num_args: | |
912 | + p = sys.argv[i] | |
839 | 913 | included_names = set() |
840 | 914 | b = Block(p) |
841 | 915 | try: |
@@ -844,30 +918,33 @@ for p in sys.argv[1:]: | ||
844 | 918 | except: |
845 | 919 | print("Error in " + p) |
846 | 920 | raise |
921 | + i += 1 | |
847 | 922 | |
848 | 923 | if len(blocks) == 0: |
849 | 924 | sys.exit(0) |
850 | 925 | |
851 | -max_bank = 0 | |
852 | -for b in blocks: | |
853 | - if b.bank == None: | |
854 | - b.bank = 0 | |
855 | - else: | |
856 | - if b.bank > max_bank: | |
857 | - max_bank = b.bank | |
858 | - if b.base == None: | |
859 | - b.error("!bank specified, but no !orig") | |
926 | +if num_banks == None: | |
927 | + max_bank = 0 | |
928 | + for b in blocks: | |
929 | + if b.bank == None: | |
930 | + b.bank = 0 | |
860 | 931 | else: |
861 | - if b.bank == 0 and b.base >= 0x4000: | |
862 | - b.error("Invalid base for bank 0") | |
863 | - elif b.bank == 0 and b.base + len(b.data) >= 0x4000: | |
864 | - b.error("Block is too large to fit into bank 0") | |
865 | - if b.bank != 0 and (b.base < 0x4000 or b.base >= 0x8000): | |
866 | - b.error("Invalid base for bank " + str(b.bank)) | |
867 | - elif b.bank == 0 and b.base + len(b.data) >= 0x8000: | |
868 | - b.error("Block is too large to fit into bank " + str(b.bank)) | |
932 | + if b.bank > max_bank: | |
933 | + max_bank = b.bank | |
934 | + if b.base == None: | |
935 | + b.error("!bank specified, but no !orig") | |
936 | + else: | |
937 | + if b.bank == 0 and b.base >= 0x4000: | |
938 | + b.error("Invalid base for bank 0") | |
939 | + elif b.bank == 0 and b.base + len(b.data) >= 0x4000: | |
940 | + b.error("Block is too large to fit into bank 0") | |
941 | + if b.bank != 0 and (b.base < 0x4000 or b.base >= 0x8000): | |
942 | + b.error("Invalid base for bank " + str(b.bank)) | |
943 | + elif b.bank == 0 and b.base + len(b.data) >= 0x8000: | |
944 | + b.error("Block is too large to fit into bank " + str(b.bank)) | |
945 | + num_banks = max_bank | |
869 | 946 | |
870 | -bank_spans=[[]] * (max_bank + 1) | |
947 | +bank_spans=[[]] * (num_banks + 1) | |
871 | 948 | |
872 | 949 | # First, place all already originated blocks. |
873 | 950 | for b in blocks: |
@@ -957,11 +1034,13 @@ for b in blocks: | ||
957 | 1034 | asc = hex(a[1])[2:].upper().rjust(4, '0') |
958 | 1035 | debug.write(bank_name + ":" + addr + " .asc:" + asc + "\n") |
959 | 1036 | |
960 | -while at < 0x7FF0: | |
1037 | +print("ROM used " + str(at) + " bytes of " + str(romsize) + " (" + str(int(at / (romsize / 100.0))) + "%)") | |
1038 | + | |
1039 | +while at < romsize - 16: | |
961 | 1040 | out.write(zero16) |
962 | 1041 | at += 16 |
963 | 1042 | |
964 | -while (at & 0x0FFF) != 0 or at < 0x8000: | |
1043 | +while at < romsize: | |
965 | 1044 | out.write(zero) |
966 | 1045 | at += 1 |
967 | 1046 |