ASFLAGS = -m68000
CFLAGS = -m68000 -ffreestanding -nostdinc -fno-builtin -pedantic -Wall -Os $(inc)
-LDFLAGS = -T amiga.ld -Wl,-print-gc-sections -Wl,-Map,link.map -ffreestanding \
+LDFLAGS = -m68000 -T amiga.ld -Wl,-print-gc-sections -Wl,-Map,link.map -ffreestanding \
-nostdlib -lgcc
$(adf): $(bin) $(bootblock)
.PHONY: run
run:
fs-uae
+
+disasm: $(elf)
+ $(tool_prefix)objdump -d $< >$@
PROVIDE (_stacktop = 0x80000);
SECTIONS {
- /* bootblock will load us at 10000h */
+ /* bootblock will load us at 64k */
. = 0x10000;
.startup : { * (.startup); }
[config]
+fullscreen = 0
+automatic_input_grab = 0
+
keep_aspect = 1
-floppies_dir = $HOME/amiga/disks
-floppy_overlays_dir = $HOME/amiga/disks
+floppies_dir = .
+floppy_overlays_dir = .
kickstarts_dir = $HOME/amiga/rom
logs_dir = $HOME/amiga/logs
screenshots_output_dir = .
--- /dev/null
+#include <stdio.h>
+#include "amigalib.h"
+
+int alib_init(void)
+{
+ execbase = *(void**)4;
+
+ printf("execbase: %lx\n", (unsigned int)execbase);
+ printf("memlist: %lx\n", (unsigned int)&execbase->memlist);
+
+ return 0;
+}
--- /dev/null
+/* structures and functions necessary to access amiga ROM services */
+#ifndef AMIGALIB_H_
+#define AMIGALIB_H_
+
+#include <stdint.h>
+
+#define ALIB_MEMF_ANY 0L
+#define ALIB_MEMF_PUBLIC 0x0001L
+#define ALIB_MEMF_CHIP 0x0002L
+#define ALIB_MEMF_FAST 0x0004L
+#define ALIB_MEMF_CLEAR 0x0100L
+#define ALIB_MEMF_LARGEST 0x0200L
+#define ALIB_MEMF_REVERSE 0x0400L
+#define ALIB_MEMF_TOTAL 0x0800L
+
+#define ALIB_NODE_COMMON(NODE_TYPE) \
+ NODE_TYPE *n_next; \
+ NODE_TYPE *n_prev; \
+ uint8_t n_type; \
+ int8_t n_prio; \
+ char *n_name
+
+struct alib_memchunk {
+ struct alib_memchunk *next;
+ uint32_t size;
+};
+
+struct alib_memnode {
+ ALIB_NODE_COMMON(struct alib_memnode);
+ uint16_t attrib;
+ struct alib_memchunk *freelist;
+ void *start, *end;
+ uint32_t freesz;
+};
+
+struct alib_memlist {
+ struct alib_memnode *head, *tail, *tailpred;
+ uint8_t type;
+ uint8_t pad;
+};
+
+struct alib_library {
+ ALIB_NODE_COMMON(struct alib_library);
+ uint8_t flags;
+ uint8_t pad;
+ uint16_t negsz, possz;
+ uint16_t ver_major, ver_minor;
+ char *idstr;
+ uint32_t csum;
+ uint16_t nref;
+};
+
+struct alib_intvec {
+ void *data;
+ void (*code)();
+ ALIB_NODE_COMMON(struct alib_intvec);
+};
+
+struct alib_execbase {
+ struct alib_library lib;
+ uint16_t softver;
+ int16_t lowmem_csum;
+ uint32_t chkbase;
+ void *coldcap_vect, *coolcap_vect, *warmcap_vect;
+ void *sysstack_upper, *sysstack_lower;
+ uint32_t chipmem_top;
+ void *dbg_entry, *dbg_data, *alert_data;
+ void *extmem_top;
+ uint16_t csum;
+
+ struct alib_intvec intvec[16];
+
+ void *curtask;
+ uint32_t idle_count, disp_count;
+ uint16_t tmslice, nticks;
+ uint16_t sysflags;
+ int8_t intr_dis_nest, task_dis_nest;
+ uint16_t attn_flags, attn_resched;
+ void *resmod;
+ void *tasktrap, *taskexcept, *taks_exit;
+ uint32_t task_sig_alloc;
+ uint16_t task_trap_alloc;
+
+ struct alib_memlist memlist;
+ /* ... more ... */
+};
+
+struct alib_execbase *execbase;
+
+int alib_init(void);
+
+#endif /* AMIGALIB_H_ */
--- /dev/null
+| vi:filetype=gas68k:
+ .section .text
+
+ .equ DMACON, 0x002
+ .equ VPOSR, 0x004
+ .equ VHPOSR, 0x006
+ .equ COLOR0, 0x180
+
+ .global exc_init
+exc_init:
+ move.l #exc_addr, 0xc
+ rts
+
+ .global exc_addr
+exc_addr:
+ ori.w #0x700, %sr
+ move.l #0xdff000, %a0
+ move.w #0x7fff, DMACON(%a0) | clear all DMACON bits
+
+ move.l #str_exc3beg, -(%sp)
+ jsr ser_print
+ add.l #4, %sp
+
+ move.l 2(%sp), %d0
+ move.l %d0, -(%sp)
+ bsr print_hex
+ add.l #4, %sp
+
+ move.l #str_exc3end, -(%sp)
+ jsr ser_print
+ add.l #4, %sp
+
+ move.l #3, -(%sp)
+
+colbars_infloop:
+ move.l #0xdff000, %a0
+ move.w #0, COLOR0(%a0)
+ move.b #128, %d1
+ move.l (%sp), %d2
+
+0: move.b VHPOSR(%a0), %d0
+ cmp.b %d1, %d0
+ bne.s 0b
+ add.b #4, %d1
+ move.w #0xfff, COLOR0(%a0)
+1: move.b VHPOSR(%a0), %d0
+ cmp.b %d1, %d0
+ bne.s 1b
+ add.b #8, %d1
+ move.w #0, COLOR0(%a0)
+ sub.b #1, %d2
+ bne.s 0b
+
+0: cmp.b #0xff, VHPOSR(%a0)
+ bne.s 0b
+ bra.s colbars_infloop
+
+print_hex:
+ move.l #hexbuf, %a0
+ move.l 4(%sp), %d0
+ move.l #8, %d3
+0: rol.l #4, %d0
+ move.b %d0, %d1
+ and.b #0xf, %d1
+ cmp.b #10, %d1
+ bhs.s 1f
+ add.b #'0', %d1 | d1 is in [0, 9]
+ bra.s 2f
+1: add.b #'a'-10, %d1 | d1 is in [10, 15]
+2: move.b %d1, (%a0)+
+ sub.l #1, %d3
+ bne.s 0b
+
+ move.b #0, (%a0)+
+ move.l #hexbuf, -(%sp)
+ jsr ser_print
+ add.l #4, %sp
+ rts
+
+hexbuf: .fill 16
+str_exc3beg: .asciz "Exception 3: address error ("
+str_exc3end: .asciz ")\n"
#include <string.h>
+#include "amigalib.h"
#include "hwregs.h"
#include "copper.h"
#include "gfx.h"
#include "game.h"
#include "serial.h"
+#include "mem.h"
static uint32_t coplist[128];
ser_init(38400);
ser_print("lugburz amiga starting up...\n");
+ alib_init();
+
+ init_mem();
+
init_gfx();
REG_COLOR0 = 0x111;
--- /dev/null
+#include <stdio.h>
+#include "serial.h"
+#include "mem.h"
+#include "amigalib.h"
+
+int init_mem(void)
+{
+ struct alib_memnode *mem;
+
+ printf("Memory ranges:\n");
+ mem = execbase->memlist.head;
+ while(mem->n_next) {
+ char *stype;
+ if(mem->attrib & ALIB_MEMF_CHIP) {
+ stype = "chip";
+ } else if(mem->attrib & ALIB_MEMF_FAST) {
+ stype = "fast";
+ } else {
+ stype = "unknown";
+ }
+ printf(" %06lx - %06lx: %s\n", (unsigned long)mem->start,
+ (unsigned long)mem->end, stype);
+ mem = mem->n_next;
+ }
+
+ return 0;
+}
--- /dev/null
+#ifndef MEM_H_
+#define MEM_H_
+
+int init_mem(void);
+
+#endif /* MEM_H_ */
cmp.l %a0, %a1
bne.s 0b
1:
- | setup the stack
- move.l #_stacktop, %sp
+ | setup the stack at the top of (traditional) chipmem for now
+ move.l #0x80000, %sp
andi.w #0xf8ff, %sr | enable interrupts
+ | initialize early exception handlers
+ jsr exc_init
+
jsr main
0: bra.b 0b
int game_init(void)
{
- printf("hello world\n");
-
return 0;
}