initial commit
authorJohn Tsiombikas <nuclear@member.fsf.org>
Tue, 24 Jul 2018 19:47:24 +0000 (22:47 +0300)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Tue, 24 Jul 2018 19:47:24 +0000 (22:47 +0300)
.gitignore [new file with mode: 0644]
Makefile.amiga [new file with mode: 0644]
amiga.ld [new file with mode: 0644]
fs-uae.conf [new file with mode: 0644]
src/amiga/boot/boot.s [new file with mode: 0644]
src/amiga/hwregs.h [new file with mode: 0644]
src/amiga/main.c [new file with mode: 0644]
src/amiga/startup.s [new file with mode: 0644]
tools/mk_adf.py [new file with mode: 0755]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..52d0701
--- /dev/null
@@ -0,0 +1,7 @@
+*.o
+*.d
+*.swp
+*.adf
+*.bin
+*.elf
+link.map
diff --git a/Makefile.amiga b/Makefile.amiga
new file mode 100644 (file)
index 0000000..38fe12d
--- /dev/null
@@ -0,0 +1,42 @@
+src = $(wildcard src/*.c) \
+         $(wildcard src/amiga/*.c)
+asrc = $(wildcard src/amiga/*.s)
+obj = $(src:.c=.o) $(asrc:.s=.o) 
+
+name = retrocrawl
+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
+CFLAGS = -m68000 -ffreestanding -pedantic -Wall -Os
+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/amiga/boot/boot.o
+       $(OBJCOPY) -O binary $< $@
+
+.PHONY: clean
+clean:
+       rm -f $(obj) src/amiga/boot/boot.o $(bin) $(elf)
+
+.PHONY: run
+run:
+       fs-uae
diff --git a/amiga.ld b/amiga.ld
new file mode 100644 (file)
index 0000000..2183783
--- /dev/null
+++ b/amiga.ld
@@ -0,0 +1,25 @@
+OUTPUT_ARCH(m68k)
+
+PROVIDE (_stacktop = 0x80000);
+
+SECTIONS {
+       /* bootblock will load us at 10000h */
+       . = 0x10000;
+
+       .startup : { * (.startup); }
+       .text : { * (.text); }
+       .rodata : { * (.rodata); }
+       .data : { * (.data); }
+
+       .dummy ALIGN(4): { LONG(42); }
+
+       .bss ALIGN(4): {
+               _bss_start = .;
+               * (.bss);
+               . = ALIGN(4);
+               _bss_end = .;
+       }
+       _bss_size = SIZEOF(.bss);
+
+       _mem_start = .;
+}
diff --git a/fs-uae.conf b/fs-uae.conf
new file mode 100644 (file)
index 0000000..fa9c69e
--- /dev/null
@@ -0,0 +1,19 @@
+[config]
+keep_aspect = 1
+floppies_dir = $HOME/amiga/disks
+floppy_overlays_dir = $HOME/amiga/disks
+kickstarts_dir = $HOME/amiga/rom
+logs_dir = $HOME/amiga/logs
+screenshots_output_dir = $HOME/amiga/shots
+floppy_drive_speed = 0
+floppy_drive_volume = 0
+kickstart_file = $HOME/amiga/rom/kickstart-1.3.rom
+console_debugger = 1
+warp_mode = 1
+chip_memory = 512
+fast_memory = 0
+slow_memory = 0
+initial_grab_input = 0
+serial_port = /tmp/uaetty
+
+floppy_drive_0 = retrocrawl.adf
diff --git a/src/amiga/boot/boot.s b/src/amiga/boot/boot.s
new file mode 100644 (file)
index 0000000..4f1ccb7
--- /dev/null
@@ -0,0 +1,20 @@
+| vi:filetype=gas68k:
+       .equ CMD_READ, 2
+       .equ EXEC_DO_IO, -0x1c8
+       .equ LOADADDR,  0x10000
+
+start:
+| starting with trackdisk device I/O request pointer in a1
+| load the program at 0x100 and jump there
+| program length is patched by mk_adf just before start
+       move.l -6(%pc), %d0             | get program size
+       move.w #0x080, 0xdff180
+       move.l %d0, 0x24(%a1)           | I/O length
+       move.l #LOADADDR, 0x28(%a1)     | I/O data pointer
+       move.l #512, 0x2c(%a1)          | I/O offset (skip first sector)
+       move.w #CMD_READ, 0x1c(%a1)     | I/O command
+       jsr EXEC_DO_IO(%a6)
+       move.w #0xf0f, 0xdff180
+
+       jmp LOADADDR
+       .align 4
diff --git a/src/amiga/hwregs.h b/src/amiga/hwregs.h
new file mode 100644 (file)
index 0000000..04385e5
--- /dev/null
@@ -0,0 +1,444 @@
+#ifndef HWREGS_H_
+#define HWREGS_H_
+
+#include "inttypes.h"
+
+#define REG_BASE_ADDR  0xdff000
+
+#define REGN_BLTDDAT   0x000
+#define REGN_DMACONR   0x002
+#define REGN_VPOSR             0x004
+#define REGN_VHPOSR            0x006
+#define REGN_DSKDATR   0x008
+#define REGN_JOY0DAT   0x00a
+#define REGN_JOY1DAT   0x00c
+#define REGN_CLXDAT            0x00e
+#define REGN_ADKCONR   0x010
+#define REGN_POT0DAT   0x012
+#define REGN_POT1DAT   0x014
+#define REGN_POTGOR            0x016
+#define REGN_SERDATR   0x018
+#define REGN_DSKBYTR   0x01a
+#define REGN_INTENAR   0x01c
+#define REGN_INTREQR   0x01e
+#define REGN_DSKPTH            0x020
+#define REGN_DSKPTL            0x022
+#define REGN_DSKLEN            0x024
+#define REGN_DSKDAT            0x026
+#define REGN_REFPTR            0x028
+#define REGN_VPOSW             0x02a
+#define REGN_VHPOSW            0x02c
+#define REGN_COPCON            0x02e
+#define REGN_SERDAT            0x030
+#define REGN_SERPER            0x032
+#define REGN_POTGO             0x034
+#define REGN_JOYTEST   0x036
+#define REGN_STREQU            0x038
+#define REGN_STRVBL            0x03a
+#define REGN_STRHOR            0x03c
+#define REGN_STRLONG   0x03e
+#define REGN_BLTCON0   0x040
+#define REGN_BLTCON1   0x042
+#define REGN_BLTAFWM   0x044
+#define REGN_BLTALWM   0x046
+#define REGN_BLTCPTH   0x048
+#define REGN_BLTCPTL   0x04a
+#define REGN_BLTBPTH   0x04c
+#define REGN_BLTBPTL   0x04e
+#define REGN_BLTAPTH   0x050
+#define REGN_BLTAPTL   0x052
+#define REGN_BLTDPTH   0x054
+#define REGN_BLTDPTL   0x056
+#define REGN_BLTSIZE   0x058
+#define REGN_BLTCON0L  0x05a
+#define REGN_BLTSIZV   0x05c
+#define REGN_BLTSIZH   0x05e
+#define REGN_BLTCMOD   0x060
+#define REGN_BLTBMOD   0x062
+#define REGN_BLTAMOD   0x064
+#define REGN_BLTDMOD   0x066
+#define REGN_BLTCDAT   0x070
+#define REGN_BLTBDAT   0x072
+#define REGN_BLTADAT   0x074
+#define REGN_SPRHDAT   0x078
+#define REGN_DENISEID  0x07c
+#define REGN_DSKSYNC   0x07e
+#define REGN_COP1LCH   0x080
+#define REGN_COP1LCL   0x082
+#define REGN_COP2LCH   0x084
+#define REGN_COP2LCL   0x086
+#define REGN_CMPJMP1   0x088
+#define REGN_CMPJMP2   0x08a
+#define REGN_COPINS            0x08c
+#define REGN_DIWSTART  0x08e
+#define REGN_DIWSTOP   0x090
+#define REGN_DDFSTART  0x092
+#define REGN_DDFSTOP   0x094
+#define REGN_DMACON            0x096
+#define REGN_CLXCON            0x098
+#define REGN_INTENA            0x09a
+#define REGN_INTREQ            0x09c
+#define REGN_ADKCON            0x09e
+
+#define REGN_AUDIO_LCH(c)      (REGN_AUDIO0_BASE + (c) * 16 + 0)
+#define REGN_AUDIO_LCL(c)      (REGN_AUDIO0_BASE + (c) * 16 + 2)
+#define REGN_AUDIO_LEN(c)      (REGN_AUDIO0_BASE + (c) * 16 + 4)
+#define REGN_AUDIO_PER(c)      (REGN_AUDIO0_BASE + (c) * 16 + 6)
+#define REGN_AUDIO_VOL(c)      (REGN_AUDIO0_BASE + (c) * 16 + 8)
+#define REGN_AUDIO_DAT(c)      (REGN_AUDIO0_BASE + (c) * 16 + 10)
+
+#define REGN_AUDIO0_BASE       0x0a0
+#define REGN_AUD0LCH           (REGN_AUDIO0_BASE + 0)
+#define REGN_AUD0LCL           (REGN_AUDIO0_BASE + 2)
+#define REGN_AUD0LEN           (REGN_AUDIO0_BASE + 4)
+#define REGN_AUD0PER           (REGN_AUDIO0_BASE + 6)
+#define REGN_AUD0VOL           (REGN_AUDIO0_BASE + 8)
+#define REGN_AUD0DAT           (REGN_AUDIO0_BASE + 10)
+#define REGN_AUDIO1_BASE       0x0b0
+#define REGN_AUD1LCH           (REGN_AUDIO1_BASE + 0)
+#define REGN_AUD1LCL           (REGN_AUDIO1_BASE + 2)
+#define REGN_AUD1LEN           (REGN_AUDIO1_BASE + 4)
+#define REGN_AUD1PER           (REGN_AUDIO1_BASE + 6)
+#define REGN_AUD1VOL           (REGN_AUDIO1_BASE + 8)
+#define REGN_AUD1DAT           (REGN_AUDIO1_BASE + 10)
+#define REGN_AUDIO2_BASE       0x0c0
+#define REGN_AUD2LCH           (REGN_AUDIO2_BASE + 0)
+#define REGN_AUD2LCL           (REGN_AUDIO2_BASE + 2)
+#define REGN_AUD2LEN           (REGN_AUDIO2_BASE + 4)
+#define REGN_AUD2PER           (REGN_AUDIO2_BASE + 6)
+#define REGN_AUD2VOL           (REGN_AUDIO2_BASE + 8)
+#define REGN_AUD2DAT           (REGN_AUDIO2_BASE + 10)
+#define REGN_AUDIO3_BASE       0x0d0
+#define REGN_AUD3LCH           (REGN_AUDIO3_BASE + 0)
+#define REGN_AUD3LCL           (REGN_AUDIO3_BASE + 2)
+#define REGN_AUD3LEN           (REGN_AUDIO3_BASE + 4)
+#define REGN_AUD3PER           (REGN_AUDIO3_BASE + 6)
+#define REGN_AUD3VOL           (REGN_AUDIO3_BASE + 8)
+#define REGN_AUD3DAT           (REGN_AUDIO3_BASE + 10)
+
+#define REGN_BPL1PTH   0x0e0
+#define REGN_BPL1PTL   0x0e2
+#define REGN_BPL2PTH   0x0e4
+#define REGN_BPL2PTL   0x0e6
+#define REGN_BPL3PTH   0x0e8
+#define REGN_BPL3PTL   0x0ea
+#define REGN_BPL4PTH   0x0ec
+#define REGN_BPL4PTL   0x0ee
+#define REGN_BPL5PTH   0x0f0
+#define REGN_BPL5PTL   0x0f2
+#define REGN_BPL6PTH   0x0f4
+#define REGN_BPL6PTL   0x0f6
+#define REGN_BPLCON0   0x100
+#define REGN_BPLCON1   0x102
+#define REGN_BPLCON2   0x104
+#define REGN_BPLCON3   0x106
+#define REGN_BPL1MOD   0x108
+#define REGN_BPL2MOD   0x10a
+#define REGN_BPL1DAT   0x110
+#define REGN_BPL2DAT   0x112
+#define REGN_BPL3DAT   0x114
+#define REGN_BPL4DAT   0x116
+#define REGN_BPL5DAT   0x118
+#define REGN_BPL6DAT   0x11a
+
+#define REGN_SPR0PTH   0x120
+#define REGN_SPR0PTL   0x122
+#define REGN_SPR1PTH   0x124
+#define REGN_SPR1PTL   0x126
+#define REGN_SPR2PTH   0x128
+#define REGN_SPR2PTL   0x12a
+#define REGN_SPR3PTH   0x12c
+#define REGN_SPR3PTL   0x12e
+#define REGN_SPR4PTH   0x130
+#define REGN_SPR4PTL   0x132
+#define REGN_SPR5PTH   0x134
+#define REGN_SPR5PTL   0x136
+#define REGN_SPR6PTH   0x138
+#define REGN_SPR6PTL   0x13a
+#define REGN_SPR7PTH   0x13c
+#define REGN_SPR7PTL   0x13e
+
+#define REGN_SPRITE_POS(s)     (REGN_SPRITE0_BASE + (s) * 8 + 0)
+#define REGN_SPRITE_CTL(s)     (REGN_SPRITE0_BASE + (s) * 8 + 2)
+#define REGN_SPRITE_DATA(s)    (REGN_SPRITE0_BASE + (s) * 8 + 4)
+#define REGN_SPRITE_DATB(s)    (REGN_SPRITE0_BASE + (s) * 8 + 6)
+
+#define REGN_SPRITE0_BASE      0x140
+#define REGN_SPR0POS           REGN_SPRITE_POS(0)
+#define REGN_SPR0CTL           REGN_SPRITE_CTL(0)
+#define REGN_SPR0DATA          REGN_SPRITE_DATA(0)
+#define REGN_SPR0DATB          REGN_SPRITE_DATB(0)
+#define REGN_SPRITE1_BASE      0x148
+#define REGN_SPR1POS           REGN_SPRITE_POS(1)
+#define REGN_SPR1CTL           REGN_SPRITE_CTL(1)
+#define REGN_SPR1DATA          REGN_SPRITE_DATA(1)
+#define REGN_SPR1DATB          REGN_SPRITE_DATB(1)
+#define REGN_SPRITE2_BASE      0x150
+#define REGN_SPR2POS           REGN_SPRITE_POS(2)
+#define REGN_SPR2CTL           REGN_SPRITE_CTL(2)
+#define REGN_SPR2DATA          REGN_SPRITE_DATA(2)
+#define REGN_SPR2DATB          REGN_SPRITE_DATB(2)
+#define REGN_SPRITE3_BASE      0x158
+#define REGN_SPR3POS           REGN_SPRITE_POS(3)
+#define REGN_SPR3CTL           REGN_SPRITE_CTL(3)
+#define REGN_SPR3DATA          REGN_SPRITE_DATA(3)
+#define REGN_SPR3DATB          REGN_SPRITE_DATB(3)
+#define REGN_SPRITE4_BASE      0x160
+#define REGN_SPR4POS           REGN_SPRITE_POS(4)
+#define REGN_SPR4CTL           REGN_SPRITE_CTL(4)
+#define REGN_SPR4DATA          REGN_SPRITE_DATA(4)
+#define REGN_SPR4DATB          REGN_SPRITE_DATB(4)
+#define REGN_SPRITE5_BASE      0x168
+#define REGN_SPR5POS           REGN_SPRITE_POS(5)
+#define REGN_SPR5CTL           REGN_SPRITE_CTL(5)
+#define REGN_SPR5DATA          REGN_SPRITE_DATA(5)
+#define REGN_SPR5DATB          REGN_SPRITE_DATB(5)
+#define REGN_SPRITE6_BASE      0x170
+#define REGN_SPR6POS           REGN_SPRITE_POS(6)
+#define REGN_SPR6CTL           REGN_SPRITE_CTL(6)
+#define REGN_SPR6DATA          REGN_SPRITE_DATA(6)
+#define REGN_SPR6DATB          REGN_SPRITE_DATB(6)
+#define REGN_SPRITE7_BASE      0x178
+#define REGN_SPR7POS           REGN_SPRITE_POS(7)
+#define REGN_SPR7CTL           REGN_SPRITE_CTL(7)
+#define REGN_SPR7DATA          REGN_SPRITE_DATA(7)
+#define REGN_SPR7DATB          REGN_SPRITE_DATB(7)
+
+#define REGN_COLOR_BASE                0x180
+#define REGN_COLOR(idx)                (REGN_COLOR_BASE + (idx) * 2)
+
+#define REGN_COLOR0                    REGN_COLOR(0)
+#define REGN_COLOR1                    REGN_COLOR(1)
+#define REGN_COLOR2                    REGN_COLOR(2)
+#define REGN_COLOR3                    REGN_COLOR(3)
+#define REGN_COLOR4                    REGN_COLOR(4)
+#define REGN_COLOR5                    REGN_COLOR(5)
+#define REGN_COLOR6                    REGN_COLOR(6)
+#define REGN_COLOR7                    REGN_COLOR(7)
+#define REGN_COLOR8                    REGN_COLOR(8)
+#define REGN_COLOR9                    REGN_COLOR(9)
+#define REGN_COLOR10           REGN_COLOR(10)
+#define REGN_COLOR11           REGN_COLOR(11)
+#define REGN_COLOR12           REGN_COLOR(12)
+#define REGN_COLOR13           REGN_COLOR(13)
+#define REGN_COLOR14           REGN_COLOR(14)
+#define REGN_COLOR15           REGN_COLOR(15)
+#define REGN_COLOR16           REGN_COLOR(16)
+#define REGN_COLOR17           REGN_COLOR(17)
+#define REGN_COLOR18           REGN_COLOR(18)
+#define REGN_COLOR19           REGN_COLOR(19)
+#define REGN_COLOR20           REGN_COLOR(20)
+#define REGN_COLOR21           REGN_COLOR(21)
+#define REGN_COLOR22           REGN_COLOR(22)
+#define REGN_COLOR23           REGN_COLOR(23)
+#define REGN_COLOR24           REGN_COLOR(24)
+#define REGN_COLOR25           REGN_COLOR(25)
+#define REGN_COLOR26           REGN_COLOR(26)
+#define REGN_COLOR27           REGN_COLOR(27)
+#define REGN_COLOR28           REGN_COLOR(28)
+#define REGN_COLOR29           REGN_COLOR(29)
+#define REGN_COLOR30           REGN_COLOR(30)
+#define REGN_COLOR31           REGN_COLOR(31)
+
+#define REGN_HTOTAL            0x1c0
+#define REGN_HSSTOP            0x1c2
+#define REGN_HBSTART   0x1c4
+#define REGN_HBSTOP            0x1c6
+#define REGN_VTOTAL            0x1c8
+#define REGN_VSSTOP            0x1ca
+#define REGN_VBSTART   0x1cc
+#define REGN_VBSTOP            0x1ce
+#define REGN_BEAMCON0  0x1dc
+#define REGN_HSSTART   0x1de
+#define REGN_VSSTART   0x1e0
+#define REGN_HCENTER   0x1e2
+#define REGN_DIWHIGH   0x1e4
+
+#define REGN_COP1LCH   0x080
+#define REGN_COP1LCL   0x082
+#define REGN_COP2LCH   0x084
+#define REGN_COP2LCL   0x086
+#define REGN_COPJMP1   0x088
+#define REGN_COPJMP2   0x08a
+
+#define REG(r) (*(volatile uint16_t*)(REG_BASE_ADDR | (r)))
+
+#define REG_CIAA_PORTA *(volatile uint8_t*)0xbfe001
+
+#define REG_INTENA             REG(REGN_INTENA)
+#define REG_INTENAR            REG(REGN_INTENAR)
+#define REG_INTREQ             REG(REGN_INTREQ)
+#define REG_INTREQR            REG(REGN_INTREQR)
+#define REG_ADKCON             REG(REGN_ADKCON)
+#define REG_ADKCONR            REG(REGN_ADKCONR)
+#define REG_DMACON             REG(REGN_DMACON)
+#define REG_DMACONR            REG(REGN_DMACONR)
+#define REG_BPLCON0            REG(REGN_BPLCON0)
+#define REG_BPLCON1            REG(REGN_BPLCON1)
+#define REG_BPLCON2            REG(REGN_BPLCON2)
+#define REG_BPL1PTH            REG(REGN_BPL1PTH)
+#define REG_BPL2PTH            REG(REGN_BPL2PTH)
+#define REG_BPL3PTH            REG(REGN_BPL3PTH)
+#define REG_BPL4PTH            REG(REGN_BPL4PTH)
+#define REG_BPL5PTH            REG(REGN_BPL5PTH)
+#define REG_BPL6PTH            REG(REGN_BPL6PTH)
+#define REG_BPL1PTL            REG(REGN_BPL1PTL)
+#define REG_BPL2PTL            REG(REGN_BPL2PTL)
+#define REG_BPL3PTL            REG(REGN_BPL3PTL)
+#define REG_BPL4PTL            REG(REGN_BPL4PTL)
+#define REG_BPL5PTL            REG(REGN_BPL5PTL)
+#define REG_BPL6PTL            REG(REGN_BPL6PTL)
+#define REG32_BPL1PT   *(volatile uint32_t*)(REG_BASE_ADDR | REGN_BPL1PTH)
+#define REG32_BPL2PT   *(volatile uint32_t*)(REG_BASE_ADDR | REGN_BPL2PTH)
+#define REG32_BPL3PT   *(volatile uint32_t*)(REG_BASE_ADDR | REGN_BPL3PTH)
+#define REG32_BPL4PT   *(volatile uint32_t*)(REG_BASE_ADDR | REGN_BPL4PTH)
+#define REG32_BPL5PT   *(volatile uint32_t*)(REG_BASE_ADDR | REGN_BPL5PTH)
+#define REG32_BPL6PT   *(volatile uint32_t*)(REG_BASE_ADDR | REGN_BPL6PTH)
+#define REG_BPL1MOD            REG(REGN_BPL1MOD)
+#define REG_BPL2MOD            REG(REGN_BPL2MOD)
+#define REG_DIWSTART   REG(REGN_DIWSTART)
+#define REG_DIWSTOP            REG(REGN_DIWSTOP)
+#define REG_DDFSTART   REG(REGN_DDFSTART)
+#define REG_DDFSTOP            REG(REGN_DDFSTOP)
+#define REG_VPOS               REG(REGN_VPOS)
+#define REG_VPOSR              REG(REGN_VPOSR)
+#define REG_VHPOS              REG(REGN_VHPOS)
+#define REG_VHPOSR             REG(REGN_VHPOSR)
+#define REG32_VPOSR            *(volatile uint32_t*)(REG_BASE_ADDR | REGN_VPOSR)
+
+#define REG_COLOR_PTR  ((volatile uint16_t*)(REG_BASE_ADDR | REGN_COLOR0))
+#define REG_COLOR0             REG(REGN_COLOR0)
+#define REG_COLOR1             REG(REGN_COLOR1)
+#define REG_COLOR2             REG(REGN_COLOR2)
+#define REG_COLOR3             REG(REGN_COLOR3)
+#define REG_COLOR4             REG(REGN_COLOR4)
+#define REG_COLOR5             REG(REGN_COLOR5)
+#define REG_COLOR6             REG(REGN_COLOR6)
+#define REG_COLOR7             REG(REGN_COLOR7)
+#define REG_COLOR8             REG(REGN_COLOR8)
+#define REG_COLOR9             REG(REGN_COLOR9)
+#define REG_COLOR10            REG(REGN_COLOR10)
+#define REG_COLOR11            REG(REGN_COLOR11)
+#define REG_COLOR12            REG(REGN_COLOR12)
+#define REG_COLOR13            REG(REGN_COLOR13)
+#define REG_COLOR14            REG(REGN_COLOR14)
+#define REG_COLOR15            REG(REGN_COLOR15)
+#define REG_COLOR16            REG(REGN_COLOR16)
+#define REG_COLOR17            REG(REGN_COLOR17)
+#define REG_COLOR18            REG(REGN_COLOR18)
+#define REG_COLOR19            REG(REGN_COLOR19)
+#define REG_COLOR20            REG(REGN_COLOR20)
+#define REG_COLOR21            REG(REGN_COLOR21)
+#define REG_COLOR22            REG(REGN_COLOR22)
+#define REG_COLOR23            REG(REGN_COLOR23)
+#define REG_COLOR24            REG(REGN_COLOR24)
+#define REG_COLOR25            REG(REGN_COLOR25)
+#define REG_COLOR26            REG(REGN_COLOR26)
+#define REG_COLOR27            REG(REGN_COLOR27)
+#define REG_COLOR28            REG(REGN_COLOR28)
+#define REG_COLOR29            REG(REGN_COLOR29)
+#define REG_COLOR30            REG(REGN_COLOR30)
+#define REG_COLOR31            REG(REGN_COLOR31)
+
+#define REG32_COP1LC   *(volatile uint32_t*)(REG_BASE_ADDR | REGN_COP1LCH)
+#define REG32_COP2LC   *(volatile uint32_t*)(REG_BASE_ADDR | REGN_COP2LCH)
+#define REG_COPJMP1            REG(REGN_COPJMP1)
+#define REG_COPJMP2            REG(REGN_COPJMP2)
+
+#define REG_SERPER             REG(REGN_SERPER)
+#define REG_SERDATR            REG(REGN_SERDATR)
+#define REG_SERDAT             REG(REGN_SERDAT)
+
+/* ------ bits ------- */
+#define SETBITS(x)     ((x) | 0x8000)
+#define CLRBITS(x)     (x)
+
+/* interrupt numbers */
+enum {
+       INTR_TBE,
+       INTR_DSKBLK,
+       INTR_SOFT,
+       INTR_PORTS,
+       INTR_COPPER,
+       INTR_VERTB,
+       INTR_BLITTER,
+       INTR_AUDIO0,
+       INTR_AUDIO1,
+       INTR_AUDIO2,
+       INTR_AUDIO3,
+       INTR_RBF,
+       INTR_DSKSYN,
+       INTR_EXTER
+};
+
+/* interrupt enable flags */
+enum {
+       INTEN_TBE               = 0x0001,
+       INTEN_DSKBLK    = 0x0002,
+       INTEN_SOFT              = 0x0004,
+       INTEN_PORTS             = 0x0008,
+       INTEN_COPPER    = 0x0010,
+       INTEN_VERTB             = 0x0020,
+       INTEN_BLITTER   = 0x0040,
+       INTEN_AUDIO0    = 0x0080,
+       INTEN_AUDIO1    = 0x0100,
+       INTEN_AUDIO2    = 0x0200,
+       INTEN_AUDIO3    = 0x0400,
+       INTEN_RBF               = 0x0800,
+       INTEN_DSKSYN    = 0x1000,
+       INTEN_EXTER             = 0x2000,
+       INTEN_MASTER    = 0x4000,
+
+       INTEN_ALL               = 0x7fff
+};
+
+/* DMA control flags */
+enum {
+       DMA_AUD0                = 0x0001,
+       DMA_AUD1                = 0x0002,
+       DMA_AUD2                = 0x0004,
+       DMA_AUD3                = 0x0008,
+       DMA_AUDIO               = 0x000f,       /* all the above */
+       DMA_DISK                = 0x0010,
+       DMA_SPRITE              = 0x0020,
+       DMA_BLITTER             = 0x0040,
+       DMA_COPPER              = 0x0080,
+       DMA_BPL                 = 0x0100,
+       DMA_MASTER              = 0x0200,
+
+       DMA_ALL                 = 0x01ff
+};
+
+/* Bitplane control */
+enum {
+       BPLCON0_ERSY    = 0x0002,
+       BPLCON0_LACE    = 0x0004,
+       BPLCON0_LPEN    = 0x0008,
+       BPLCON0_GAUD    = 0x0100,
+       BPLCON0_COLOR   = 0x0200,
+       BPLCON0_DBLPF   = 0x0400,
+       BPLCON0_HOMOD   = 0x0800,
+       BPLCON0_BPU0    = 0x1000,
+       BPLCON0_BPU1    = 0x2000,
+       BPLCON0_BPU2    = 0x4000,
+       BPLCON0_HIRES   = 0x8000
+};
+
+#define BPLCON0_COUNT(x)       ((x) << 12)
+
+#define CIAA_PA_FIR0   0x40
+#define CIAA_PA_FIR1   0x80
+
+enum {
+       SERDATR_STOP8   = 0x0100,
+       SERDATR_STOP9   = 0x0200,
+       SERDATR_RXD             = 0x0800,
+       SERDATR_TSRE    = 0x1000,
+       SERDATR_TBE             = 0x2000,
+       SERDATR_RBF             = 0x4000,
+       SERDATR_OVRUN   = 0x8000
+};
+
+#define ADKCON_UARTBRK 0x0800
+
+#endif /* HWREGS_H_ */
diff --git a/src/amiga/main.c b/src/amiga/main.c
new file mode 100644 (file)
index 0000000..e3cfcd5
--- /dev/null
@@ -0,0 +1,19 @@
+#include "hwregs.h"
+
+int main(void)
+{
+       REG_INTENA = SETBITS(INTEN_VERTB | INTEN_MASTER);
+
+       REG_DMACON = CLRBITS(DMA_ALL);
+       REG_BPLCON0 = BPLCON0_COLOR;
+       REG_BPLCON1 = 0;
+       REG_DIWSTART = 0x2c81;
+       REG_DIWSTOP = 0x2cc1;
+       REG_DDFSTART = 0x38;
+       REG_DDFSTOP = 0xd0;
+
+       REG_COLOR0 = 0x237;
+
+       for(;;);
+       return 0;
+}
diff --git a/src/amiga/startup.s b/src/amiga/startup.s
new file mode 100644 (file)
index 0000000..745cf67
--- /dev/null
@@ -0,0 +1,30 @@
+| vi:filetype=gas68k:
+       .global halt_cpu
+       .extern main
+
+       .section .startup,"a"
+
+       | enter supervisor mode (assumes VBR=0)
+       move.l #super, 0x80
+       trap #0
+super:
+       ori.w #0x0300, %sr      | disable interrupts
+
+       | 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.b (%a0)+
+       cmp.l %a0, %a1
+       bne.s 0b
+1:
+       | setup the stack
+       move.l #_stacktop, %sp
+       andi.w #0xf8ff, %sr     | enable interrupts
+
+       jsr main
+0:     bra.b 0b
+
+halt_cpu:
+       stop #0x2700
diff --git a/tools/mk_adf.py b/tools/mk_adf.py
new file mode 100755 (executable)
index 0000000..64b0d94
--- /dev/null
@@ -0,0 +1,56 @@
+#!/usr/bin/python
+# mk_adf.py <bootblock> <payload> <output_adf>
+#
+# Stuff a given bootblock and payload into an output ADF image.
+# 
+# Written & released by Keir Fraser <keir.xen@gmail.com>
+# 
+# This is free and unencumbered software released into the public domain.
+# See the file COPYING for more details, or visit <http://unlicense.org>.
+
+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)