# HG changeset patch # User John Tsiombikas # Date 1519207213 -7200 # Node ID 51422ea54b9d0b7d074b9f3dfcd58953eacacc94 initial commit diff -r 000000000000 -r 51422ea54b9d Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Makefile Wed Feb 21 12:00:13 2018 +0200 @@ -0,0 +1,35 @@ +asrc = $(wildcard src/*.s) +obj = $(asrc:.s=.o) + +name = test +elf = $(name).elf +bin = $(name).bin +adf = $(name).adf +bootblock = boot.bin + +tool_prefix = m68k-linux-gnu- + +CC = $(tool_prefix)gcc +AS = $(tool_prefix)as +LD = $(tool_prefix)ld +OBJCOPY = $(tool_prefix)objcopy + +ASFLAGS = -m68000 +LDFLAGS = -T amiga.ld -print-gc-sections \ + -L/usr/lib/gcc-cross/m68k-linux-gnu/6 -lgcc + +$(adf): $(bin) $(bootblock) + tools/mk_adf.py $(bootblock) $(bin) $@ + +$(bin): $(elf) + $(OBJCOPY) -O binary $< $@ + +$(elf): $(obj) + $(LD) -o $@ $(obj) -Map link.map $(LDFLAGS) + +$(bootblock): src/boot/boot.o + $(OBJCOPY) -O binary $< $@ + +.PHONY: clean +clean: + rm -f $(obj) $(bin) $(elf) diff -r 000000000000 -r 51422ea54b9d amiga.ld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/amiga.ld Wed Feb 21 12:00:13 2018 +0200 @@ -0,0 +1,27 @@ +OUTPUT_ARCH(m68k) + +MEMORY +{ + chipram : ORIGIN = 0, LENGTH = 0x80000 +} + +PROVIDE (_stacktop = 0x80000); + +SECTIONS { + /* bootblock will load us at 100h, after the interrupt vectors */ + . = 0x100; + + .text : { * (.text); } >chipram + .rodata : { * (.rodata); } >chipram + .data : { * (.data); } >chipram + + .bss ALIGN(4): { + _bss_start = .; + * (.bss); + . = ALIGN(4); + _bss_end = .; + } >chipram + _bss_size = SIZEOF(.bss); + + .dummy ALIGN(4): { LONG(42); } >chipram +} diff -r 000000000000 -r 51422ea54b9d src/boot/boot.s --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/boot/boot.s Wed Feb 21 12:00:13 2018 +0200 @@ -0,0 +1,24 @@ +| vi:filetype=gas68k: + + .equ CMD_READ, 2 + + .equ EXEC_DO_IO, -0x1c8 + +| starting with trackdisk device I/O request pointer in a1 +| load the program at 0x100 and return with that value in a0 +| program length is patched by mk_adf at start - 4 +start: + move.l #0x100, 0x28(%a1) | I/O data pointer + move.l start - 4, 0x24(%a1) | I/O length (1 sector for now) + move.l #512, 0x2c(%a1) | I/O offset (skip first sector) + move.w #CMD_READ, 0x1c(%a1) | I/O command + move.l %a1, -(%sp) + jsr EXEC_DO_IO(%a6) + move.l (%sp)+, %a1 + move.b 0x1f(%a1), %d0 + + move.l #0x100, %a0 + rts + + .ascii "bootblock_end" + .align 4 diff -r 000000000000 -r 51422ea54b9d src/startup.s --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/startup.s Wed Feb 21 12:00:13 2018 +0200 @@ -0,0 +1,27 @@ +| vi:filetype=gas68k: + .text + + .equ REG_COL0, 0xdff180 + + .global start + .global halt_cpu + +start: + | zero the .bss section + move.l #_bss_start, %a0 + move.l #_bss_end, %a1 + cmp.l %a0, %a1 + beq.s 1f | skip zeroing if the section is empty +0: clr.l (%a0)+ + cmp.l %a0, %a1 + bne.s 0b +1: + | setup the stack + move.l #_stacktop, %sp + + | test output + move.w #0xf0f, REG_COL0 +0: bra.b 0b | infloop + +halt_cpu: + stop #0x2700 diff -r 000000000000 -r 51422ea54b9d tools/mk_adf.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/mk_adf.py Wed Feb 21 12:00:13 2018 +0200 @@ -0,0 +1,56 @@ +#!/usr/bin/python +# mk_adf.py +# +# Stuff a given bootblock and payload into an output ADF image. +# +# Written & released by Keir Fraser +# +# This is free and unencumbered software released into the public domain. +# See the file COPYING for more details, or visit . + +import struct, sys + +# Amiga bootblock checksum +def checksum(bb, sum=0): + while len(bb): + x, bb = struct.unpack(">L",bb[:4]), bb[4:] + sum += x[0] + if sum >= (1<<32): + sum -= (1<<32)-1 + return sum + +def main(argv): + bb_f = open(argv[1], "rb") + pl_f = open(argv[2], "rb") + out_f = open(argv[3], "wb") + bb_dat = bb_f.read() + pl_dat = pl_f.read() + + # Construct bootblock header. We will splice in the checksum later. + header = struct.pack(">ccccLLLL", + 'D', 'O', 'S', '\0', # Bootblock signature + 0, # Checksum (placeholder) + 880, # Root block + 0x60060000, # BRA.B +6 + (len(pl_dat) + 511) & ~511) # Payload length, padded + + + # Compute checksum over header, bootblock, and first 512 bytes of payload. + sum = checksum(pl_dat[:512], checksum(bb_dat, checksum(header))) + sum ^= 0xFFFFFFFF + # Splice the computed checksum into the header + header = header[:4] + struct.pack(">L", sum) + header[8:] + # Write out the header and bootblock code + out_f.write(header) + out_f.write(bb_dat) + # Pad bootblock to 512 bytes + for x in xrange((512-len(bb_dat)-len(header))/4): + out_f.write(struct.pack(">L", 0)) + # Write the payload from sector 1 onwards + out_f.write(pl_dat) + # Pad the ADF image to 880kB + for x in xrange((901120-len(pl_dat)-512)/4): + out_f.write(struct.pack(">L", 0)) + +if __name__ == "__main__": + main(sys.argv)