amiga_imgv

changeset 0:a4788c959918

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 25 Oct 2017 19:34:53 +0300
parents
children 6320a20f17c5
files .hgignore Makefile src/amiga/copper.c src/amiga/copper.h src/amiga/gfx.c src/amiga/hwregs.h src/amiga/inttypes.h src/amiga/mouse.c src/amiga/mouse.h src/gfx.h src/image.c src/image.h src/logger.c src/logger.h src/main.c tools/convhammer/Makefile tools/convhammer/main.c
diffstat 17 files changed, 1181 insertions(+), 0 deletions(-) [+]
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/.hgignore	Wed Oct 25 19:34:53 2017 +0300
     1.3 @@ -0,0 +1,7 @@
     1.4 +\.o$
     1.5 +\.d$
     1.6 +\.swp$
     1.7 +\.uaem$
     1.8 +^imgv$
     1.9 +^logfile$
    1.10 +convhammer$
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/Makefile	Wed Oct 25 19:34:53 2017 +0300
     2.3 @@ -0,0 +1,14 @@
     2.4 +src = $(wildcard src/*.c) $(wildcard src/amiga/*.c)
     2.5 +obj = $(src:.c=.o)
     2.6 +bin = imgv
     2.7 +
     2.8 +CC = vc
     2.9 +CFLAGS = -Isrc -Isrc/amiga
    2.10 +LDFLAGS = -lamiga
    2.11 +
    2.12 +$(bin): $(obj)
    2.13 +	$(CC) -o $@ $(obj) $(LDFLAGS)
    2.14 +
    2.15 +.PHONY: clean
    2.16 +clean:
    2.17 +	rm -f $(obj) $(bin)
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/amiga/copper.c	Wed Oct 25 19:34:53 2017 +0300
     3.3 @@ -0,0 +1,113 @@
     3.4 +#include <stdio.h>
     3.5 +#include <exec/memory.h>
     3.6 +#include <exec/libraries.h>
     3.7 +#include <graphics/gfxbase.h>
     3.8 +#include "copper.h"
     3.9 +#include "hwregs.h"
    3.10 +
    3.11 +uint32_t *copperlist, *copperlist_end;
    3.12 +static uint32_t *copmem, *curlist;
    3.13 +static void *savedlist, *savedview;
    3.14 +static int mode, copmem_size;
    3.15 +
    3.16 +struct GfxBase *GfxBase;
    3.17 +
    3.18 +int init_copper(int maxlist, int nlists)
    3.19 +{
    3.20 +	/* save copper list (TODO) */
    3.21 +	if((GfxBase = (struct GfxBase*)OpenLibrary("graphics.library", 0))) {
    3.22 +		savedlist = GfxBase->copinit;
    3.23 +		savedview = GfxBase->ActiView;
    3.24 +		LoadView(0);
    3.25 +		WaitTOF();
    3.26 +		WaitTOF();
    3.27 +
    3.28 +		CloseLibrary(GfxBase);
    3.29 +		GfxBase = 0;
    3.30 +	}
    3.31 +
    3.32 +	/* allocate and set new copper lists */
    3.33 +	if(maxlist <= 0) maxlist = 256;
    3.34 +	mode = nlists >= COPPER_DOUBLE ? COPPER_DOUBLE : COPPER_SINGLE;
    3.35 +
    3.36 +	copmem_size = maxlist * 4 * mode;
    3.37 +	if(!(copmem = (uint32_t*)AllocMem(copmem_size, MEMF_CHIP))) {
    3.38 +		printf("failed to allocate chip memory for %d copper lists of %d instructions\n",
    3.39 +				mode, maxlist);
    3.40 +		return -1;
    3.41 +	}
    3.42 +
    3.43 +	curlist = copperlist = copmem;
    3.44 +	*curlist = COPPER_END;
    3.45 +
    3.46 +	if(mode == COPPER_DOUBLE) {
    3.47 +		copperlist = curlist + maxlist;
    3.48 +		*copperlist = COPPER_END;
    3.49 +	}
    3.50 +	copperlist_end = copperlist;
    3.51 +
    3.52 +	REG32_COP1LC = (uint32_t)curlist;
    3.53 +	REG_COPJMP1 = 0;	/* causes copper to read COP1LC */
    3.54 +	return 0;
    3.55 +}
    3.56 +
    3.57 +void cleanup_copper(void)
    3.58 +{
    3.59 +	/* restore copper list */
    3.60 +	REG32_COP1LC = (uint32_t)savedlist;
    3.61 +
    3.62 +	if((GfxBase = (struct GfxBase*)OpenLibrary("graphics.library", 0))) {
    3.63 +		GfxBase->copinit = savedlist;
    3.64 +		LoadView(savedview);
    3.65 +		WaitTOF();
    3.66 +		WaitTOF();
    3.67 +		CloseLibrary(GfxBase);
    3.68 +		GfxBase = 0;
    3.69 +	}
    3.70 +
    3.71 +	if(copmem) {
    3.72 +		FreeMem(copmem, copmem_size);
    3.73 +	}
    3.74 +}
    3.75 +
    3.76 +void enable_copper(void)
    3.77 +{
    3.78 +	REG_DMACON = SETBITS(DMA_COPPER);
    3.79 +}
    3.80 +
    3.81 +void disable_copper(void)
    3.82 +{
    3.83 +	REG_DMACON = CLRBITS(DMA_COPPER);
    3.84 +}
    3.85 +
    3.86 +void clear_copper(void)
    3.87 +{
    3.88 +	copperlist_end = copperlist;
    3.89 +	*copperlist_end = COPPER_END;
    3.90 +}
    3.91 +
    3.92 +void add_copper(uint32_t cmd)
    3.93 +{
    3.94 +	*copperlist_end++ = cmd;
    3.95 +}
    3.96 +
    3.97 +void sort_copper(void)
    3.98 +{
    3.99 +	/* TODO */
   3.100 +}
   3.101 +
   3.102 +void swap_copper(void)
   3.103 +{
   3.104 +	if(mode == COPPER_DOUBLE) {
   3.105 +		uint32_t *tmpptr;
   3.106 +		tmpptr = curlist;
   3.107 +		curlist = copperlist;
   3.108 +		copperlist = copperlist_end = tmpptr;
   3.109 +
   3.110 +		REG32_COP1LC = (uint32_t)curlist;
   3.111 +		REG_COPJMP1 = 0;
   3.112 +	} else {
   3.113 +		copperlist_end = curlist;
   3.114 +	}
   3.115 +	*copperlist_end = COPPER_END;
   3.116 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/amiga/copper.h	Wed Oct 25 19:34:53 2017 +0300
     4.3 @@ -0,0 +1,38 @@
     4.4 +#ifndef COPPER_H_
     4.5 +#define COPPER_H_
     4.6 +
     4.7 +#include "inttypes.h"
     4.8 +
     4.9 +#define COPPER_MOVE(reg, data)	(((uint32_t)(reg) << 16) | ((uint32_t)(data) & 0xffff))
    4.10 +#define COPPER_WAIT(x, y) \
    4.11 +	(0x0001fffe | ((uint32_t)((x) + 0x81) << 16) | ((uint32_t)((y) + 0x2c) << 24))
    4.12 +#define COPPER_WAIT_OVERSCAN(x, y) \
    4.13 +	(0x0001fffe | ((uint32_t)(x) << 16) | ((uint32_t)(y) << 24))
    4.14 +#define COPPER_VWAIT(s)			(0x0001ff00 | ((uint32_t)((s) + 0x2c) << 24))
    4.15 +#define COPPER_VWAIT_OVERSCAN(s) \
    4.16 +	(0x0001ff00 | ((uint32_t)(s) << 24))
    4.17 +#define COPPER_END				0xfffffffe
    4.18 +
    4.19 +extern uint32_t *copperlist, *copperlist_end;
    4.20 +
    4.21 +enum {
    4.22 +	COPPER_SINGLE = 1,
    4.23 +	COPPER_DOUBLE = 2
    4.24 +};
    4.25 +
    4.26 +int init_copper(int maxlist, int nlists);
    4.27 +void cleanup_copper(void);
    4.28 +
    4.29 +/* enables copper DMA */
    4.30 +void enable_copper(void);
    4.31 +/* disables copper DMA */
    4.32 +void disable_copper(void);
    4.33 +
    4.34 +void clear_copper(void);
    4.35 +void add_copper(uint32_t cmd);
    4.36 +void sort_copper(void);	/* TODO */
    4.37 +
    4.38 +void swap_copper(void);
    4.39 +
    4.40 +
    4.41 +#endif	/* COPPER_H_ */
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/src/amiga/gfx.c	Wed Oct 25 19:34:53 2017 +0300
     5.3 @@ -0,0 +1,203 @@
     5.4 +#include <stdio.h>
     5.5 +#include <proto/exec.h>
     5.6 +#include "gfx.h"
     5.7 +#include "copper.h"
     5.8 +#include "hwregs.h"
     5.9 +#include "logger.h"
    5.10 +
    5.11 +static int scr_width, scr_height;
    5.12 +static int fb_width, fb_height;
    5.13 +static int num_bitplanes;
    5.14 +static uint16_t prev_intena, prev_intreq, prev_adkcon, prev_dmacon;
    5.15 +
    5.16 +static unsigned char *framebuf;
    5.17 +static unsigned long fbsize;
    5.18 +static int own_framebuf;
    5.19 +
    5.20 +int gfx_init(int nbpl, unsigned int flags)
    5.21 +{
    5.22 +	uint16_t bplcon0;
    5.23 +
    5.24 +	num_bitplanes = nbpl;
    5.25 +	scr_width = fb_width = (flags & GFX_HIRES) ? 640 : 320;
    5.26 +	scr_height = fb_height = (flags & GFX_ILACE) ? 512 : 256;
    5.27 +
    5.28 +	Forbid();
    5.29 +
    5.30 +	prev_dmacon = REG_DMACONR;
    5.31 +	REG_DMACON = CLRBITS(DMA_ALL);
    5.32 +
    5.33 +	prev_intena = REG_INTENAR;
    5.34 +	prev_intreq = REG_INTREQR;
    5.35 +	prev_adkcon = REG_ADKCONR;
    5.36 +
    5.37 +	if(init_copper(0, 0) == -1) {
    5.38 +		return -1;
    5.39 +	}
    5.40 +
    5.41 +	if(!gfx_set_framebuffer(0, scr_width, scr_height)) {
    5.42 +		gfx_shutdown();
    5.43 +		return -1;
    5.44 +	}
    5.45 +
    5.46 +	bplcon0 = BPLCON0_COUNT(nbpl) | BPLCON0_COLOR;
    5.47 +	if(flags & GFX_HIRES) bplcon0 |= BPLCON0_HIRES;
    5.48 +	if(flags & GFX_ILACE) bplcon0 |= BPLCON0_LACE;
    5.49 +	if(flags & GFX_HAM) bplcon0 |= BPLCON0_HOMOD;
    5.50 +	if(flags & GFX_DBLPF) bplcon0 |= BPLCON0_DBLPF;
    5.51 +
    5.52 +	REG_BPLCON0 = bplcon0;
    5.53 +	REG_BPLCON1 = 0;	/* h-scroll */
    5.54 +	REG_DIWSTART = 0x2c81;	/* 81h horiz start, 2ch vertical start */
    5.55 +	REG_DIWSTOP = 0x2cc1;
    5.56 +	REG_DDFSTART = (flags & GFX_HIRES) ? 0x3c : 0x38;
    5.57 +	REG_DDFSTOP = (flags & GFX_HIRES) ? 0xd4 : 0xd0;
    5.58 +
    5.59 +	gfx_wait_vblank();
    5.60 +	gfx_begin_copperlist();
    5.61 +	add_copper(COPPER_END);
    5.62 +
    5.63 +	REG_DMACON = SETBITS(DMA_BPL | DMA_COPPER | DMA_MASTER);
    5.64 +	return 0;
    5.65 +}
    5.66 +
    5.67 +void gfx_shutdown(void)
    5.68 +{
    5.69 +	REG_DMACON = CLRBITS(DMA_ALL);
    5.70 +	REG_DMACON = SETBITS(prev_dmacon);
    5.71 +
    5.72 +	REG_INTREQ = CLRBITS(0x7fff);
    5.73 +	REG_INTREQ = SETBITS(prev_intreq);
    5.74 +
    5.75 +	REG_ADKCON = CLRBITS(0x7fff);
    5.76 +	REG_ADKCON = SETBITS(prev_adkcon);
    5.77 +
    5.78 +	REG_INTENA = CLRBITS(INTEN_ALL);
    5.79 +	REG_INTENA = SETBITS(prev_intena);
    5.80 +
    5.81 +	if(framebuf && own_framebuf) {
    5.82 +		FreeMem(framebuf, fbsize);
    5.83 +	}
    5.84 +	framebuf = 0;
    5.85 +
    5.86 +	cleanup_copper();
    5.87 +	Permit();
    5.88 +}
    5.89 +
    5.90 +int gfx_screen_width(void)
    5.91 +{
    5.92 +	return scr_width;
    5.93 +}
    5.94 +
    5.95 +int gfx_screen_height(void)
    5.96 +{
    5.97 +	return scr_height;
    5.98 +}
    5.99 +
   5.100 +void *gfx_set_framebuffer(void *fb, int width, int height)
   5.101 +{
   5.102 +	/*unsigned int bpl_scanline_sz = width / 8;*/
   5.103 +	unsigned long sz = width * height / 8 * num_bitplanes;
   5.104 +	uint32_t bpladdr;
   5.105 +	uint16_t bplmod;
   5.106 +
   5.107 +	if(framebuf && own_framebuf) {
   5.108 +		FreeMem(framebuf, fbsize);
   5.109 +	}
   5.110 +
   5.111 +	if(fb) {
   5.112 +		framebuf = fb;
   5.113 +		own_framebuf = 0;
   5.114 +	} else {
   5.115 +		if(!(framebuf = AllocMem(sz, MEMF_CHIP))) {
   5.116 +			logmsg("gfx_set_framebuffer failed to allocate %lu bytes of chip mem for framebuffer\n", sz);
   5.117 +			return 0;
   5.118 +		}
   5.119 +		own_framebuf = 1;
   5.120 +	}
   5.121 +
   5.122 +	fb_width = width;
   5.123 +	fb_height = height;
   5.124 +	fbsize = sz;
   5.125 +
   5.126 +	bpladdr = (uint32_t)framebuf;
   5.127 +	logmsg("bitplane address: %lx\n", (unsigned long)bpladdr);
   5.128 +
   5.129 +	bplmod = (fb_width - scr_width) / 8 + fb_width / 8 * num_bitplanes;
   5.130 +	REG_BPL1MOD = bplmod;
   5.131 +	REG_BPL2MOD = bplmod;
   5.132 +
   5.133 +	/*
   5.134 +	REG32_BPL1PT = bpladdr; bpladdr += bpl_scanline_sz;
   5.135 +	REG32_BPL2PT = bpladdr; bpladdr += bpl_scanline_sz;
   5.136 +	REG32_BPL3PT = bpladdr; bpladdr += bpl_scanline_sz;
   5.137 +	REG32_BPL4PT = bpladdr; bpladdr += bpl_scanline_sz;
   5.138 +	REG32_BPL5PT = bpladdr; bpladdr += bpl_scanline_sz;
   5.139 +	REG32_BPL6PT = bpladdr;
   5.140 +	*/
   5.141 +	return framebuf;
   5.142 +}
   5.143 +
   5.144 +void *gfx_get_framebuffer(void)
   5.145 +{
   5.146 +	return framebuf;
   5.147 +}
   5.148 +
   5.149 +int gfx_framebuffer_width(void)
   5.150 +{
   5.151 +	return fb_width;
   5.152 +}
   5.153 +
   5.154 +int gfx_framebuffer_height(void)
   5.155 +{
   5.156 +	return fb_height;
   5.157 +}
   5.158 +
   5.159 +void gfx_begin_copperlist(void)
   5.160 +{
   5.161 +	static const uint16_t bplptr[] = {
   5.162 +		REGN_BPL1PTH, REGN_BPL2PTH, REGN_BPL3PTH, REGN_BPL4PTH, REGN_BPL5PTH, REGN_BPL6PTH
   5.163 +	};
   5.164 +	int i;
   5.165 +	uint32_t bpladdr;
   5.166 +	bpladdr = (uint32_t)framebuf;
   5.167 +
   5.168 +	for(i=0; i<num_bitplanes; i++) {
   5.169 +		add_copper(COPPER_MOVE(bplptr[i], bpladdr >> 16));
   5.170 +		add_copper(COPPER_MOVE(bplptr[i] + 2, bpladdr));
   5.171 +		bpladdr += fb_width / 8 * num_bitplanes;
   5.172 +	}
   5.173 +}
   5.174 +
   5.175 +static int mouse_bnstate(void)
   5.176 +{
   5.177 +	return (REG_CIAA_PORTA & CIAA_PA_FIR0) ? 0 : 1;
   5.178 +}
   5.179 +
   5.180 +int gfx_next_event(union gfx_event *ev, int block)
   5.181 +{
   5.182 +	/* TODO */
   5.183 +	if(block) {
   5.184 +		while(!mouse_bnstate());
   5.185 +		ev->type = GFX_EV_QUIT;
   5.186 +		return 1;
   5.187 +	}
   5.188 +
   5.189 +	if(mouse_bnstate()) {
   5.190 +		ev->type = GFX_EV_QUIT;
   5.191 +		return 1;
   5.192 +	}
   5.193 +
   5.194 +	return 0;
   5.195 +}
   5.196 +
   5.197 +void gfx_wait_vpos(int x)
   5.198 +{
   5.199 +	x <<= 8;
   5.200 +	while((REG32_VPOSR & 0x1ff00) < x);
   5.201 +}
   5.202 +
   5.203 +void gfx_wait_vblank(void)
   5.204 +{
   5.205 +	gfx_wait_vpos(300);
   5.206 +}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/amiga/hwregs.h	Wed Oct 25 19:34:53 2017 +0300
     6.3 @@ -0,0 +1,410 @@
     6.4 +#ifndef HWREGS_H_
     6.5 +#define HWREGS_H_
     6.6 +
     6.7 +#include "inttypes.h"
     6.8 +
     6.9 +#define REG_BASE_ADDR	0xdff000
    6.10 +
    6.11 +#define REGN_BLTDDAT	0x000
    6.12 +#define REGN_DMACONR	0x002
    6.13 +#define REGN_VPOSR		0x004
    6.14 +#define REGN_VHPOSR		0x006
    6.15 +#define REGN_DSKDATR	0x008
    6.16 +#define REGN_JOY0DAT	0x00a
    6.17 +#define REGN_JOY1DAT	0x00c
    6.18 +#define REGN_CLXDAT		0x00e
    6.19 +#define REGN_ADKCONR	0x010
    6.20 +#define REGN_POT0DAT	0x012
    6.21 +#define REGN_POT1DAT	0x014
    6.22 +#define REGN_POTGOR		0x016
    6.23 +#define REGN_SERDATR	0x018
    6.24 +#define REGN_DSKBYTR	0x01a
    6.25 +#define REGN_INTENAR	0x01c
    6.26 +#define REGN_INTREQR	0x01e
    6.27 +#define REGN_DSKPTH		0x020
    6.28 +#define REGN_DSKPTL		0x022
    6.29 +#define REGN_DSKLEN		0x024
    6.30 +#define REGN_DSKDAT		0x026
    6.31 +#define REGN_REFPTR		0x028
    6.32 +#define REGN_VPOSW		0x02a
    6.33 +#define REGN_VHPOSW		0x02c
    6.34 +#define REGN_COPCON		0x02e
    6.35 +#define REGN_SERDAT		0x030
    6.36 +#define REGN_SERPER		0x032
    6.37 +#define REGN_POTGO		0x034
    6.38 +#define REGN_JOYTEST	0x036
    6.39 +#define REGN_STREQU		0x038
    6.40 +#define REGN_STRVBL		0x03a
    6.41 +#define REGN_STRHOR		0x03c
    6.42 +#define REGN_STRLONG	0x03e
    6.43 +#define REGN_BLTCON0	0x040
    6.44 +#define REGN_BLTCON1	0x042
    6.45 +#define REGN_BLTAFWM	0x044
    6.46 +#define REGN_BLTALWM	0x046
    6.47 +#define REGN_BLTCPTH	0x048
    6.48 +#define REGN_BLTCPTL	0x04a
    6.49 +#define REGN_BLTBPTH	0x04c
    6.50 +#define REGN_BLTBPTL	0x04e
    6.51 +#define REGN_BLTAPTH	0x050
    6.52 +#define REGN_BLTAPTL	0x052
    6.53 +#define REGN_BLTDPTH	0x054
    6.54 +#define REGN_BLTDPTL	0x056
    6.55 +#define REGN_BLTSIZE	0x058
    6.56 +#define REGN_BLTCON0L	0x05a
    6.57 +#define REGN_BLTSIZV	0x05c
    6.58 +#define REGN_BLTSIZH	0x05e
    6.59 +#define REGN_BLTCMOD	0x060
    6.60 +#define REGN_BLTBMOD	0x062
    6.61 +#define REGN_BLTAMOD	0x064
    6.62 +#define REGN_BLTDMOD	0x066
    6.63 +#define REGN_BLTCDAT	0x070
    6.64 +#define REGN_BLTBDAT	0x072
    6.65 +#define REGN_BLTADAT	0x074
    6.66 +#define REGN_SPRHDAT	0x078
    6.67 +#define REGN_DENISEID	0x07c
    6.68 +#define REGN_DSKSYNC	0x07e
    6.69 +#define REGN_COP1LCH	0x080
    6.70 +#define REGN_COP1LCL	0x082
    6.71 +#define REGN_COP2LCH	0x084
    6.72 +#define REGN_COP2LCL	0x086
    6.73 +#define REGN_CMPJMP1	0x088
    6.74 +#define REGN_CMPJMP2	0x08a
    6.75 +#define REGN_COPINS		0x08c
    6.76 +#define REGN_DIWSTART	0x08e
    6.77 +#define REGN_DIWSTOP	0x090
    6.78 +#define REGN_DDFSTART	0x092
    6.79 +#define REGN_DDFSTOP	0x094
    6.80 +#define REGN_DMACON		0x096
    6.81 +#define REGN_CLXCON		0x098
    6.82 +#define REGN_INTENA		0x09a
    6.83 +#define REGN_INTREQ		0x09c
    6.84 +#define REGN_ADKCON		0x09e
    6.85 +
    6.86 +#define REGN_AUDIO_LCH(c)	(REGN_AUDIO0_BASE + (c) * 16 + 0)
    6.87 +#define REGN_AUDIO_LCL(c)	(REGN_AUDIO0_BASE + (c) * 16 + 2)
    6.88 +#define REGN_AUDIO_LEN(c)	(REGN_AUDIO0_BASE + (c) * 16 + 4)
    6.89 +#define REGN_AUDIO_PER(c)	(REGN_AUDIO0_BASE + (c) * 16 + 6)
    6.90 +#define REGN_AUDIO_VOL(c)	(REGN_AUDIO0_BASE + (c) * 16 + 8)
    6.91 +#define REGN_AUDIO_DAT(c)	(REGN_AUDIO0_BASE + (c) * 16 + 10)
    6.92 +
    6.93 +#define REGN_AUDIO0_BASE	0x0a0
    6.94 +#define REGN_AUD0LCH		(REGN_AUDIO0_BASE + 0)
    6.95 +#define REGN_AUD0LCL		(REGN_AUDIO0_BASE + 2)
    6.96 +#define REGN_AUD0LEN		(REGN_AUDIO0_BASE + 4)
    6.97 +#define REGN_AUD0PER		(REGN_AUDIO0_BASE + 6)
    6.98 +#define REGN_AUD0VOL		(REGN_AUDIO0_BASE + 8)
    6.99 +#define REGN_AUD0DAT		(REGN_AUDIO0_BASE + 10)
   6.100 +#define REGN_AUDIO1_BASE	0x0b0
   6.101 +#define REGN_AUD1LCH		(REGN_AUDIO1_BASE + 0)
   6.102 +#define REGN_AUD1LCL		(REGN_AUDIO1_BASE + 2)
   6.103 +#define REGN_AUD1LEN		(REGN_AUDIO1_BASE + 4)
   6.104 +#define REGN_AUD1PER		(REGN_AUDIO1_BASE + 6)
   6.105 +#define REGN_AUD1VOL		(REGN_AUDIO1_BASE + 8)
   6.106 +#define REGN_AUD1DAT		(REGN_AUDIO1_BASE + 10)
   6.107 +#define REGN_AUDIO2_BASE	0x0c0
   6.108 +#define REGN_AUD2LCH		(REGN_AUDIO2_BASE + 0)
   6.109 +#define REGN_AUD2LCL		(REGN_AUDIO2_BASE + 2)
   6.110 +#define REGN_AUD2LEN		(REGN_AUDIO2_BASE + 4)
   6.111 +#define REGN_AUD2PER		(REGN_AUDIO2_BASE + 6)
   6.112 +#define REGN_AUD2VOL		(REGN_AUDIO2_BASE + 8)
   6.113 +#define REGN_AUD2DAT		(REGN_AUDIO2_BASE + 10)
   6.114 +#define REGN_AUDIO3_BASE	0x0d0
   6.115 +#define REGN_AUD3LCH		(REGN_AUDIO3_BASE + 0)
   6.116 +#define REGN_AUD3LCL		(REGN_AUDIO3_BASE + 2)
   6.117 +#define REGN_AUD3LEN		(REGN_AUDIO3_BASE + 4)
   6.118 +#define REGN_AUD3PER		(REGN_AUDIO3_BASE + 6)
   6.119 +#define REGN_AUD3VOL		(REGN_AUDIO3_BASE + 8)
   6.120 +#define REGN_AUD3DAT		(REGN_AUDIO3_BASE + 10)
   6.121 +
   6.122 +#define REGN_BPL1PTH	0x0e0
   6.123 +#define REGN_BPL1PTL	0x0e2
   6.124 +#define REGN_BPL2PTH	0x0e4
   6.125 +#define REGN_BPL2PTL	0x0e6
   6.126 +#define REGN_BPL3PTH	0x0e8
   6.127 +#define REGN_BPL3PTL	0x0ea
   6.128 +#define REGN_BPL4PTH	0x0ec
   6.129 +#define REGN_BPL4PTL	0x0ee
   6.130 +#define REGN_BPL5PTH	0x0f0
   6.131 +#define REGN_BPL5PTL	0x0f2
   6.132 +#define REGN_BPL6PTH	0x0f4
   6.133 +#define REGN_BPL6PTL	0x0f6
   6.134 +#define REGN_BPLCON0	0x100
   6.135 +#define REGN_BPLCON1	0x102
   6.136 +#define REGN_BPLCON2	0x104
   6.137 +#define REGN_BPLCON3	0x106
   6.138 +#define REGN_BPL1MOD	0x108
   6.139 +#define REGN_BPL2MOD	0x10a
   6.140 +#define REGN_BPL1DAT	0x110
   6.141 +#define REGN_BPL2DAT	0x112
   6.142 +#define REGN_BPL3DAT	0x114
   6.143 +#define REGN_BPL4DAT	0x116
   6.144 +#define REGN_BPL5DAT	0x118
   6.145 +#define REGN_BPL6DAT	0x11a
   6.146 +
   6.147 +#define REGN_SPR0PTH	0x120
   6.148 +#define REGN_SPR0PTL	0x122
   6.149 +#define REGN_SPR1PTH	0x124
   6.150 +#define REGN_SPR1PTL	0x126
   6.151 +#define REGN_SPR2PTH	0x128
   6.152 +#define REGN_SPR2PTL	0x12a
   6.153 +#define REGN_SPR3PTH	0x12c
   6.154 +#define REGN_SPR3PTL	0x12e
   6.155 +#define REGN_SPR4PTH	0x130
   6.156 +#define REGN_SPR4PTL	0x132
   6.157 +#define REGN_SPR5PTH	0x134
   6.158 +#define REGN_SPR5PTL	0x136
   6.159 +#define REGN_SPR6PTH	0x138
   6.160 +#define REGN_SPR6PTL	0x13a
   6.161 +#define REGN_SPR7PTH	0x13c
   6.162 +#define REGN_SPR7PTL	0x13e
   6.163 +
   6.164 +#define REGN_SPRITE_POS(s)	(REGN_SPRITE0_BASE + (s) * 8 + 0)
   6.165 +#define REGN_SPRITE_CTL(s)	(REGN_SPRITE0_BASE + (s) * 8 + 2)
   6.166 +#define REGN_SPRITE_DATA(s)	(REGN_SPRITE0_BASE + (s) * 8 + 4)
   6.167 +#define REGN_SPRITE_DATB(s)	(REGN_SPRITE0_BASE + (s) * 8 + 6)
   6.168 +
   6.169 +#define REGN_SPRITE0_BASE	0x140
   6.170 +#define REGN_SPR0POS		REGN_SPRITE_POS(0)
   6.171 +#define REGN_SPR0CTL		REGN_SPRITE_CTL(0)
   6.172 +#define REGN_SPR0DATA		REGN_SPRITE_DATA(0)
   6.173 +#define REGN_SPR0DATB		REGN_SPRITE_DATB(0)
   6.174 +#define REGN_SPRITE1_BASE	0x148
   6.175 +#define REGN_SPR1POS		REGN_SPRITE_POS(1)
   6.176 +#define REGN_SPR1CTL		REGN_SPRITE_CTL(1)
   6.177 +#define REGN_SPR1DATA		REGN_SPRITE_DATA(1)
   6.178 +#define REGN_SPR1DATB		REGN_SPRITE_DATB(1)
   6.179 +#define REGN_SPRITE2_BASE	0x150
   6.180 +#define REGN_SPR2POS		REGN_SPRITE_POS(2)
   6.181 +#define REGN_SPR2CTL		REGN_SPRITE_CTL(2)
   6.182 +#define REGN_SPR2DATA		REGN_SPRITE_DATA(2)
   6.183 +#define REGN_SPR2DATB		REGN_SPRITE_DATB(2)
   6.184 +#define REGN_SPRITE3_BASE	0x158
   6.185 +#define REGN_SPR3POS		REGN_SPRITE_POS(3)
   6.186 +#define REGN_SPR3CTL		REGN_SPRITE_CTL(3)
   6.187 +#define REGN_SPR3DATA		REGN_SPRITE_DATA(3)
   6.188 +#define REGN_SPR3DATB		REGN_SPRITE_DATB(3)
   6.189 +#define REGN_SPRITE4_BASE	0x160
   6.190 +#define REGN_SPR4POS		REGN_SPRITE_POS(4)
   6.191 +#define REGN_SPR4CTL		REGN_SPRITE_CTL(4)
   6.192 +#define REGN_SPR4DATA		REGN_SPRITE_DATA(4)
   6.193 +#define REGN_SPR4DATB		REGN_SPRITE_DATB(4)
   6.194 +#define REGN_SPRITE5_BASE	0x168
   6.195 +#define REGN_SPR5POS		REGN_SPRITE_POS(5)
   6.196 +#define REGN_SPR5CTL		REGN_SPRITE_CTL(5)
   6.197 +#define REGN_SPR5DATA		REGN_SPRITE_DATA(5)
   6.198 +#define REGN_SPR5DATB		REGN_SPRITE_DATB(5)
   6.199 +#define REGN_SPRITE6_BASE	0x170
   6.200 +#define REGN_SPR6POS		REGN_SPRITE_POS(6)
   6.201 +#define REGN_SPR6CTL		REGN_SPRITE_CTL(6)
   6.202 +#define REGN_SPR6DATA		REGN_SPRITE_DATA(6)
   6.203 +#define REGN_SPR6DATB		REGN_SPRITE_DATB(6)
   6.204 +#define REGN_SPRITE7_BASE	0x178
   6.205 +#define REGN_SPR7POS		REGN_SPRITE_POS(7)
   6.206 +#define REGN_SPR7CTL		REGN_SPRITE_CTL(7)
   6.207 +#define REGN_SPR7DATA		REGN_SPRITE_DATA(7)
   6.208 +#define REGN_SPR7DATB		REGN_SPRITE_DATB(7)
   6.209 +
   6.210 +#define REGN_COLOR_BASE		0x180
   6.211 +#define REGN_COLOR(idx)		(REGN_COLOR_BASE + (idx) * 2)
   6.212 +
   6.213 +#define REGN_COLOR0			REGN_COLOR(0)
   6.214 +#define REGN_COLOR1			REGN_COLOR(1)
   6.215 +#define REGN_COLOR2			REGN_COLOR(2)
   6.216 +#define REGN_COLOR3			REGN_COLOR(3)
   6.217 +#define REGN_COLOR4			REGN_COLOR(4)
   6.218 +#define REGN_COLOR5			REGN_COLOR(5)
   6.219 +#define REGN_COLOR6			REGN_COLOR(6)
   6.220 +#define REGN_COLOR7			REGN_COLOR(7)
   6.221 +#define REGN_COLOR8			REGN_COLOR(8)
   6.222 +#define REGN_COLOR9			REGN_COLOR(9)
   6.223 +#define REGN_COLOR10		REGN_COLOR(10)
   6.224 +#define REGN_COLOR11		REGN_COLOR(11)
   6.225 +#define REGN_COLOR12		REGN_COLOR(12)
   6.226 +#define REGN_COLOR13		REGN_COLOR(13)
   6.227 +#define REGN_COLOR14		REGN_COLOR(14)
   6.228 +#define REGN_COLOR15		REGN_COLOR(15)
   6.229 +#define REGN_COLOR16		REGN_COLOR(16)
   6.230 +#define REGN_COLOR17		REGN_COLOR(17)
   6.231 +#define REGN_COLOR18		REGN_COLOR(18)
   6.232 +#define REGN_COLOR19		REGN_COLOR(19)
   6.233 +#define REGN_COLOR20		REGN_COLOR(20)
   6.234 +#define REGN_COLOR21		REGN_COLOR(21)
   6.235 +#define REGN_COLOR22		REGN_COLOR(22)
   6.236 +#define REGN_COLOR23		REGN_COLOR(23)
   6.237 +#define REGN_COLOR24		REGN_COLOR(24)
   6.238 +#define REGN_COLOR25		REGN_COLOR(25)
   6.239 +#define REGN_COLOR26		REGN_COLOR(26)
   6.240 +#define REGN_COLOR27		REGN_COLOR(27)
   6.241 +#define REGN_COLOR28		REGN_COLOR(28)
   6.242 +#define REGN_COLOR29		REGN_COLOR(29)
   6.243 +#define REGN_COLOR30		REGN_COLOR(30)
   6.244 +#define REGN_COLOR31		REGN_COLOR(31)
   6.245 +
   6.246 +#define REGN_HTOTAL		0x1c0
   6.247 +#define REGN_HSSTOP		0x1c2
   6.248 +#define REGN_HBSTART	0x1c4
   6.249 +#define REGN_HBSTOP		0x1c6
   6.250 +#define REGN_VTOTAL		0x1c8
   6.251 +#define REGN_VSSTOP		0x1ca
   6.252 +#define REGN_VBSTART	0x1cc
   6.253 +#define REGN_VBSTOP		0x1ce
   6.254 +#define REGN_BEAMCON0	0x1dc
   6.255 +#define REGN_HSSTART	0x1de
   6.256 +#define REGN_VSSTART	0x1e0
   6.257 +#define REGN_HCENTER	0x1e2
   6.258 +#define REGN_DIWHIGH	0x1e4
   6.259 +
   6.260 +#define REGN_COP1LCH	0x080
   6.261 +#define REGN_COP1LCL	0x082
   6.262 +#define REGN_COP2LCH	0x084
   6.263 +#define REGN_COP2LCL	0x086
   6.264 +#define REGN_COPJMP1	0x088
   6.265 +#define REGN_COPJMP2	0x08a
   6.266 +
   6.267 +#define REG(r)	(*(volatile uint16_t*)(REG_BASE_ADDR | (r)))
   6.268 +
   6.269 +#define REG_CIAA_PORTA	*(volatile uint8_t*)0xbfe001
   6.270 +
   6.271 +#define REG_INTENA		REG(REGN_INTENA)
   6.272 +#define REG_INTENAR		REG(REGN_INTENAR)
   6.273 +#define REG_INTREQ		REG(REGN_INTREQ)
   6.274 +#define REG_INTREQR		REG(REGN_INTREQR)
   6.275 +#define REG_ADKCON		REG(REGN_ADKCON)
   6.276 +#define REG_ADKCONR		REG(REGN_ADKCONR)
   6.277 +#define REG_DMACON		REG(REGN_DMACON)
   6.278 +#define REG_DMACONR		REG(REGN_DMACONR)
   6.279 +#define REG_BPLCON0		REG(REGN_BPLCON0)
   6.280 +#define REG_BPLCON1		REG(REGN_BPLCON1)
   6.281 +#define REG_BPLCON2		REG(REGN_BPLCON2)
   6.282 +#define REG_BPL1PTH		REG(REGN_BPL1PTH)
   6.283 +#define REG_BPL2PTH		REG(REGN_BPL2PTH)
   6.284 +#define REG_BPL3PTH		REG(REGN_BPL3PTH)
   6.285 +#define REG_BPL4PTH		REG(REGN_BPL4PTH)
   6.286 +#define REG_BPL5PTH		REG(REGN_BPL5PTH)
   6.287 +#define REG_BPL6PTH		REG(REGN_BPL6PTH)
   6.288 +#define REG_BPL1PTL		REG(REGN_BPL1PTL)
   6.289 +#define REG_BPL2PTL		REG(REGN_BPL2PTL)
   6.290 +#define REG_BPL3PTL		REG(REGN_BPL3PTL)
   6.291 +#define REG_BPL4PTL		REG(REGN_BPL4PTL)
   6.292 +#define REG_BPL5PTL		REG(REGN_BPL5PTL)
   6.293 +#define REG_BPL6PTL		REG(REGN_BPL6PTL)
   6.294 +#define REG32_BPL1PT	*(volatile uint32_t*)(REG_BASE_ADDR | REGN_BPL1PTH)
   6.295 +#define REG32_BPL2PT	*(volatile uint32_t*)(REG_BASE_ADDR | REGN_BPL2PTH)
   6.296 +#define REG32_BPL3PT	*(volatile uint32_t*)(REG_BASE_ADDR | REGN_BPL3PTH)
   6.297 +#define REG32_BPL4PT	*(volatile uint32_t*)(REG_BASE_ADDR | REGN_BPL4PTH)
   6.298 +#define REG32_BPL5PT	*(volatile uint32_t*)(REG_BASE_ADDR | REGN_BPL5PTH)
   6.299 +#define REG32_BPL6PT	*(volatile uint32_t*)(REG_BASE_ADDR | REGN_BPL6PTH)
   6.300 +#define REG_BPL1MOD		REG(REGN_BPL1MOD)
   6.301 +#define REG_BPL2MOD		REG(REGN_BPL2MOD)
   6.302 +#define REG_DIWSTART	REG(REGN_DIWSTART)
   6.303 +#define REG_DIWSTOP		REG(REGN_DIWSTOP)
   6.304 +#define REG_DDFSTART	REG(REGN_DDFSTART)
   6.305 +#define REG_DDFSTOP		REG(REGN_DDFSTOP)
   6.306 +#define REG_VPOS		REG(REGN_VPOS)
   6.307 +#define REG_VPOSR		REG(REGN_VPOSR)
   6.308 +#define REG_VHPOS		REG(REGN_VHPOS)
   6.309 +#define REG_VHPOSR		REG(REGN_VHPOSR)
   6.310 +#define REG32_VPOSR		*(volatile uint32_t*)(REG_BASE_ADDR | REGN_VPOSR)
   6.311 +
   6.312 +#define REG_COLOR_PTR	((volatile uint16_t*)(REG_BASE_ADDR | REGN_COLOR0))
   6.313 +#define REG_COLOR0		REG(REGN_COLOR0)
   6.314 +#define REG_COLOR1		REG(REGN_COLOR1)
   6.315 +#define REG_COLOR2		REG(REGN_COLOR2)
   6.316 +#define REG_COLOR3		REG(REGN_COLOR3)
   6.317 +#define REG_COLOR4		REG(REGN_COLOR4)
   6.318 +#define REG_COLOR5		REG(REGN_COLOR5)
   6.319 +#define REG_COLOR6		REG(REGN_COLOR6)
   6.320 +#define REG_COLOR7		REG(REGN_COLOR7)
   6.321 +#define REG_COLOR8		REG(REGN_COLOR8)
   6.322 +#define REG_COLOR9		REG(REGN_COLOR9)
   6.323 +#define REG_COLOR10		REG(REGN_COLOR10)
   6.324 +#define REG_COLOR11		REG(REGN_COLOR11)
   6.325 +#define REG_COLOR12		REG(REGN_COLOR12)
   6.326 +#define REG_COLOR13		REG(REGN_COLOR13)
   6.327 +#define REG_COLOR14		REG(REGN_COLOR14)
   6.328 +#define REG_COLOR15		REG(REGN_COLOR15)
   6.329 +#define REG_COLOR16		REG(REGN_COLOR16)
   6.330 +#define REG_COLOR17		REG(REGN_COLOR17)
   6.331 +#define REG_COLOR18		REG(REGN_COLOR18)
   6.332 +#define REG_COLOR19		REG(REGN_COLOR19)
   6.333 +#define REG_COLOR20		REG(REGN_COLOR20)
   6.334 +#define REG_COLOR21		REG(REGN_COLOR21)
   6.335 +#define REG_COLOR22		REG(REGN_COLOR22)
   6.336 +#define REG_COLOR23		REG(REGN_COLOR23)
   6.337 +#define REG_COLOR24		REG(REGN_COLOR24)
   6.338 +#define REG_COLOR25		REG(REGN_COLOR25)
   6.339 +#define REG_COLOR26		REG(REGN_COLOR26)
   6.340 +#define REG_COLOR27		REG(REGN_COLOR27)
   6.341 +#define REG_COLOR28		REG(REGN_COLOR28)
   6.342 +#define REG_COLOR29		REG(REGN_COLOR29)
   6.343 +#define REG_COLOR30		REG(REGN_COLOR30)
   6.344 +#define REG_COLOR31		REG(REGN_COLOR31)
   6.345 +
   6.346 +#define REG32_COP1LC	*(volatile uint32_t*)(REG_BASE_ADDR | REGN_COP1LCH)
   6.347 +#define REG32_COP2LC	*(volatile uint32_t*)(REG_BASE_ADDR | REGN_COP2LCH)
   6.348 +#define REG_COPJMP1		REG(REGN_COPJMP1)
   6.349 +#define REG_COPJMP2		REG(REGN_COPJMP2)
   6.350 +
   6.351 +/* ------ bits ------- */
   6.352 +#define SETBITS(x)	((x) | 0x8000)
   6.353 +#define CLRBITS(x)	(x)
   6.354 +
   6.355 +/* interrupt enable flags */
   6.356 +enum {
   6.357 +	INTEN_TBE		= 0x0001,
   6.358 +	INTEN_DSKBLK	= 0x0002,
   6.359 +	INTEN_SOFT		= 0x0004,
   6.360 +	INTEN_PORTS		= 0x0008,
   6.361 +	INTEN_COPPER	= 0x0010,
   6.362 +	INTEN_VERTB		= 0x0020,
   6.363 +	INTEN_BLITTER	= 0x0040,
   6.364 +	INTEN_AUDIO0	= 0x0080,
   6.365 +	INTEN_AUDIO1	= 0x0100,
   6.366 +	INTEN_AUDIO2	= 0x0200,
   6.367 +	INTEN_AUDIO3	= 0x0400,
   6.368 +	INTEN_RBF		= 0x0800,
   6.369 +	INTEN_DSKSYN	= 0x1000,
   6.370 +	INTEN_EXTER		= 0x2000,
   6.371 +	INTEN_MASTER	= 0x4000,
   6.372 +
   6.373 +	INTEN_ALL		= 0x7fff
   6.374 +};
   6.375 +
   6.376 +/* DMA control flags */
   6.377 +enum {
   6.378 +	DMA_AUD0		= 0x0001,
   6.379 +	DMA_AUD1		= 0x0002,
   6.380 +	DMA_AUD2		= 0x0004,
   6.381 +	DMA_AUD3		= 0x0008,
   6.382 +	DMA_AUDIO		= 0x000f,	/* all the above */
   6.383 +	DMA_DISK		= 0x0010,
   6.384 +	DMA_SPRITE		= 0x0020,
   6.385 +	DMA_BLITTER		= 0x0040,
   6.386 +	DMA_COPPER		= 0x0080,
   6.387 +	DMA_BPL			= 0x0100,
   6.388 +	DMA_MASTER		= 0x0200,
   6.389 +
   6.390 +	DMA_ALL			= 0x01ff
   6.391 +};
   6.392 +
   6.393 +/* Bitplane control */
   6.394 +enum {
   6.395 +	BPLCON0_ERSY	= 0x0002,
   6.396 +	BPLCON0_LACE	= 0x0004,
   6.397 +	BPLCON0_LPEN	= 0x0008,
   6.398 +	BPLCON0_GAUD	= 0x0100,
   6.399 +	BPLCON0_COLOR	= 0x0200,
   6.400 +	BPLCON0_DBLPF	= 0x0400,
   6.401 +	BPLCON0_HOMOD	= 0x0800,
   6.402 +	BPLCON0_BPU0	= 0x1000,
   6.403 +	BPLCON0_BPU1	= 0x2000,
   6.404 +	BPLCON0_BPU2	= 0x4000,
   6.405 +	BPLCON0_HIRES	= 0x8000
   6.406 +};
   6.407 +
   6.408 +#define BPLCON0_COUNT(x)	((x) << 12)
   6.409 +
   6.410 +#define CIAA_PA_FIR0	0x40
   6.411 +#define CIAA_PA_FIR1	0x80
   6.412 +
   6.413 +#endif	/* HWREGS_H_ */
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/src/amiga/inttypes.h	Wed Oct 25 19:34:53 2017 +0300
     7.3 @@ -0,0 +1,11 @@
     7.4 +#ifndef INTTYPES_H_
     7.5 +#define INTTYPES_H_
     7.6 +
     7.7 +typedef signed char int8_t;
     7.8 +typedef unsigned char uint8_t;
     7.9 +typedef short int16_t;
    7.10 +typedef unsigned short uint16_t;
    7.11 +typedef long int32_t;
    7.12 +typedef unsigned long uint32_t;
    7.13 +
    7.14 +#endif	/* INTTYPES_H_ */
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/src/amiga/mouse.c	Wed Oct 25 19:34:53 2017 +0300
     8.3 @@ -0,0 +1,69 @@
     8.4 +#include <stdlib.h>
     8.5 +#include "mouse.h"
     8.6 +#include "inttypes.h"
     8.7 +
     8.8 +
     8.9 +#define REG_BASE_ADDR	0xdff000
    8.10 +#define REGNO_JOY0DAT	0x00a
    8.11 +#define REG_JOY0DAT *(volatile uint16_t*)(REG_BASE_ADDR | REGNO_JOY0DAT)
    8.12 +#define REG_CIAA_PORTA	*(volatile uint8_t*)0xbfe001
    8.13 +
    8.14 +#define CIAA_PA_FIR0	0x40
    8.15 +#define CIAA_PA_FIR1	0x80
    8.16 +
    8.17 +static int xrng[2] = {0, 320};
    8.18 +static int yrng[2] = {0, 240};
    8.19 +
    8.20 +void set_mouse_bounds(int x0, int y0, int x1, int y1)
    8.21 +{
    8.22 +	xrng[0] = x0;
    8.23 +	xrng[1] = x1;
    8.24 +	yrng[0] = y0;
    8.25 +	yrng[1] = y1;
    8.26 +}
    8.27 +
    8.28 +int mouse_state(int *x, int *y)
    8.29 +{
    8.30 +	mouse_pos(x, y);
    8.31 +	return mouse_bnstate();
    8.32 +}
    8.33 +
    8.34 +int mouse_bnstate(void)
    8.35 +{
    8.36 +	/* TODO: handle right mouse button */
    8.37 +	return (REG_CIAA_PORTA & CIAA_PA_FIR0) ? 0 : 1;
    8.38 +}
    8.39 +
    8.40 +/* TODO: for when I feel like making a proper mouse handler
    8.41 + * use vblank interrupt vector to read the mouse register once
    8.42 + * and have mouse_pos (and friends) simply access the global data
    8.43 + */
    8.44 +void mouse_pos(int *x, int *y)
    8.45 +{
    8.46 +	static int xpos, ypos;
    8.47 +	static int prev_xcount, prev_ycount;
    8.48 +	int xcount, ycount, dx, dy;
    8.49 +	uint16_t raw = REG_JOY0DAT;
    8.50 +
    8.51 +	xcount = raw & 0xff;
    8.52 +	ycount = raw >> 8;
    8.53 +
    8.54 +	dx = xcount - prev_xcount;
    8.55 +	dy = ycount - prev_ycount;
    8.56 +
    8.57 +	if(abs(dx) > 127) dx = 255 - (xcount - prev_xcount);
    8.58 +	if(abs(dy) > 127) dy = 255 - (ycount - prev_ycount);
    8.59 +	prev_xcount = xcount;
    8.60 +	prev_ycount = ycount;
    8.61 +
    8.62 +	xpos += dx;
    8.63 +	ypos += dy;
    8.64 +
    8.65 +	if(xpos < xrng[0]) xpos = xrng[0];
    8.66 +	if(ypos < yrng[0]) ypos = yrng[0];
    8.67 +	if(xpos >= xrng[1]) xpos = xrng[1] - 1;
    8.68 +	if(ypos >= yrng[1]) ypos = yrng[1] - 1;
    8.69 +
    8.70 +	*x = xpos;
    8.71 +	*y = ypos;
    8.72 +}
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/src/amiga/mouse.h	Wed Oct 25 19:34:53 2017 +0300
     9.3 @@ -0,0 +1,9 @@
     9.4 +#ifndef MOUSE_H_
     9.5 +#define MOUSE_H_
     9.6 +
     9.7 +int mouse_state(int *x, int *y);
     9.8 +
     9.9 +int mouse_bnstate(void);
    9.10 +void mouse_pos(int *x, int *y);
    9.11 +
    9.12 +#endif	/* MOUSE_H_ */
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/src/gfx.h	Wed Oct 25 19:34:53 2017 +0300
    10.3 @@ -0,0 +1,69 @@
    10.4 +#ifndef GFX_H_
    10.5 +#define GFX_H_
    10.6 +
    10.7 +enum {
    10.8 +	GFX_HIRES	= 1,
    10.9 +	GFX_ILACE	= 2,
   10.10 +	GFX_HAM		= 4,
   10.11 +	GFX_DBLPF	= 8
   10.12 +};
   10.13 +
   10.14 +enum { GFX_EVLOOP_BLOCK, GFX_EVLOOP_NONBLOCK };
   10.15 +
   10.16 +enum {
   10.17 +	GFX_EV_QUIT,
   10.18 +	GFX_EV_KEY,
   10.19 +	GFX_EV_BUTTON,
   10.20 +	GFX_EV_MOTION
   10.21 +};
   10.22 +
   10.23 +struct gfx_event_key {
   10.24 +	int type;
   10.25 +	int key;
   10.26 +	int pressed;
   10.27 +};
   10.28 +
   10.29 +struct gfx_event_button {
   10.30 +	int type;
   10.31 +	int bn;
   10.32 +	int pressed;
   10.33 +	int x, y;
   10.34 +};
   10.35 +
   10.36 +struct gfx_event_motion {
   10.37 +	int type;
   10.38 +	int x, y;
   10.39 +};
   10.40 +
   10.41 +union gfx_event {
   10.42 +	int type;
   10.43 +	struct gfx_event_key key;
   10.44 +	struct gfx_event_button button;
   10.45 +	struct gfx_event_motion motion;
   10.46 +};
   10.47 +
   10.48 +struct gfx_rect {
   10.49 +	int x, y;
   10.50 +	int width, height;
   10.51 +};
   10.52 +
   10.53 +int gfx_init(int nbpl, unsigned int flags);
   10.54 +void gfx_shutdown(void);
   10.55 +
   10.56 +int gfx_screen_width(void);
   10.57 +int gfx_screen_height(void);
   10.58 +
   10.59 +void *gfx_set_framebuffer(void *fb, int width, int height);
   10.60 +void *gfx_get_framebuffer(void);
   10.61 +
   10.62 +int get_framebuffer_width(void);
   10.63 +int get_framebuffer_height(void);
   10.64 +
   10.65 +void gfx_begin_copperlist(void);
   10.66 +
   10.67 +int gfx_next_event(union gfx_event *ev, int block);
   10.68 +
   10.69 +void gfx_wait_vpos(int x);
   10.70 +void gfx_wait_vblank(void);
   10.71 +
   10.72 +#endif	/* GFX_H_ */
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/src/image.c	Wed Oct 25 19:34:53 2017 +0300
    11.3 @@ -0,0 +1,55 @@
    11.4 +#include <stdlib.h>
    11.5 +#include <string.h>
    11.6 +#include "image.h"
    11.7 +
    11.8 +struct ham_image *load_ham_image(const char *fname)
    11.9 +{
   11.10 +	return 0;	/* TODO */
   11.11 +}
   11.12 +
   11.13 +struct ham_image *gen_ham_image(int w, int h, int nbpl)
   11.14 +{
   11.15 +	int i, x, y;
   11.16 +	struct ham_image *img;
   11.17 +	unsigned char *pptr;
   11.18 +	unsigned char pixval;
   11.19 +	/*static const uint16_t defpal[] = {
   11.20 +		0x000, 0xf00, 0xff0, 0x0f0, 0x0ff, 0x00f, 0xf0f, 0xfff,
   11.21 +		0x444, 0x800, 0x880, 0x080, 0x088, 0x008, 0x808, 0x888
   11.22 +	};*/
   11.23 +
   11.24 +	if(!(img = malloc(sizeof *img))) {
   11.25 +		return 0;
   11.26 +	}
   11.27 +	if(!(img->pixels = calloc(w * h / 8 * nbpl, 1))) {
   11.28 +		free(img);
   11.29 +		return 0;
   11.30 +	}
   11.31 +	img->width = w;
   11.32 +	img->height = h;
   11.33 +	img->chglist = 0;
   11.34 +
   11.35 +	img->nbitplanes = nbpl;
   11.36 +	/*memcpy(img->palette, defpal, sizeof defpal);*/
   11.37 +	for(i=0; i<16; i++) {
   11.38 +		img->palette[i] = i | (i << 4) | (i << 8);
   11.39 +	}
   11.40 +
   11.41 +	pptr = img->pixels;
   11.42 +	for(i=0; i<4; i++) {
   11.43 +		pptr = img->pixels + i * w / 8;
   11.44 +		for(y=0; y<h; y++) {
   11.45 +			pixval = 0;
   11.46 +			for(x=0; x<w; x++) {
   11.47 +				pixval = (pixval >> 1) | ((((x ^ y) >> i) & 1) ? 0x80 : 0);
   11.48 +				if((x & 7) == 7) {
   11.49 +					*pptr++ = pixval;
   11.50 +					pixval = 0;
   11.51 +				}
   11.52 +			}
   11.53 +			pptr += w / 8 * (img->nbitplanes - 1);
   11.54 +		}
   11.55 +	}
   11.56 +
   11.57 +	return img;
   11.58 +}
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/src/image.h	Wed Oct 25 19:34:53 2017 +0300
    12.3 @@ -0,0 +1,23 @@
    12.4 +#ifndef IMAGE_H_
    12.5 +#define IMAGE_H_
    12.6 +
    12.7 +#include "inttypes.h"
    12.8 +
    12.9 +struct palchange {
   12.10 +	int line;
   12.11 +	uint16_t entry;	/* [ idx | r | g | b ] */
   12.12 +	struct palchange *next;
   12.13 +};
   12.14 +
   12.15 +struct ham_image {
   12.16 +	int width, height;
   12.17 +	unsigned char *pixels;
   12.18 +	uint16_t palette[16];
   12.19 +	int nbitplanes;
   12.20 +	struct palchange *chglist;
   12.21 +};
   12.22 +
   12.23 +struct ham_image *load_ham_image(const char *fname);
   12.24 +struct ham_image *gen_ham_image(int w, int h, int nbpl);
   12.25 +
   12.26 +#endif	/* IMAGE_H_ */
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/src/logger.c	Wed Oct 25 19:34:53 2017 +0300
    13.3 @@ -0,0 +1,26 @@
    13.4 +#include <stdio.h>
    13.5 +#include <stdlib.h>
    13.6 +#include <stdarg.h>
    13.7 +#include "logger.h"
    13.8 +
    13.9 +static FILE *fp;
   13.10 +
   13.11 +static void init(void)
   13.12 +{
   13.13 +	if(!(fp = fopen("logfile", "w"))) {
   13.14 +		printf("failed to open logfile\n");
   13.15 +		abort();
   13.16 +	}
   13.17 +	setvbuf(fp, 0, _IONBF, 0);
   13.18 +}
   13.19 +
   13.20 +void logmsg(const char *fmt, ...)
   13.21 +{
   13.22 +	va_list ap;
   13.23 +
   13.24 +	if(!fp) init();
   13.25 +
   13.26 +	va_start(ap, fmt);
   13.27 +	vfprintf(fp, fmt, ap);
   13.28 +	va_end(ap);
   13.29 +}
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/src/logger.h	Wed Oct 25 19:34:53 2017 +0300
    14.3 @@ -0,0 +1,6 @@
    14.4 +#ifndef LOGGER_H_
    14.5 +#define LOGGER_H_
    14.6 +
    14.7 +void logmsg(const char *fmt, ...);
    14.8 +
    14.9 +#endif	/* LOGGER_H_ */
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/src/main.c	Wed Oct 25 19:34:53 2017 +0300
    15.3 @@ -0,0 +1,106 @@
    15.4 +#include <stdio.h>
    15.5 +#include <stdlib.h>
    15.6 +#include <string.h>
    15.7 +#include <assert.h>
    15.8 +#include "gfx.h"
    15.9 +#include "image.h"
   15.10 +#include "logger.h"
   15.11 +
   15.12 +#include "hwregs.h"
   15.13 +#include "copper.h"
   15.14 +
   15.15 +
   15.16 +static int proc_event(union gfx_event *ev);
   15.17 +static void show_ham_image(struct ham_image *img);
   15.18 +
   15.19 +static int win_width, win_height;
   15.20 +
   15.21 +int main(int argc, char **argv)
   15.22 +{
   15.23 +	struct ham_image *img;
   15.24 +
   15.25 +	if(argv[1]) {
   15.26 +		if(!(img = load_ham_image(argv[1]))) {
   15.27 +			fprintf(stderr, "failed to load image: %s\n", argv[1]);
   15.28 +			return 1;
   15.29 +		}
   15.30 +	} else {
   15.31 +		printf("generating test image ...\n");
   15.32 +		if(!(img = gen_ham_image(320, 256, 6))) {
   15.33 +			fprintf(stderr, "failed to generate image\n");
   15.34 +			return 1;
   15.35 +		}
   15.36 +	}
   15.37 +
   15.38 +	if(gfx_init(6, GFX_HAM) == -1) {
   15.39 +		return 1;
   15.40 +	}
   15.41 +	gfx_wait_vblank();
   15.42 +	show_ham_image(img);
   15.43 +
   15.44 +	for(;;) {
   15.45 +		union gfx_event ev;
   15.46 +		if(gfx_next_event(&ev, GFX_EVLOOP_BLOCK)) {
   15.47 +			if(proc_event(&ev) == -1) {
   15.48 +				break;
   15.49 +			}
   15.50 +		}
   15.51 +	}
   15.52 +
   15.53 +	gfx_shutdown();
   15.54 +	return 0;
   15.55 +}
   15.56 +
   15.57 +static int proc_event(union gfx_event *ev)
   15.58 +{
   15.59 +	switch(ev->type) {
   15.60 +	case GFX_EV_QUIT:
   15.61 +		return -1;
   15.62 +
   15.63 +	case GFX_EV_KEY:
   15.64 +		switch(ev->key.key) {
   15.65 +		case 27:
   15.66 +			return -1;
   15.67 +		default:
   15.68 +			break;
   15.69 +		}
   15.70 +		break;
   15.71 +
   15.72 +	default:
   15.73 +		break;
   15.74 +	}
   15.75 +	return 0;
   15.76 +}
   15.77 +
   15.78 +#define NUM_BPL		6
   15.79 +static void show_ham_image(struct ham_image *img)
   15.80 +{
   15.81 +	int i, j, k, fbwidth, fbheight, ncolors, prev_line;
   15.82 +	unsigned char *fbptr = gfx_get_framebuffer();
   15.83 +	struct palchange *chg = img->chglist;
   15.84 +
   15.85 +	fbwidth = gfx_framebuffer_width();
   15.86 +	fbheight = gfx_framebuffer_height();
   15.87 +
   15.88 +	memcpy(fbptr, img->pixels, fbwidth * fbheight / 8 * NUM_BPL);
   15.89 +
   15.90 +	/* create copper list that handles the palette */
   15.91 +	clear_copper();
   15.92 +	gfx_begin_copperlist();
   15.93 +	/* initial palette at the start of frame */
   15.94 +	for(i=0; i<16; i++) {
   15.95 +		add_copper(COPPER_MOVE(REGN_COLOR(i), img->palette[i]));
   15.96 +		logmsg("copper palette[%d]: %x\n", i, (unsigned int)img->palette[i]);
   15.97 +	}
   15.98 +	/* add copper instructions for palette changes according to the image changelist */
   15.99 +	prev_line = -1;
  15.100 +	while(chg) {
  15.101 +		assert(chg->line >= prev_line);
  15.102 +		if(chg->line != prev_line) {
  15.103 +			prev_line = chg->line;
  15.104 +			add_copper(COPPER_VWAIT(chg->line));
  15.105 +		}
  15.106 +		add_copper(COPPER_MOVE(REGN_COLOR(chg->entry >> 12), chg->entry & 0xfff));
  15.107 +	}
  15.108 +	add_copper(COPPER_END);
  15.109 +}
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/tools/convhammer/Makefile	Wed Oct 25 19:34:53 2017 +0300
    16.3 @@ -0,0 +1,12 @@
    16.4 +src = $(wildcard *.c)
    16.5 +obj = $(src:.c=.o)
    16.6 +bin = convhammer
    16.7 +
    16.8 +CFLAGS = -pedantic -Wall -g -I../../src
    16.9 +
   16.10 +$(bin): $(obj)
   16.11 +	$(CC) -o $@ $(obj) $(LDFLAGS)
   16.12 +
   16.13 +.PHONY: clean
   16.14 +clean:
   16.15 +	rm -f $(obj) $(bin)
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/tools/convhammer/main.c	Wed Oct 25 19:34:53 2017 +0300
    17.3 @@ -0,0 +1,10 @@
    17.4 +#include <stdio.h>
    17.5 +#include <stdlib.h>
    17.6 +#include "image.h"
    17.7 +
    17.8 +struct ham_image *load_hammer(const char *fname);
    17.9 +int save_ham(struct ham_image *img, const char *fname);
   17.10 +
   17.11 +int main(int argc, char **argv)
   17.12 +{
   17.13 +}