Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
| blog:ql_dev1 [2021/12/14 12:55] – john | blog:ql_dev1 [2021/12/16 11:03] (current) – john | ||
|---|---|---|---|
| Line 23: | Line 23: | ||
| * {{ : | * {{ : | ||
| * {{ : | * {{ : | ||
| + | * {{ : | ||
| === Sample C68 Makefile === | === Sample C68 Makefile === | ||
| Line 34: | Line 35: | ||
| < | < | ||
| # Sample makefile for C68 projects | # Sample makefile for C68 projects | ||
| + | |||
| + | ################################# | ||
| + | # Temporarily add the cross | ||
| + | # compiler location to the path | ||
| + | ################################# | ||
| + | SHELL := /bin/bash | ||
| + | PREFIX = / | ||
| + | PATH := ${PREFIX}/ | ||
| ################################# | ################################# | ||
| Line 39: | Line 48: | ||
| # and friends | # and friends | ||
| ################################# | ################################# | ||
| - | PREFIX = / | + | CC = qcc |
| - | PATH = ${PREFIX}/ | + | LD = qld |
| - | CC = ${PREFIX}/ | + | AS = as68 |
| - | LD = ${PREFIX}/ | + | CPP = qcpp |
| - | AS = ${PREFIX}/ | + | |
| - | CPP = ${PREFIX}/ | + | |
| ################################# | ################################# | ||
| Line 59: | Line 66: | ||
| ################################# | ################################# | ||
| ASFLAGS = | ASFLAGS = | ||
| - | LDFLAGS = | + | LDFLAGS = -v |
| CFLAGS = -O | CFLAGS = -O | ||
| Line 104: | Line 111: | ||
| $(CC) $(CFLAGS) $(INCLUDES) -c other.c | $(CC) $(CFLAGS) $(INCLUDES) -c other.c | ||
| </ | </ | ||
| + | |||
| + | === Running C68 === | ||
| + | |||
| + | If you use a sample makefile such as the one above, you should get an output such as this: | ||
| + | |||
| + | < | ||
| + | $ make | ||
| + | qcc -O -c test.c | ||
| + | qcc -O -c other.c | ||
| + | qld -v test.o other.o | ||
| + | ld v1.22 QL 68000 SROFF Linker | ||
| + | COMMENT: C68 crt_o v4.24f | ||
| + | COMMENT: C68 libc_a v4.24f | ||
| + | |||
| + | --------------------------- | ||
| + | SECTION | ||
| + | --------------------------- | ||
| + | TEXT | ||
| + | DATA 3ad6 2FA | ||
| + | UDATA | ||
| + | --------------------------- | ||
| + | Program length | ||
| + | Relocation table = 1ef | ||
| + | -------------------- | ||
| + | Memory Usage | ||
| + | Buffer Usage | ||
| + | -------------------- | ||
| + | game: dataspace 870 (366) | ||
| + | |||
| + | Link completed | ||
| + | </ | ||
| + | |||
| + | This is mostly easy to understand - two passes of the compiler; one for each source file, then the linker takes the two object files, adds-in //crt.o// and any functions from the //standard library//. The output is a little more verbose than the usual compiler though - an important element being the // | ||
| + | |||
| + | If you hexdump the binary, you will see some trailing data that mirrors that // | ||
| + | |||
| + | < | ||
| + | $ hexdump -C game | ||
| + | . | ||
| + | . | ||
| + | . | ||
| + | 00003fa0 | ||
| + | 00003fb0 | ||
| + | 00003fc0 | ||
| + | 00003fc8 | ||
| + | </ | ||
| + | |||
| + | This is referred to as the //xtcc field// and is used by the **qlzip** utility when unpacking on the QL native filesystem to restore the needed metadata about the application. | ||
| ==== GCC Cross-Compiler ==== | ==== GCC Cross-Compiler ==== | ||
| Line 127: | Line 182: | ||
| * https:// | * https:// | ||
| * Works with native QL floppy disks (DD 720K, HD 1440K or ED 3.2MB) or disk images to transfer files to/from those devices from Linux. | * Works with native QL floppy disks (DD 720K, HD 1440K or ED 3.2MB) or disk images to transfer files to/from those devices from Linux. | ||
| + | |||
| + | ==== Other Stuff ==== | ||
| + | |||
| + | I wrote a quick Python script to print out the value of an XTcc field in a binary produced by C68, GCC or similar. This is useful when copying an executable into a QL floppy or hard drive filesystem and you need to set the //dataspace parameter//: | ||
| + | |||
| + | < | ||
| + | # | ||
| + | |||
| + | #################################### | ||
| + | # | ||
| + | # Prints out the value of a Sinclar | ||
| + | # QL binary XTcc field, as needed to | ||
| + | # turn it into an executable file | ||
| + | # on the QL itself, or when transferred | ||
| + | # using qltool. | ||
| + | # | ||
| + | # John Snowdon, 2021 | ||
| + | # | ||
| + | #################################### | ||
| + | |||
| + | import sys | ||
| + | import os | ||
| + | |||
| + | if len(sys.argv) < 2: | ||
| + | print(" | ||
| + | sys.exit(-1) | ||
| + | |||
| + | ql_filename = sys.argv[1] | ||
| + | if (os.path.exists(ql_filename)): | ||
| + | f = open(ql_filename, | ||
| + | filedata = f.read() | ||
| + | offset = filedata.find(b' | ||
| + | |||
| + | if offset: | ||
| + | # First byte of " | ||
| + | f.seek(offset + 5) | ||
| + | dataspace = f.read(4) | ||
| + | |||
| + | # Print out the value of the dataspace field | ||
| + | print(int.from_bytes(dataspace, | ||
| + | |||
| + | f.close() | ||
| + | |||
| + | else: | ||
| + | print(" | ||
| + | sys.exit(-1) | ||
| + | </ | ||
| + | |||
| + | Just call the script with the name of your C68 executable. For example: | ||
| + | |||
| + | < | ||
| + | $ xtcc game.bin | ||
| + | 868 | ||
| + | </ | ||
| + | |||
| + | ... the value printed is the size of the dataspace needed. So you would then copy and mark your binary with qltools as follows: | ||
| + | |||
| + | < | ||
| + | $ xtcc game.bin | ||
| + | 868 | ||
| + | $ qltools floppy.img -W game.bin | ||
| + | $ qltools floppy.img -x game.bin 868 | ||
| + | </ | ||
| + | |||
| + | Or even easier, embed the xtcc call in backticks: | ||
| + | |||
| + | < | ||
| + | $ qltools floppy.img -W game.bin | ||
| + | $ qltools floppy.img -x game.bin `xtcc game.bin` | ||
| + | </ | ||
| + | |||