From: Joost Y. D. <jo...@da...> - 2011-07-09 07:40:23
|
Hey, are you planning on making a point release with this fix or should I just trivially backport it to 0.8.1 for within Debian? Joost On Saturday 09 July 2011 09:05:10 m97...@us... wrote: > Revision: 12202 > http://openmsx.svn.sourceforge.net/openmsx/?rev=12202&view=rev > Author: m9710797 > Date: 2011-07-09 07:05:09 +0000 (Sat, 09 Jul 2011) > > Log Message: > ----------- > Make our ARM inline asm routines compile in Thumb2 mode > > Modern ARM distributions (e.g. Ubuntu 11.04) by default generate code for > ARM-Thumb2 mode. But before this patch, our code contained some ARM inline > asm routines that are not valid Thumb2 instructions. Now the code should > compile fine in both ARM- and Thumb2-mode (but not Thumb1). > > FYI: > ARM-mode: All instructions are 32-bit. > Thumb1-mode: All instructions are 16-bit, (of course) these can only > represent a subset of the full (32-bit) ARM instructions. > Thumb2-mode: Mix of 16-bit and 32-bit instructions. Many (but not all) > ARM instructions can directly be represented as a single > Thumb2 instruction. The most common instructions only take 16-bit, the > others are 32-bit (of course with some limitations). > > We could have 'fixed' the compilation errors by simply forcing ARM-mode > (gcc compiler switch '-marm'). But that would completely eliminate the > code-size advantage of Thumb2 mode (and because of better cache locality > this often also implies a speed-advantage). (There are also a few ARM > cores that only support Thumb2-mode (no ARM-mode), OTOH those cores are > often also not suitable to be used as a general purpose application CPU.) > > Because most ARM instructions have a direct mapping to a single Thumb2 > instruction, it wasn't that hard to rewrite our code so that it compiles in > both ARM and Thumb2 mode. Making it also compile in Thumb1 mode is much > harder and it would also degrade performance when that same code is > compiled to ARM or Thumb2 code. > > These are the most important changes I had to make: > > - In ARM-mode there's an instruction: > ORR Rd,Rn,Rm,LSL Rs // equivalent to: Rd = Rn | (Rm << Rs) > In thumb2-mode these 'inline shifts' are only possible with an immediate > shift count (not a variable count from another register as in this case). > As a solution I've split this instruction in two. For ARM-mode this > introduces a small inefficiency, but that's a small price compared to > having to maintain two separate versions. > > - In ARM-mode each instruction can be conditionally executed. In Thumb2 > there's a 'IT..' instruction that conditionally executes the next (1-4) > instructions. Though luckily the same asm syntax can be used for both > modes (when you use the 'IT..' instruction in your asm code, it either > expands to a real thumb2 instruction, or it only influences the condition > bits in the next instructions). > > - In some cases gcc complains about the use of register 'r7' (thumb2 mode) > or register 'r11' (arm mode) (not clear to me when/why exactly, though > it's related to the use of this same register as a > frame-pointer-register). As a workaround I've rewritten the code to avoid > using either of these two registers. > > - Some tweaks to allow to use short (16-bit) instead of long (32-bit) > instructions. For example, in ARM and thumb2 mode, for most instructions, > there's a variant that does and one that does not update the status > flags. Short thumb2 instructions often only have the variant that does > update the flags. So when the value of the status flags doesn't matter > it's sometimes better to choose the variant that does update the flags. > > Modified Paths: > -------------- > openmsx/trunk/src/sound/MSXMixer.cc > openmsx/trunk/src/sound/ResampleLQ.cc > openmsx/trunk/src/sound/SCC.cc > openmsx/trunk/src/utils/DivModByConst.hh > openmsx/trunk/src/utils/DivModBySame.hh > openmsx/trunk/src/utils/MemoryOps.cc > openmsx/trunk/src/video/BitmapConverter.cc > openmsx/trunk/src/video/CharacterConverter.cc > openmsx/trunk/src/video/scalers/LineScalers.hh > > Modified: openmsx/trunk/src/sound/MSXMixer.cc > =================================================================== > --- openmsx/trunk/src/sound/MSXMixer.cc 2011-07-07 17:59:13 UTC (rev 12201) > +++ openmsx/trunk/src/sound/MSXMixer.cc 2011-07-09 07:05:09 UTC (rev 12202) > @@ -243,12 +243,12 @@ > #ifdef __arm__ > asm volatile ( > "0:\n\t" > - "ldmia %[in]!,{r4-r7}\n\t" > - "mul r4,%[f],r4\n\t" > - "mul r5,%[f],r5\n\t" > - "mul r6,%[f],r6\n\t" > - "mul r7,%[f],r7\n\t" > - "stmia %[out]!,{r4-r7}\n\t" > + "ldmia %[in]!,{r3-r6}\n\t" > + "muls r3,%[f],r3\n\t" > + "muls r4,%[f],r4\n\t" > + "muls r5,%[f],r5\n\t" > + "muls r6,%[f],r6\n\t" > + "stmia %[out]!,{r3-r6}\n\t" > "subs %[n],%[n],#4\n\t" > "bgt 0b\n\t" > > : // no output > > @@ -256,7 +256,7 @@ > , [out] "r" (monoBuf) > , [f] "r" (l1) > , [n] "r" (samples) > - : "r4","r5","r6","r7" > + : "r3","r4","r5","r6" > ); > #else > for (unsigned i = 0; i < samples; ++i) { > @@ -268,13 +268,13 @@ > #ifdef __arm__ > asm volatile ( > "0:\n\t" > - "ldmia %[in]!,{r3-r6}\n\t" > - "ldmia %[out],{r7-r10}\n\t" > - "mla r3,%[f],r3,r7\n\t" > - "mla r4,%[f],r4,r8\n\t" > - "mla r5,%[f],r5,r9\n\t" > - "mla r6,%[f],r6,r10\n\t" > - "stmia %[out]!,{r3-r6}\n\t" > + "ldmia %[in]!,{r3,r4,r5,r6}\n\t" > + "ldmia %[out],{r8,r9,r10,r12}\n\t" > + "mla r3,%[f],r3,r8\n\t" > + "mla r4,%[f],r4,r9\n\t" > + "mla r5,%[f],r5,r10\n\t" > + "mla r6,%[f],r6,r12\n\t" > + "stmia %[out]!,{r3,r4,r5,r6}\n\t" > "subs %[n],%[n],#4\n\t" > "bgt 0b\n\t" > > : // no output > > @@ -283,7 +283,7 @@ > , [f] "r" (l1) > , [n] "r" (samples) > > : "r3","r4","r5","r6" > > - , "r7","r8","r9","r10" > + , "r8","r9","r10","r12" > ); > #else > for (unsigned i = 0; i < samples; ++i) { > @@ -408,10 +408,11 @@ > "rsb %[o],%[o],%[o],LSL #9\n\t" > "rsb %[o],%[p],%[o],ASR #9\n\t" > "ldr %[p],[%[in]],#4\n\t" > - "mov %[p],%[p],ASR #8\n\t" > + "asrs %[p],%[p],#8\n\t" > "add %[o],%[o],%[p]\n\t" > - "mov %[t],%[o],LSL #16\n\t" > + "lsls %[t],%[o],#16\n\t" > "cmp %[o],%[t],ASR #16\n\t" > + "it ne\n\t" > "subne %[o],%[m],%[o],ASR #31\n\t" > "strh %[o],[%[out]],#2\n\t" > "strh %[o],[%[out]],#2\n\t" > > Modified: openmsx/trunk/src/sound/ResampleLQ.cc > =================================================================== > --- openmsx/trunk/src/sound/ResampleLQ.cc 2011-07-07 17:59:13 UTC (rev > 12201) +++ openmsx/trunk/src/sound/ResampleLQ.cc 2011-07-09 07:05:09 UTC > (rev 12202) @@ -174,22 +174,22 @@ > // 0th order interpolation > asm volatile ( > "0:\n\t" > - "mov %[t],%[p],LSR #16\n\t" > + "lsrs %[t],%[p],#16\n\t" > "ldr %[t],[%[buf],%[t],LSL #2]\n\t" > "str %[t],[%[out]],#4\n\t" > "add %[p],%[p],%[s]\n\t" > > - "mov %[t],%[p],LSR #16\n\t" > + "lsrs %[t],%[p],#16\n\t" > "ldr %[t],[%[buf],%[t],LSL #2]\n\t" > "str %[t],[%[out]],#4\n\t" > "add %[p],%[p],%[s]\n\t" > > - "mov %[t],%[p],LSR #16\n\t" > + "lsrs %[t],%[p],#16\n\t" > "ldr %[t],[%[buf],%[t],LSL #2]\n\t" > "str %[t],[%[out]],#4\n\t" > "add %[p],%[p],%[s]\n\t" > > - "mov %[t],%[p],LSR #16\n\t" > + "lsrs %[t],%[p],#16\n\t" > "ldr %[t],[%[buf],%[t],LSL #2]\n\t" > "str %[t],[%[out]],#4\n\t" > "add %[p],%[p],%[s]\n\t" > > Modified: openmsx/trunk/src/sound/SCC.cc > =================================================================== > --- openmsx/trunk/src/sound/SCC.cc 2011-07-07 17:59:13 UTC (rev 12201) > +++ openmsx/trunk/src/sound/SCC.cc 2011-07-09 07:05:09 UTC (rev 12202) > @@ -506,8 +506,8 @@ > "bne 0b\n\t" > "b 3f\n" > "2:\n\t" > + "adds %[PO],%[PO],#1\n\t" > "subs %[T],%[T],%[PE]\n\t" > - "add %[PO],%[PO],#1\n\t" > "bpl 2b\n\t" > "and %[PO],%[PO],#31\n\t" > "add %[C],%[T],%[PE]\n\t" > > Modified: openmsx/trunk/src/utils/DivModByConst.hh > =================================================================== > --- openmsx/trunk/src/utils/DivModByConst.hh 2011-07-07 17:59:13 UTC (rev > 12201) +++ openmsx/trunk/src/utils/DivModByConst.hh 2011-07-09 07:05:09 > UTC (rev 12202) @@ -268,7 +268,7 @@ > unsigned th,tl; > asm volatile ( > "umull %[TH],%[TL],%[AL],%[BL]\n\t" > - "mov %[TH],#0\n\t" > + "eors %[TH],%[TH]\n\t" > "umlal %[TL],%[TH],%[AH],%[BL]\n\t" > > "umull %[BL],%[AL],%[BH],%[AL]\n\t" > @@ -278,8 +278,10 @@ > "adc %[TL],%[TL],%[TL]\n\t" > "umlal %[TH],%[TL],%[AH],%[BH]\n\t" > > - "mov %[RES],%[TH],LSR %[S]\n\t" > - "orr %[RES],%[RES],%[TL],LSL %[S32]\n\t" > + "lsr %[RES],%[TH],%[S]\n\t" > + //"orr %[RES],%[RES],%[TL],LSL %[S32]\n\t" // not thumb2 > + "lsls %[TL],%[TL],%[S32]\n\t" > + "orrs %[RES],%[RES],%[TL]\n\t" > > : [RES] "=r" (res) > > , [TH] "=&r" (th) > , [TL] "=&r" (tl) > @@ -384,8 +386,10 @@ > "adc %[TL],%[TL],%[TL]\n\t" > "umlal %[TH],%[TL],%[AH],%[BH]\n\t" > > - "mov %[RES],%[TH],LSR %[S]\n\t" > - "orr %[RES],%[RES],%[TL],LSL %[S32]\n\t" > + "lsr %[RES],%[TH],%[S]\n\t" > + //"orr %[RES],%[RES],%[TL],LSL %[S32]\n\t" // not thumb2 > + "lsls %[TL],%[TL],%[S32]\n\t" > + "orrs %[RES],%[RES],%[TL]\n\t" > > : [RES] "=r" (res) > > , [TH] "=&r" (th) > , [TL] "=&r" (tl) > > Modified: openmsx/trunk/src/utils/DivModBySame.hh > =================================================================== > --- openmsx/trunk/src/utils/DivModBySame.hh 2011-07-07 17:59:13 UTC (rev > 12201) +++ openmsx/trunk/src/utils/DivModBySame.hh 2011-07-09 07:05:09 UTC > (rev 12202) @@ -164,7 +164,7 @@ > unsigned res; > unsigned dummy; > asm volatile ( > - "ldmia %[RES],{r3,r4,r5,r6,r7}\n\t" > + "ldmia %[RES],{r3,r4,r5,r6,r8}\n\t" > > "umull %[T],%[RES],%[AL],r3\n\t" // RES:T = AL * BL > "adds %[T],%[T],r5\n\t" // T += CL > @@ -179,17 +179,19 @@ > "adc r3,r5,r5\n\t" // r3 = carry > "umlal r6,r3,%[AH],r4\n\t" // r3:r6 = AH:AL * BH:BL + CH:CL > > - "rsb %[T],r7,#32\n\t" > - "mov %[RES],r6,LSR r7\n\t" > - "orr %[RES],%[RES],r3,LSL %[T]\n\t" > - //"mov %[AL],r3,LSR r7\n\t" // high word of result, should be 0 > + "rsb %[T],r8,#32\n\t" > + "lsr %[RES],r6,r8\n\t" > + //"orr %[RES],%[RES],r3,LSL %[T]\n\t" // not thumb2 > + "lsls r3,r3,%[T]\n\t" > + "orrs %[RES],%[RES],r3\n\t" > + //"mov %[AL],r3,LSR r8\n\t" // high word of result, should be 0 > > : [RES] "=r" (res) > > , [T] "=&r" (dummy) > > : "[RES]" (this) > > , [AL] "r" (unsigned(dividend)) > , [AH] "r" (dividend >> 32) > - : "r3","r4","r5","r6","r7" > + : "r3","r4","r5","r6","r8" > ); > return res; > #else > @@ -223,7 +225,7 @@ > unsigned res; > unsigned dummy; > asm volatile ( > - "ldmia %[RES],{r3,r4,r5,r6,r7,r8}\n\t" > + "ldmia %[RES],{r3,r4,r5,r6,r8,r9}\n\t" > > "umull %[T],%[RES],%[AL],r3\n\t" // RES:T = AL * BL > "adds %[T],%[T],r5\n\t" // T += CL > @@ -238,11 +240,13 @@ > "adc r3,r5,r5\n\t" // r3 = carry > "umlal r6,r3,%[AH],r4\n\t" // r3:r6 = AH:AL * BH:BL + CH:CL > > - "rsb %[T],r7,#32\n\t" > - "mov %[RES],r6,LSR r7\n\t" > - "orr %[RES],%[RES],r3,LSL %[T]\n\t" // RES = quotient (must fit in > 32-bit) + "rsb %[T],r8,#32\n\t" > + "lsr %[RES],r6,r8\n\t" > + //"orr %[RES],%[RES],r3,LSL %[T]\n\t" // not thumb2 > + "lsls r3,r3,%[T]\n\t" > + "orrs %[RES],%[RES],r3\n\t" // RES = quotient (must fit in > 32-bit) > > - "mul %[AH],%[RES],r8\n\t" // AH = q * divisor > + "mul %[AH],%[RES],r9\n\t" // AH = q * divisor > "sub %[RES],%[AL],%[AH]\n\t" // RES = D - q*d > > : [RES] "=r" (res) > > @@ -250,7 +254,7 @@ > > : "[RES]" (this) > > , [AL] "r" (unsigned(dividend)) > , [AH] "r" (dividend >> 32) > - : "r3","r4","r5","r6","r7","r8" > + : "r3","r4","r5","r6","r8","r9" > ); > return res; > #else > > Modified: openmsx/trunk/src/utils/MemoryOps.cc > =================================================================== > --- openmsx/trunk/src/utils/MemoryOps.cc 2011-07-07 17:59:13 UTC (rev > 12201) +++ openmsx/trunk/src/utils/MemoryOps.cc 2011-07-09 07:05:09 UTC > (rev 12202) @@ -322,35 +322,38 @@ > memset_32_2<STREAMING>(dest, num, val, val); > #endif > #elif defined __arm__ > + register int val_r3 asm("r3") = val; > asm volatile ( > - "mov r3, %[val]\n\t" > - "mov r4, %[val]\n\t" > - "mov r5, %[val]\n\t" > - "mov r6, %[val]\n\t" > + "mov r4, r3\n\t" > + "mov r5, r3\n\t" > + "mov r6, r3\n\t" > "subs %[num],%[num],#8\n\t" > "bmi 1f\n" > - "mov r7, %[val]\n\t" > - "mov r8, %[val]\n\t" > - "mov r9, %[val]\n\t" > - "mov r10,%[val]\n\t" > + "mov r8, r3\n\t" > + "mov r9, r3\n\t" > + "mov r10,r3\n\t" > + "mov r12,r3\n\t" > "0:\n\t" > - "stmia %[dest]!,{r3-r10}\n\t" > + "stmia %[dest]!,{r3,r4,r5,r6,r8,r9,r10,r12}\n\t" > "subs %[num],%[num],#8\n\t" > "bpl 0b\n\t" > "1:\n\t" > "tst %[num],#4\n\t" > - "stmneia %[dest]!,{r3-r6}\n\t" > + "it ne\n\t" > + "stmne %[dest]!,{r3,r4,r5,r6}\n\t" > "tst %[num],#2\n\t" > - "stmneia %[dest]!,{r3-r4}\n\t" > + "it ne\n\t" > + "stmne %[dest]!,{r3,r4}\n\t" > "tst %[num],#1\n\t" > + "it ne\n\t" > "strne r3,[%[dest]]\n\t" > > : [dest] "=r" (dest) > > - , [num] "=r" (num) > + , [num] "=r" (num) > > : "[dest]" (dest) > > - , "[num]" (num) > - , [val] "r" (val) > - : "r3","r4","r5","r6","r7","r8","r9","r10" > + , "[num]" (num) > + , "r" (val_r3) > + : "r4","r5","r6","r8","r9","r10","r12" > ); > return; > #else > > Modified: openmsx/trunk/src/video/BitmapConverter.cc > =================================================================== > --- openmsx/trunk/src/video/BitmapConverter.cc 2011-07-07 17:59:13 UTC (rev > 12201) +++ openmsx/trunk/src/video/BitmapConverter.cc 2011-07-09 07:05:09 > UTC (rev 12202) @@ -124,24 +124,24 @@ > asm volatile ( > "0:\n\t" > "ldmia %[vram]!, {r3,r4}\n\t" > - "and r5, r3, #0x00FF0000\n\t" > - "and r6, r3, #0xFF000000\n\t" > - "and r7, r4, #0x000000FF\n\t" > - "and r8, r4, #0x0000FF00\n\t" > - "and r9, r4, #0x00FF0000\n\t" > - "and r10, r4, #0xFF000000\n\t" > - "and r4, r3, #0x0000FF00\n\t" > - "and r3, r3, #0x000000FF\n\t" > - "ldr r3, [%[pal], r3, lsl #2]\n\t" > - "ldr r4, [%[pal], r4, lsr #6]\n\t" > - "ldr r5, [%[pal], r5, lsr #14]\n\t" > - "ldr r6, [%[pal], r6, lsr #22]\n\t" > - "ldr r7, [%[pal], r7, lsl #2]\n\t" > - "ldr r8, [%[pal], r8, lsr #6]\n\t" > - "ldr r9, [%[pal], r9, lsr #14]\n\t" > - "ldr r10, [%[pal], r10,lsr #22]\n\t" > + "and r5, %[m255], r3, lsr #16\n\t" > + "and r6, %[m255], r3, lsr #24\n\t" > + "and r8, %[m255], r4\n\t" > + "and r9, %[m255], r4, lsr #8\n\t" > + "and r10, %[m255], r4, lsr #16\n\t" > + "and r12, %[m255], r4, lsr #24\n\t" > + "and r4, %[m255], r3, lsr #8\n\t" > + "and r3, %[m255], r3\n\t" > + "ldr r3, [%[pal], r3, lsl #2]\n\t" > + "ldr r4, [%[pal], r4, lsl #2]\n\t" > + "ldr r5, [%[pal], r5, lsl #2]\n\t" > + "ldr r6, [%[pal], r6, lsl #2]\n\t" > + "ldr r8, [%[pal], r8, lsl #2]\n\t" > + "ldr r9, [%[pal], r9, lsl #2]\n\t" > + "ldr r10, [%[pal], r10,lsl #2]\n\t" > + "ldr r12, [%[pal], r12,lsl #2]\n\t" > "subs %[count], %[count], #1\n\t" > - "stmia %[out]!, {r3-r10}\n\t" > + "stmia %[out]!, {r3,r4,r5,r6,r8,r9,r10,r12}\n\t" > "bne 0b\n\t" > > : [vram] "=r" (vramPtr0) > > @@ -150,7 +150,8 @@ > , "[out]" (pixelPtr) > , [pal] "r" (dPalette) > , [count] "r" (16) > - : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" > + , [m255] "r" (255) > + : "r3", "r4", "r5", "r6", "r8", "r9", "r10", "r12" > ); > return; > } > > Modified: openmsx/trunk/src/video/CharacterConverter.cc > =================================================================== > --- openmsx/trunk/src/video/CharacterConverter.cc 2011-07-07 17:59:13 UTC > (rev 12201) +++ openmsx/trunk/src/video/CharacterConverter.cc 2011-07-09 > 07:05:09 UTC (rev 12202) @@ -291,27 +291,35 @@ > if (sizeof(Pixel) == 2) { > asm volatile ( > "tst %[PAT],#128\n\t" > + "ite eq\n\t" > "moveq r0,%[BG]\n\t" > "movne r0,%[FG]\n\t" > "tst %[PAT],#64\n\t" > + "ite eq\n\t" > "orreq r0,r0,%[BG], lsl #16\n\t" > "orrne r0,r0,%[FG], lsl #16\n\t" > "tst %[PAT],#32\n\t" > + "ite eq\n\t" > "moveq r1,%[BG]\n\t" > "movne r1,%[FG]\n\t" > "tst %[PAT],#16\n\t" > + "ite eq\n\t" > "orreq r1,r1,%[BG], lsl #16\n\t" > "orrne r1,r1,%[FG], lsl #16\n\t" > "tst %[PAT],#8\n\t" > + "ite eq\n\t" > "moveq r2,%[BG]\n\t" > "movne r2,%[FG]\n\t" > "tst %[PAT],#4\n\t" > + "ite eq\n\t" > "orreq r2,r2,%[BG], lsl #16\n\t" > "orrne r2,r2,%[FG], lsl #16\n\t" > "tst %[PAT],#2\n\t" > + "ite eq\n\t" > "moveq r3,%[BG]\n\t" > "movne r3,%[FG]\n\t" > "tst %[PAT],#1\n\t" > + "ite eq\n\t" > "orreq r3,r3,%[BG], lsl #16\n\t" > "orrne r3,r3,%[FG], lsl #16\n\t" > "stmia %[OUT]!,{r0-r3}\n\t" > > Modified: openmsx/trunk/src/video/scalers/LineScalers.hh > =================================================================== > --- openmsx/trunk/src/video/scalers/LineScalers.hh 2011-07-07 17:59:13 UTC > (rev 12201) +++ openmsx/trunk/src/video/scalers/LineScalers.hh 2011-07-09 > 07:05:09 UTC (rev 12202) @@ -755,10 +755,10 @@ > > asm volatile ( > "0:\n\t" > - "ldmia %1!,{r0,r1,r2,r3,r4,r5,r6,r7};\n\t" > - "stmia %2!,{r0,r1,r2,r3,r4,r5,r6,r7};\n\t" > - "ldmia %1!,{r0,r1,r2,r3,r4,r5,r6,r7};\n\t" > - "stmia %2!,{r0,r1,r2,r3,r4,r5,r6,r7};\n\t" > + "ldmia %1!,{r0,r1,r2,r3,r4,r5,r6,r8};\n\t" > + "stmia %2!,{r0,r1,r2,r3,r4,r5,r6,r8};\n\t" > + "ldmia %1!,{r0,r1,r2,r3,r4,r5,r6,r8};\n\t" > + "stmia %2!,{r0,r1,r2,r3,r4,r5,r6,r8};\n\t" > "subs %0,%0,#64;\n\t" > "bne 0b;\n\t" > > @@ -766,7 +766,7 @@ > > : "r" (nBytes) > > , "r" (in) > , "r" (out) > - : "r0","r1","r2","r3","r4","r5","r6","r7" > + : "r0","r1","r2","r3","r4","r5","r6","r8" > ); > return; > #endif > > > This was sent by the SourceForge.net collaborative development platform, > the world's largest Open Source development site. > > --------------------------------------------------------------------------- > --- All of the data generated in your IT infrastructure is seriously > valuable. Why? It contains a definitive record of application performance, > security threats, fraudulent activity, and more. Splunk takes this data > and makes sense of it. IT sense. And common sense. > http://p.sf.net/sfu/splunk-d2d-c2 > _______________________________________________ > openMSX-commits mailing list > ope...@li... > https://lists.sourceforge.net/lists/listinfo/openmsx-commits -- Joost Yervante Damad - http://damad.be/joost/ |