diff --git a/MISCFILES b/MISCFILES index 6985551b..e43e8a63 100644 --- a/MISCFILES +++ b/MISCFILES @@ -1,4 +1,4 @@ # This file gets included by the Makefile in this directory to determine # the files that should go both into source and binary distributions. -MISCFILES = gem.h gemx.h mt_gem.h mt_gemx.h +MISCFILES = gem.h gemx.h mt_gem.h mt_gemx.h include/arm/compiler.h diff --git a/Makefile b/Makefile index 3ee11204..306baf23 100644 --- a/Makefile +++ b/Makefile @@ -14,11 +14,23 @@ top_builddir = . default: all +ARCH ?= m68k + +ifeq ($(ARCH),arm) +CROSS_TOOL ?= arm-none-eabi +endif + include $(top_srcdir)/CONFIGVARS include $(top_srcdir)/RULES include $(top_srcdir)/PHONY include $(srcdir)/VERSION +ifeq ($(ARCH),arm) +CFLAGS_arm = -mfloat-abi=hard -mfpu=vfp -mword-relocations +ARCH_INCLUDES = -I$(srcdir)/include/arm +ALL_LIBS = arm +else + CFLAGS_68000 = -m68000 CFLAGS_68000.short = -m68000 -mshort CFLAGS_68020-60 = -m68020-60 @@ -36,7 +48,9 @@ CFLAGS_5475.short.fastcall = -mcpu=5475 -mshort -mfastcall ALL_LIBS = 68000 68020-60 68000.short 68020-60.short 5475 5475.short BUILD_FAST=$(shell if $(CC) -mfastcall -E - < /dev/null >/dev/null 2>&1; then echo Y; else echo N; fi) ifeq ($(BUILD_FAST), Y) -ALL_LIBS += 68000.fastcall 68020-60.fastcall 68000.short.fastcall 68020-60.short.fastcall 5475.fastcall 5475.short.fastcall + ALL_LIBS += 68000.fastcall 68020-60.fastcall 68000.short.fastcall 68020-60.short.fastcall 5475.fastcall 5475.short.fastcall +endif + endif all-here: $(foreach LIB, $(ALL_LIBS), .lib$(LIB)/libgem.a) @@ -63,7 +77,7 @@ OBJS_$(1) = $(foreach FILE, $(COBJS) $(SOBJS), .lib$(1)/$(notdir $(basename $(FI endef define CC_TEMPLATE .lib$(1)/$(notdir $(basename $(2))).o: $(2) mt_gem.h Makefile - $$(AM_V_CC)$$(CC) $$(CFLAGS_$(1)) $$(CFLAGS) -I$$(srcdir) -c -o $$@ $$< + $$(AM_V_CC)$$(CC) $$(CFLAGS_$(1)) $$(CFLAGS) $$(ARCH_INCLUDES) -I$$(srcdir) -c -o $$@ $$< endef $(foreach DIR,$(ALL_LIBS),$(eval $(call LIB_TEMPLATE,$(DIR)))) @@ -166,6 +180,27 @@ mt_gem.h: mt_gem.h.in VERSION mv $(srcdir)/mt_gem.tmp $(srcdir)/mt_gem.h # $(MOVEIFCHANGE) $(srcdir)/mt_gem.tmp $(srcdir)/mt_gem.h +ifeq ($(ARCH),arm) +install: + install -m 755 -d $(DESTDIR)$(PREFIX)/lib + install -m 644 .libarm/libgem.a $(DESTDIR)$(PREFIX)/lib/libgem.a + install -m 755 -d $(DESTDIR)$(PREFIX)/include + install -m 644 gem.h $(DESTDIR)$(PREFIX)/include + install -m 644 gemx.h $(DESTDIR)$(PREFIX)/include + install -m 644 mt_gem.h $(DESTDIR)$(PREFIX)/include + install -m 644 mt_gemx.h $(DESTDIR)$(PREFIX)/include + install -m 644 include/arm/compiler.h $(DESTDIR)$(PREFIX)/include + +uninstall: + rm -f $(DESTDIR)$(PREFIX)/lib/libgem.a + rm -f $(DESTDIR)$(PREFIX)/include/gem.h + rm -f $(DESTDIR)$(PREFIX)/include/gemx.h + rm -f $(DESTDIR)$(PREFIX)/include/mt_gem.h + rm -f $(DESTDIR)$(PREFIX)/include/mt_gemx.h + rm -f $(DESTDIR)$(PREFIX)/include/compiler.h + +else + install: @for i in $(ALL_LIBS); do \ cpu=`echo $$i | cut -d . -f 1`; \ @@ -197,6 +232,8 @@ uninstall: rm -f $(DESTDIR)$(PREFIX)/include/mt_gem.h rm -f $(DESTDIR)$(PREFIX)/include/mt_gemx.h +endif + ifneq (clean,$(findstring clean,$(MAKECMDGOALS))) DEPS_MAGIC := $(shell mkdir -p $(foreach LIB, $(ALL_LIBS), .lib$(LIB))) > /dev/null 2>&1 || :) diff --git a/RULES b/RULES index 8b5e8791..4b39e94c 100644 --- a/RULES +++ b/RULES @@ -119,6 +119,7 @@ distdir: $(DISTFILES) distdir-local mkdir -p $(distdir) @for file in $(DISTFILES); do \ d=$(srcdir); \ + mkdir -p `dirname $(distdir)/$$file` || exit 1; \ test -d $$d/$$file \ || test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2>/dev/null \ diff --git a/_gc_aes.c b/_gc_aes.c index 23edac79..af8b0450 100644 --- a/_gc_aes.c +++ b/_gc_aes.c @@ -3,6 +3,17 @@ #ifdef __GNUC__ void aes(AESPB *pb) { +#if defined(__arm__) + register long r0 __asm__("r0") = 200; + register AESPB *r1 __asm__("r1") = pb; + + __asm__ __volatile__ ( + "svc #2" + : "+r"(r0), "+r"(r1) + : + : "r2", "r3", "r7", "r12", "lr", "memory", "cc" + ); +#else register long d1 __asm__("d1") = (long)pb; __asm__ __volatile__ ( @@ -12,5 +23,6 @@ void aes(AESPB *pb) : "r"(d1) : "d0", "d2", "a0", "a1", "a2", "memory", "cc" ); +#endif } #endif diff --git a/_gc_vdi.c b/_gc_vdi.c index f2b84714..1b3a5689 100644 --- a/_gc_vdi.c +++ b/_gc_vdi.c @@ -3,6 +3,47 @@ #ifdef __GNUC__ void vdi(VDIPB *pb) { +#if defined(__arm__) + typedef struct + { + short code, nptsin, nptsout, nintin, nintout, subcode, handle, pad; + void *ptr1, *ptr2; + } ARM_VDICONTROL; + ARM_VDICONTROL control; + VDIPB arm_pb; + + control.code = pb->control[0]; + control.nptsin = pb->control[1]; + control.nptsout = pb->control[2]; + control.nintin = pb->control[3]; + control.nintout = pb->control[4]; + control.subcode = pb->control[5]; + control.handle = pb->control[6]; + control.pad = 0; + control.ptr1 = vdi_control_get_ptr(pb->control, 0); + control.ptr2 = vdi_control_get_ptr(pb->control, 1); + + arm_pb.control = (short *)&control; + arm_pb.intin = pb->intin; + arm_pb.ptsin = pb->ptsin; + arm_pb.intout = pb->intout; + arm_pb.ptsout = pb->ptsout; + + __asm__ __volatile__ ( + "mov r0, #0x73\n\t" + "mov r1, %0\n\t" + "svc #2" + : + : "r"(&arm_pb) + : "r0", "r1", "r2", "r3", "r7", "r12", "lr", "memory", "cc" + ); + + pb->control[2] = control.nptsout; + pb->control[4] = control.nintout; + pb->control[6] = control.handle; + vdi_control_set_ptr(pb->control, 0, control.ptr1); + vdi_control_set_ptr(pb->control, 1, control.ptr2); +#else register long d1 __asm__("d1") = (long)pb; __asm__ __volatile__ ( @@ -12,5 +53,6 @@ void vdi(VDIPB *pb) : "r"(d1) : "d0", "d2", "a0", "a1", "a2", "memory", "cc" ); +#endif } #endif diff --git a/_gc_vq_gdos.c b/_gc_vq_gdos.c index ad573be5..cca26e16 100644 --- a/_gc_vq_gdos.c +++ b/_gc_vq_gdos.c @@ -3,6 +3,17 @@ #ifdef __GNUC__ short vq_gdos(void) { +#if defined(__arm__) + register long ret __asm__("r0") = -2; + + __asm__ __volatile__ ( + "svc #2" + : "+r"(ret) + : + : "r1", "r2", "r3", "r7", "r12", "lr", "memory", "cc" + ); + return ret == -2 ? 0 : 1; +#else register long ret __asm__("d0"); __asm__ __volatile__ ( @@ -19,5 +30,6 @@ short vq_gdos(void) : "d1", "d2", "a0", "a1", "a2", "memory", "cc" ); return ret; +#endif } #endif diff --git a/_gc_vq_vgdos.c b/_gc_vq_vgdos.c index acdcaf2b..ebb03099 100644 --- a/_gc_vq_vgdos.c +++ b/_gc_vq_vgdos.c @@ -3,6 +3,17 @@ #ifdef __GNUC__ long vq_vgdos(void) { +#if defined(__arm__) + register long ret __asm__("r0") = -2; + + __asm__ __volatile__ ( + "svc #2" + : "+r"(ret) + : + : "r1", "r2", "r3", "r7", "r12", "lr", "memory", "cc" + ); + return ret; +#else register long ret __asm__("d0"); __asm__ __volatile__ ( @@ -13,5 +24,6 @@ long vq_vgdos(void) : "d1", "d2", "a0", "a1", "a2", "memory", "cc" ); return (short)ret == -2 ? (short)ret : ret; +#endif } #endif diff --git a/a__appl_yield.c b/a__appl_yield.c index cfe48f19..c085af84 100644 --- a/a__appl_yield.c +++ b/a__appl_yield.c @@ -13,6 +13,16 @@ #ifdef __GNUC__ void _appl_yield(void) { +#if defined(__arm__) + register long r0 __asm__("r0") = 201; + + __asm__ volatile ( + "svc #2" + : "+r"(r0) + : + : "r1", "r2", "r3", "r7", "r12", "lr", "memory", "cc" + ); +#else __asm__ volatile ( "move.w #201,%%d0\n\t" "trap #2" @@ -20,6 +30,7 @@ void _appl_yield(void) : : "d0","d1","d2","a0","a1","a2","memory","cc" ); +#endif } #endif diff --git a/gem_aesP.h b/gem_aesP.h index 6f987598..0c99ba2d 100644 --- a/gem_aesP.h +++ b/gem_aesP.h @@ -21,6 +21,19 @@ #if defined(__GNUC__) && !defined(__NO_INLINE__) +#if defined(__arm__) + +static inline void +_aes_trap(AESPB *aespb) +{ + /* pTOS ARM passes the AES opcode in r0 and the parameter block in r1. */ + aes(aespb); +} + +#define AES_TRAP(aespb) _aes_trap(&aespb) + +#else + static inline void _aes_trap (AESPB * aespb) { @@ -35,6 +48,8 @@ _aes_trap (AESPB * aespb) } #define AES_TRAP(aespb) _aes_trap(&aespb) +#endif + #else #if defined(__VBCC__) diff --git a/gem_vdiP.h b/gem_vdiP.h index 93ef3e59..c1e27822 100644 --- a/gem_vdiP.h +++ b/gem_vdiP.h @@ -20,6 +20,38 @@ #if defined(__GNUC__) && !defined(__NO_INLINE__) +#if defined(__arm__) + +static inline void +_vdi_trap_esc(VDIPB *vdipb, long cntrl_0_1, long cntrl_2_3, + long cntrl_4_5, short handle) +{ + short *control = vdipb->control; + + control[0] = (short)(cntrl_0_1 >> 16); + control[1] = (short)cntrl_0_1; + control[2] = (short)(cntrl_2_3 >> 16); + control[3] = (short)cntrl_2_3; + control[4] = (short)(cntrl_4_5 >> 16); + control[5] = (short)cntrl_4_5; + control[6] = handle; + vdi(vdipb); +} + +#define VDI_TRAP_ESC(vdipb, handle, opcode, subop, nptsin, nintin) \ + _vdi_trap_esc(&vdipb, (opcode##uL << 16) | nptsin, nintin, subop, handle) + +static inline void +_vdi_trap_00(VDIPB *vdipb, long cntrl_0_1, short handle) +{ + _vdi_trap_esc(vdipb, cntrl_0_1, 0, 0, handle); +} + +#define VDI_TRAP_00(vdipb, handle, opcode) \ + _vdi_trap_00(&vdipb, (opcode##uL << 16), handle) + +#else + static inline void _vdi_trap_esc (VDIPB * vdipb, long cntrl_0_1, long cntrl_2_3, long cntrl_4_5, short handle) @@ -64,6 +96,7 @@ _vdi_trap_00 (VDIPB * vdipb, long cntrl_0_1, short handle) #define VDI_TRAP_00(vdipb, handle, opcode) \ _vdi_trap_00 (&vdipb, (opcode##uL<<16), handle) +#endif #else @@ -155,6 +188,30 @@ __regsused("d0/d1/a0/a1") void _vdi_trap_00( #define N_PTRINTS (sizeof(void *) / sizeof(short)) +/* Avoid unaligned control[7..] pointer access. */ +static __inline void +vdi_control_set_ptr(short *control, short n, const void *value) +{ + unsigned char *dest = (unsigned char *)control + (7 + n * N_PTRINTS) * sizeof(*control); + const unsigned char *source = (const unsigned char *)&value; + unsigned long i; + + for (i = 0; i < sizeof(value); i++) + dest[i] = source[i]; +} + +static __inline void * +vdi_control_get_ptr(const short *control, short n) +{ + void *value; + const unsigned char *source = (const unsigned char *)control + (7 + n * N_PTRINTS) * sizeof(*control); + unsigned char *dest = (unsigned char *)&value; + unsigned long i; + + for (i = 0; i < sizeof(value); i++) + dest[i] = source[i]; + return value; +} #ifdef __GNUC__ /* to avoid "dereferencing type-punned pointer" */ diff --git a/include/arm/compiler.h b/include/arm/compiler.h new file mode 100644 index 00000000..01315c8c --- /dev/null +++ b/include/arm/compiler.h @@ -0,0 +1,14 @@ +#ifndef _GEMLIB_ARM_COMPILER_H +#define _GEMLIB_ARM_COMPILER_H + +#ifdef __cplusplus +#define __BEGIN_DECLS extern "C" { +#define __END_DECLS } +#else +#define __BEGIN_DECLS +#define __END_DECLS +#endif + +#define __CDECL + +#endif diff --git a/mt_gem.h.in b/mt_gem.h.in index 094948ab..2a0249ff 100644 --- a/mt_gem.h.in +++ b/mt_gem.h.in @@ -2050,6 +2050,15 @@ typedef struct cicon_blk /** Bit Field OBject SPECification */ typedef struct { + #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + unsigned interiorcol : 4; /**< color of interior */ + unsigned fillpattern : 3; /**< fill pattern index */ + unsigned textmode : 1; /**< transparent or replace */ + unsigned textcol : 4; /**< color of text */ + unsigned framecol : 4; /**< color of frame */ + signed framesize : 8; /**< size of frame */ + unsigned character : 8; /**< character to display (BOXCHAR) */ + #else unsigned character : 8; /**< character to display (BOXCHAR) */ signed framesize : 8; /**< size of frame */ unsigned framecol : 4; /**< color of frame */ @@ -2057,6 +2066,7 @@ typedef struct unsigned textmode : 1; /**< transparent or replace */ unsigned fillpattern : 3; /**< fill pattern index */ unsigned interiorcol : 4; /**< color of interior */ + #endif } BFOBSPEC; /** User block */ diff --git a/n_v_open_bm.c b/n_v_open_bm.c index 9aaa8b66..156a4de8 100644 --- a/n_v_open_bm.c +++ b/n_v_open_bm.c @@ -33,7 +33,7 @@ v_open_bm (short base_handle, GCBITMAP * bitmap, short color_flags, vdi_intin[2] = pixel_width; vdi_intin[3] = pixel_height; - vdi_control_ptr(0, GCBITMAP *) = bitmap; + vdi_control_set_ptr(vdi_control, 0, bitmap); VDI_TRAP_ESC (vdi_params, base_handle, 100,3, 0,4); return vdi_control[6]; diff --git a/n_v_opnbm.c b/n_v_opnbm.c index 4092425c..2855a0e8 100644 --- a/n_v_opnbm.c +++ b/n_v_opnbm.c @@ -60,7 +60,7 @@ v_opnbm (short *work_in, MFDB *bitmap, short *handle, short *work_out) VDI_PARAMS(vdi_control, work_in, 0L, &work_out[0], &work_out[45]); - vdi_control_ptr(0, MFDB *) = bitmap; + vdi_control_set_ptr(vdi_control, 0, bitmap); VDI_TRAP_ESC (vdi_params, *handle, 100,1, 0,20); diff --git a/n_vr_transfer_bits.c b/n_vr_transfer_bits.c index 57364f0b..4da713bc 100644 --- a/n_vr_transfer_bits.c +++ b/n_vr_transfer_bits.c @@ -34,9 +34,9 @@ vr_transfer_bits (short handle, GCBITMAP * src_bm, GCBITMAP * dst_bm, *((RECT16*)&vdi_ptsin[0]) = *((const RECT16*)src_rect); *((RECT16*)&vdi_ptsin[4]) = *((const RECT16*)dst_rect); - vdi_control_ptr(0, GCBITMAP *) = src_bm; - vdi_control_ptr(1, GCBITMAP *) = dst_bm; - vdi_control_ptr(2, void *) = 0; + vdi_control_set_ptr(vdi_control, 0, src_bm); + vdi_control_set_ptr(vdi_control, 1, dst_bm); + vdi_control_set_ptr(vdi_control, 2, 0); VDI_TRAP (vdi_params, handle, 170, 4,4); } diff --git a/vex_butv.c b/vex_butv.c index e0b0afc3..4d379556 100644 --- a/vex_butv.c +++ b/vex_butv.c @@ -21,11 +21,11 @@ vex_butv (short handle, void *newhdlr, void **old) VDI_PARAMS(vdi_control, 0L, 0L, vdi_dummy, vdi_dummy ); - vdi_control_ptr(0, void *) = newhdlr; - vdi_control_ptr(1, void *) = 0; + vdi_control_set_ptr(vdi_control, 0, newhdlr); + vdi_control_set_ptr(vdi_control, 1, 0); VDI_TRAP_00 (vdi_params, handle, 125); if (old) - *old = vdi_control_ptr(1, void *); + *old = vdi_control_get_ptr(vdi_control, 1); } diff --git a/vex_curv.c b/vex_curv.c index 902ba4bb..504ed7fd 100644 --- a/vex_curv.c +++ b/vex_curv.c @@ -27,11 +27,11 @@ vex_curv (short handle, void *new, void **old) VDI_PARAMS(vdi_control, 0L, 0L, vdi_dummy, vdi_dummy); - vdi_control_ptr(0, void *) = new; - vdi_control_ptr(1, void *) = 0; + vdi_control_set_ptr(vdi_control, 0, new); + vdi_control_set_ptr(vdi_control, 1, 0); VDI_TRAP_00 (vdi_params, handle, 127); if (old) - *old = vdi_control_ptr(1, void *); + *old = vdi_control_get_ptr(vdi_control, 1); } diff --git a/vex_motv.c b/vex_motv.c index d0fae1a4..fe360b26 100644 --- a/vex_motv.c +++ b/vex_motv.c @@ -23,11 +23,11 @@ vex_motv (short handle, void *new, void **old) VDI_PARAMS(vdi_control, 0L, 0L, vdi_dummy, vdi_dummy ); - vdi_control_ptr(0, void *) = new; - vdi_control_ptr(1, void *) = 0; + vdi_control_set_ptr(vdi_control, 0, new); + vdi_control_set_ptr(vdi_control, 1, 0); VDI_TRAP_00 (vdi_params, handle, 126); if (old) - *old = vdi_control_ptr(1, void *); + *old = vdi_control_get_ptr(vdi_control, 1); } diff --git a/vex_timv.c b/vex_timv.c index a946b6c1..99f9ecf5 100644 --- a/vex_timv.c +++ b/vex_timv.c @@ -24,13 +24,13 @@ vex_timv (short handle, void *time_addr, void **otime_addr, short *time_conv) VDI_PARAMS(vdi_control, 0L, 0L, vdi_intout, vdi_dummy ); - vdi_control_ptr(0, void *) = time_addr; - vdi_control_ptr(1, void *) = 0; + vdi_control_set_ptr(vdi_control, 0, time_addr); + vdi_control_set_ptr(vdi_control, 1, 0); VDI_TRAP_00 (vdi_params, handle, 118); if (otime_addr) - *otime_addr = vdi_control_ptr(1, void *); + *otime_addr = vdi_control_get_ptr(vdi_control, 1); if (time_conv) *time_conv = vdi_intout[0]; } diff --git a/vex_wheelv.c b/vex_wheelv.c index b4ba40a9..a0eaf413 100644 --- a/vex_wheelv.c +++ b/vex_wheelv.c @@ -24,11 +24,11 @@ vex_wheelv (short handle, void *new, void **old) VDI_PARAMS(vdi_control, 0L, 0L, vdi_dummy, vdi_dummy ); - vdi_control_ptr(0, void *) = new; - vdi_control_ptr(1, void *) = 0; + vdi_control_set_ptr(vdi_control, 0, new); + vdi_control_set_ptr(vdi_control, 1, 0); VDI_TRAP_00 (vdi_params, handle, 134); if (old) - *old = vdi_control_ptr(1, void *); + *old = vdi_control_get_ptr(vdi_control, 1); } diff --git a/vr_trnfm.c b/vr_trnfm.c index 5f1889cf..7d6ac511 100644 --- a/vr_trnfm.c +++ b/vr_trnfm.c @@ -19,8 +19,8 @@ vr_trnfm (short handle, MFDB * src, MFDB * dst) VDI_PARAMS(vdi_control, 0L, 0L, vdi_dummy, vdi_dummy ); - vdi_control_ptr(0, MFDB *) = src; - vdi_control_ptr(1, MFDB *) = dst; + vdi_control_set_ptr(vdi_control, 0, src); + vdi_control_set_ptr(vdi_control, 1, dst); VDI_TRAP_00 (vdi_params, handle, 110); } diff --git a/vro_cpyfm.c b/vro_cpyfm.c index f94a7302..111cc4a7 100644 --- a/vro_cpyfm.c +++ b/vro_cpyfm.c @@ -56,8 +56,8 @@ vro_cpyfm (short handle, short mode, short pxy[], MFDB *src, MFDB *dst) VDI_PARAMS(vdi_control, &mode, pxy, vdi_dummy, vdi_dummy); - vdi_control_ptr(0, MFDB *) = src; - vdi_control_ptr(1, MFDB *) = dst; + vdi_control_set_ptr(vdi_control, 0, src); + vdi_control_set_ptr(vdi_control, 1, dst); VDI_TRAP (vdi_params, handle, 109, 4,1); } diff --git a/vrt_cpyfm.c b/vrt_cpyfm.c index 0fc290ea..366e18d3 100644 --- a/vrt_cpyfm.c +++ b/vrt_cpyfm.c @@ -42,8 +42,8 @@ vrt_cpyfm (short handle, short mode, short pxy[], MFDB *src, MFDB *dst, vdi_intin[0] = mode; vdi_intin[1] = color[0]; vdi_intin[2] = color[1]; - vdi_control_ptr(0, MFDB *) = src; - vdi_control_ptr(1, MFDB *) = dst; + vdi_control_set_ptr(vdi_control, 0, src); + vdi_control_set_ptr(vdi_control, 1, dst); VDI_TRAP (vdi_params, handle, 121, 4,3); }