changelog shortlog tags branches files raw gz bz2 help

Mercurial > hg > plan9front / changeset: games/md: use cpu.c from blit

changeset 6898: adf1d1950ce6
parent 6897: 53034d183846
child 6899: 0cedaa205af6
author: aiju
date: Tue, 20 Nov 2018 09:20:46 +0000
files: sys/src/games/md/cpu.c sys/src/games/md/mkfile
description: games/md: use cpu.c from blit
     1.1deleted file mode 100644
     1.2--- a/sys/src/games/md/cpu.c
     1.3+++ /dev/null
     1.4@@ -1,1185 +0,0 @@
     1.5-#include <u.h>
     1.6-#include <libc.h>
     1.7-#include <thread.h>
     1.8-#include "../eui.h"
     1.9-#include "dat.h"
    1.10-#include "fns.h"
    1.11-
    1.12-enum {
    1.13-	FLAGS = 1<<13,
    1.14-	FLAGX = 16,
    1.15-	FLAGN = 8,
    1.16-	FLAGZ = 4,
    1.17-	FLAGV = 2,
    1.18-	FLAGC = 1,
    1.19-};
    1.20-
    1.21-u32int r[16], pc, curpc;
    1.22-u32int asp, irq, stop;
    1.23-extern u32int irql[8];
    1.24-u32int irqla[8];
    1.25-u16int rS;
    1.26-static u32int op;
    1.27-int tim;
    1.28-#define ra (r+8)
    1.29-
    1.30-static void
    1.31-undef(void)
    1.32-{
    1.33-	sysfatal("undefined opcode %#o at pc=%#.6x", op, curpc);
    1.34-}
    1.35-
    1.36-static u16int
    1.37-fetch16(void)
    1.38-{
    1.39-	u16int v;
    1.40-	
    1.41-	v = memread(pc);
    1.42-	pc += 2;
    1.43-	return v;
    1.44-}
    1.45-
    1.46-static u32int
    1.47-fetch32(void)
    1.48-{
    1.49-	u32int v;
    1.50-	
    1.51-	v = fetch16() << 16;
    1.52-	return v | fetch16();
    1.53-}
    1.54-
    1.55-static void
    1.56-push16(u16int u)
    1.57-{
    1.58-	ra[7] -= 2;
    1.59-	memwrite(ra[7], u, -1);
    1.60-}
    1.61-
    1.62-static u16int
    1.63-pop16(void)
    1.64-{
    1.65-	u16int v;
    1.66-	
    1.67-	v = memread(ra[7]);
    1.68-	ra[7] += 2;
    1.69-	return v;
    1.70-}
    1.71-
    1.72-static void
    1.73-push32(u32int u)
    1.74-{
    1.75-	ra[7] -= 4;
    1.76-	memwrite(ra[7], u >> 16, -1);
    1.77-	memwrite(ra[7] + 2, u, -1);
    1.78-}
    1.79-
    1.80-static u32int
    1.81-pop32(void)
    1.82-{
    1.83-	u32int v;
    1.84-	v = memread(ra[7]) << 16;
    1.85-	v |= memread(ra[7] + 2);
    1.86-	ra[7] += 4;
    1.87-	return v;
    1.88-}
    1.89-
    1.90-static vlong
    1.91-amode(int m, int n, int s)
    1.92-{
    1.93-	u16int w;
    1.94-	u32int v;
    1.95-	
    1.96-	m &= 7;
    1.97-	n &= 7;
    1.98-	s &= 3;
    1.99-	if(n == 7 && s == 0)
   1.100-		s++;
   1.101-	switch(m){
   1.102-	case 0:
   1.103-		return ~n;
   1.104-	case 1:
   1.105-		return ~(n+8);
   1.106-	case 2:
   1.107-		tim += s == 2 ? 8 : 4;
   1.108-		return ra[n];
   1.109-	case 3:
   1.110-		v = ra[n];
   1.111-		ra[n] += 1<<s;
   1.112-		tim += s == 2 ? 8 : 4;
   1.113-		return v;
   1.114-	case 4:
   1.115-		tim += s == 2 ? 10 : 6;
   1.116-		return ra[n] -= 1<<s;
   1.117-	case 5:
   1.118-		tim += s == 2 ? 12 : 8;
   1.119-		return (u32int)(ra[n] + (s16int)fetch16());
   1.120-	case 6:
   1.121-		tim += s == 2 ? 14 : 10;
   1.122-		w = fetch16();
   1.123-		v = r[w >> 12];
   1.124-		if((w & 1<<11) == 0)
   1.125-			v = (s16int)v;
   1.126-		return (u32int)(ra[n] + v + (s8int)w);
   1.127-	case 7:
   1.128-		switch(n){
   1.129-		case 0:
   1.130-			tim += s == 2 ? 12 : 8;
   1.131-			return (u32int)(s16int)fetch16();
   1.132-		case 1:
   1.133-			tim += s == 2 ? 16 : 12;
   1.134-			return fetch32();
   1.135-		case 2:
   1.136-			tim += s == 2 ? 12 : 8;
   1.137-			v = fetch16();
   1.138-			return (u32int)(pc + (s16int)v - 2);
   1.139-		case 3:
   1.140-			tim += s == 2 ? 14 : 4;
   1.141-			w = fetch16();
   1.142-			v = r[w >> 12];
   1.143-			if((w & 1<<11) == 0)
   1.144-				v = (s16int)v;
   1.145-			return (u32int)(pc + v + (s8int)w - 2);
   1.146-		case 4:
   1.147-			tim += s == 2 ? 8 : 4;
   1.148-			v = pc;
   1.149-			pc += 1<<s;
   1.150-			if(s == 0)
   1.151-				v = pc++;
   1.152-			return v;
   1.153-		default:
   1.154-			undef();
   1.155-		}
   1.156-	default:
   1.157-		undef();
   1.158-	}
   1.159-	return 0;
   1.160-}
   1.161-
   1.162-static u32int
   1.163-rmode(vlong a, int s)
   1.164-{
   1.165-	u32int v;
   1.166-
   1.167-	if(a >= 0){
   1.168-		switch(s & 3){
   1.169-		case 0:
   1.170-			v = memread(a);
   1.171-			if((a & 1) == 0)
   1.172-				v >>= 8;
   1.173-			return (s8int) v;
   1.174-		default:
   1.175-			return (s16int) memread(a);
   1.176-		case 2:
   1.177-			v = memread(a) << 16;
   1.178-			return v | memread(a + 2);
   1.179-		}
   1.180-	}
   1.181-	v = r[~a];
   1.182-	switch(s & 3){
   1.183-	case 0: return (s8int) v;
   1.184-	case 1: return (s16int) v;
   1.185-	default: return v;
   1.186-	}
   1.187-}
   1.188-
   1.189-static void
   1.190-wmode(vlong a, int s, u32int v)
   1.191-{
   1.192-	int n;
   1.193-
   1.194-	if(a >= 0){
   1.195-		switch(s & 3){
   1.196-		case 0:
   1.197-			memwrite(a, (u8int)v | (u8int)v << 8, (a & 1) != 0 ? 0xff : 0xff00);
   1.198-			return;
   1.199-		default:
   1.200-			memwrite(a, v, -1);
   1.201-			return;
   1.202-		case 2:
   1.203-			memwrite(a, v >> 16, -1);
   1.204-			memwrite(a + 2, v, -1);
   1.205-			return;
   1.206-		}
   1.207-	}
   1.208-	n = ~a;
   1.209-	if(n < 8){
   1.210-		switch(s){
   1.211-		case 0: r[n] = r[n] & 0xffffff00 | v & 0xff; break;
   1.212-		case 1: r[n] = r[n] & 0xffff0000 | v & 0xffff; break;
   1.213-		default: r[n] = v;
   1.214-		}
   1.215-	}else{
   1.216-		if(s == 1)
   1.217-			v = (s16int) v;
   1.218-		r[n] = v;
   1.219-	}
   1.220-}
   1.221-
   1.222-static void
   1.223-nz(u32int v, int s)
   1.224-{
   1.225-	switch(s){
   1.226-	case 0: v = (s8int) v; break;
   1.227-	case 1: v = (s16int) v; break;
   1.228-	}
   1.229-	rS &= ~(FLAGC|FLAGN|FLAGV|FLAGZ);
   1.230-	if(v == 0)
   1.231-		rS |= FLAGZ;
   1.232-	if((s32int)v < 0)
   1.233-		rS |= FLAGN;
   1.234-}
   1.235-
   1.236-static u32int
   1.237-add(u32int u, u32int w, int c, int s)
   1.238-{
   1.239-	u64int v;
   1.240-
   1.241-	rS &= ~(FLAGN|FLAGV|FLAGC);
   1.242-	switch(s){
   1.243-	case 0:
   1.244-		v = (u8int)w + (u8int)u + c;
   1.245-		if(v >= 0x100)
   1.246-			rS |= FLAGC;
   1.247-		if((v & 0x80) != 0)
   1.248-			rS |= FLAGN;
   1.249-		if((~(w ^ u) & (v ^ u) & 0x80) != 0)
   1.250-			rS |= FLAGV;
   1.251-		if((u8int)v != 0)
   1.252-			rS &= ~FLAGZ;
   1.253-		break;
   1.254-	case 1:
   1.255-		v = (u16int)w + (u16int)u + c;
   1.256-		if(v >= 0x10000)
   1.257-			rS |= FLAGC;
   1.258-		if((v & 0x8000) != 0)
   1.259-			rS |= FLAGN;
   1.260-		if((~(w ^ u) & (v ^ u) & 0x8000) != 0)
   1.261-			rS |= FLAGV;
   1.262-		if((u16int)v != 0)
   1.263-			rS &= ~FLAGZ;
   1.264-		break;
   1.265-	default:
   1.266-		v = (u64int)w + u + c;
   1.267-		if((v >> 32) != 0)
   1.268-			rS |= FLAGC;
   1.269-		if((v & 0x80000000) != 0)
   1.270-			rS |= FLAGN;
   1.271-		if((~(w ^ u) & (v ^ u) & 0x80000000) != 0)
   1.272-			rS |= FLAGV;
   1.273-		if((u32int)v != 0)
   1.274-			rS &= ~FLAGZ;
   1.275-		break;
   1.276-	}
   1.277-	return v;
   1.278-} 
   1.279-
   1.280-static u32int
   1.281-sub(u32int u, u32int w, int c, int s)
   1.282-{
   1.283-	u64int v;
   1.284-
   1.285-	rS &= ~(FLAGN|FLAGV|FLAGC);
   1.286-	switch(s){
   1.287-	case 0:
   1.288-		v = (u8int)u - (u8int)w - c;
   1.289-		if(v >= 0x100)
   1.290-			rS |= FLAGC;
   1.291-		if((v & 0x80) != 0)
   1.292-			rS |= FLAGN;
   1.293-		if(((w ^ u) & (v ^ u) & 0x80) != 0)
   1.294-			rS |= FLAGV;
   1.295-		if((u8int)v != 0)
   1.296-			rS &= ~FLAGZ;
   1.297-		break;
   1.298-	case 1:
   1.299-		v = (u16int)u - (u16int)w - c;
   1.300-		if(v >= 0x10000)
   1.301-			rS |= FLAGC;
   1.302-		if((v & 0x8000) != 0)
   1.303-			rS |= FLAGN;
   1.304-		if(((w ^ u) & (v ^ u) & 0x8000) != 0)
   1.305-			rS |= FLAGV;
   1.306-		if((u16int)v != 0)
   1.307-			rS &= ~FLAGZ;
   1.308-		break;
   1.309-	default:
   1.310-		v = (u64int)u - w - c;
   1.311-		if((v >> 32) != 0)
   1.312-			rS |= FLAGC;
   1.313-		if((v & 0x80000000) != 0)
   1.314-			rS |= FLAGN;
   1.315-		if(((w ^ u) & (v ^ u) & (1<<31)) != 0)
   1.316-			rS |= FLAGV;
   1.317-		if((u32int)v != 0)
   1.318-			rS &= ~FLAGZ;
   1.319-		break;
   1.320-	}
   1.321-	return v;
   1.322-}
   1.323-
   1.324-static int
   1.325-cond(int n)
   1.326-{
   1.327-	switch(n){
   1.328-	case 0: return 1; break;
   1.329-	default: return 0; break;
   1.330-	case 2: return (rS & (FLAGC|FLAGZ)) == 0; break;
   1.331-	case 3: return (rS & (FLAGC|FLAGZ)) != 0; break;
   1.332-	case 4: return (rS & FLAGC) == 0; break;
   1.333-	case 5: return (rS & FLAGC) != 0; break;
   1.334-	case 6: return (rS & FLAGZ) == 0; break;
   1.335-	case 7: return (rS & FLAGZ) != 0; break;
   1.336-	case 8: return (rS & FLAGV) == 0; break;
   1.337-	case 9: return (rS & FLAGV) != 0; break;
   1.338-	case 10: return (rS & FLAGN) == 0; break;
   1.339-	case 11: return (rS & FLAGN) != 0; break;
   1.340-	case 12: return ((rS ^ (rS << 2)) & FLAGN) == 0; break;
   1.341-	case 13: return ((rS ^ (rS << 2)) & FLAGN) != 0; break;
   1.342-	case 14: return ((rS ^ (rS << 2)) & FLAGN) == 0 && (rS & FLAGZ) == 0; break;
   1.343-	case 15: return ((rS ^ (rS << 2)) & FLAGN) != 0 || (rS & FLAGZ) != 0; break;
   1.344-	}
   1.345-}
   1.346-
   1.347-static u32int
   1.348-rot(u32int v, int m, int n, int s)
   1.349-{
   1.350-	int l, ll, x, vf;
   1.351-	u32int msb;
   1.352-	
   1.353-	msb = 1 << ((8 << s) - 1);
   1.354-	v &= (msb << 1) - 1;
   1.355-	if(m == 0)
   1.356-		x = (v & msb) != 0;
   1.357-	else
   1.358-		x = 0;
   1.359-	if((m & 6) == 4)
   1.360-		ll = l = (rS & FLAGX) != 0;
   1.361-	else
   1.362-		ll = l = 0;
   1.363-	vf = 0;
   1.364-	while(n--){
   1.365-		if((m & 1) == 0){
   1.366-			l = v & 1;
   1.367-			v >>= 1;
   1.368-		}else{
   1.369-			l = (v & msb) != 0;
   1.370-			v <<= 1;
   1.371-		}
   1.372-		rS = rS & ~FLAGX | l << 4;
   1.373-		if(m >= 6)
   1.374-			x = l;
   1.375-		else if(m >= 4){
   1.376-			x = ll;
   1.377-			ll = l;
   1.378-		}
   1.379-		if((m & 1) == 0){
   1.380-			if(x != 0)
   1.381-				v |= msb;
   1.382-		}else
   1.383-			v |= x;
   1.384-		vf |= x ^ (v & msb) != 0;
   1.385-		tim += 2;
   1.386-	}
   1.387-	nz(v, s);
   1.388-	rS |= l;
   1.389-	if(m <= 1 && vf)
   1.390-		rS |= FLAGV;
   1.391-	tim += s == 2 ? 8 : 6;
   1.392-	return v;
   1.393-}
   1.394-
   1.395-static u8int
   1.396-addbcd(u8int a, u8int b)
   1.397-{
   1.398-	int r;
   1.399-	
   1.400-	r = (a & 0xf) + (b & 0xf) + ((rS & FLAGX) != 0);
   1.401-	if(r > 0x09) r += 0x06;
   1.402-	if(r > 0x1f) r -= 0x10;
   1.403-	r += (a & 0xf0) + (b & 0xf0);
   1.404-	if(r > 0x9f) r += 0x60;
   1.405-	if((u8int)r != 0)
   1.406-		rS &= ~FLAGZ;
   1.407-	if(r > 0xff)
   1.408-		rS |= FLAGC|FLAGX;
   1.409-	else
   1.410-		rS &= ~(FLAGC|FLAGX);
   1.411-	return r;
   1.412-}
   1.413-
   1.414-static u8int
   1.415-subbcd(u8int a, u8int b)
   1.416-{
   1.417-	int x;
   1.418-	
   1.419-	x = (a & 0xf) + (~b & 0xf) + ((rS & FLAGX) == 0);
   1.420-	if(x < 0x10) x -= 0x06;
   1.421-	if(x < 0) x += 0x10;
   1.422-	x += (a & 0xf0) + (~b & 0xf0);
   1.423-	if(x > 0xff)
   1.424-		rS &= ~(FLAGC|FLAGX);
   1.425-	else{
   1.426-		rS |= FLAGC|FLAGX;
   1.427-		x -= 0x60;
   1.428-	}
   1.429-	if((u8int)x != 0)
   1.430-		rS &= ~FLAGZ;
   1.431-	return x;
   1.432-}
   1.433-
   1.434-static void
   1.435-dtime(u16int op, u8int s)
   1.436-{
   1.437-	if((op & 0x100) != 0){
   1.438-		if(s == 2)
   1.439-			if((op & 0x30) == 0 || (op & 0x3f) == 0x3c)
   1.440-				tim += 8;
   1.441-			else
   1.442-				tim += 6;
   1.443-		else
   1.444-			tim += 4;
   1.445-	}else
   1.446-		tim += s == 2 ? 12 : 8;
   1.447-}
   1.448-
   1.449-static void
   1.450-stime(int a, u8int s)
   1.451-{
   1.452-	if(a)
   1.453-		tim += s == 2 ? 6 : 4;
   1.454-	else
   1.455-		tim += s == 2 ? 12 : 8;
   1.456-}
   1.457-
   1.458-static void
   1.459-trap(int n, u32int pcv)
   1.460-{
   1.461-	int l, v;
   1.462-	u32int sr, t;
   1.463-	
   1.464-	sr = rS;
   1.465-	if(n < 0){
   1.466-		for(l = 7; l > ((rS >> 8) & 7); l--)
   1.467-			if((irql[l] & irq) != 0)
   1.468-				break;
   1.469-		v = intack(l);
   1.470-		rS = rS & ~0x700 | l << 8;
   1.471-		tim += 44;
   1.472-	}else{
   1.473-		switch(n){
   1.474-		case 2: case 3: tim += 50; break;
   1.475-		case 5: tim += 38; break;
   1.476-		case 6: tim += 40; break;
   1.477-		default: tim += 34; break;
   1.478-		}
   1.479-		v = n;
   1.480-	}
   1.481-	if((rS & FLAGS) == 0){
   1.482-		t = asp;
   1.483-		asp = ra[7];
   1.484-		ra[7] = t;
   1.485-	}
   1.486-	rS |= FLAGS;
   1.487-	push32(pcv);
   1.488-	push16(sr);
   1.489-	pc = memread(v * 4) << 16;
   1.490-	pc |= memread(v * 4 + 2);
   1.491-	stop = 0;
   1.492-}
   1.493-
   1.494-void
   1.495-cpureset(void)
   1.496-{
   1.497-	u32int v;
   1.498-	int i;
   1.499-
   1.500-	ra[7] = memread(0) << 16 | memread(2);
   1.501-	pc = memread(4) << 16 | memread(6);
   1.502-	rS = 0x2700;
   1.503-	for(i = 7, v = 0; i >= 0; i--){
   1.504-		irqla[i] = v;
   1.505-		v |= irql[i];
   1.506-	}
   1.507-}
   1.508-
   1.509-int
   1.510-step(void)
   1.511-{
   1.512-	u32int v, w;
   1.513-	vlong a;
   1.514-	int s;
   1.515-	int n, m, d;
   1.516-	static int cnt;
   1.517-
   1.518-	if(0 && pc == 0x4118c){
   1.519-		trace++;
   1.520-		print("%x\n", curpc);
   1.521-	}
   1.522-	tim = 0;
   1.523-	curpc = pc;
   1.524-	if(irq && (irqla[(rS >> 8) & 7] & irq) != 0){
   1.525-		trap(-1, curpc);
   1.526-		return tim;
   1.527-	}
   1.528-	if(stop)
   1.529-		return 1;
   1.530-	op = fetch16();
   1.531-	if(trace)
   1.532-		print("%.6ux %.6uo %.4ux %.8ux | %.8ux %.8ux %.8ux %.8ux | %.8ux %.8ux %.8ux\n", curpc, op, rS, memread(ra[7])<<16|memread(ra[7]+2), r[0], r[1], r[2], r[3], ra[0], ra[6], ra[7]);
   1.533-	s = op >> 6 & 3;
   1.534-	n = op >> 9 & 7;
   1.535-	switch(op >> 12){
   1.536-	case 0:
   1.537-		if((op & 0x3f) == 0x3c){ /* (ORI|ANDI|EORI) to (CCR|SR) */
   1.538-			if(s == 1 && (rS & FLAGS) == 0){
   1.539-				trap(8, curpc);
   1.540-				break;
   1.541-			}
   1.542-			v = rS;
   1.543-			w = fetch16();
   1.544-			switch(n){
   1.545-			case 0: v |= w; break;
   1.546-			case 1: v &= w; break;
   1.547-			case 5: v ^= w; break;
   1.548-			default: undef();
   1.549-			}
   1.550-			if(s != 1)
   1.551-				v = v & 0xff | rS & 0xff00;
   1.552-			rS = v;
   1.553-			if(s == 1 && (rS & FLAGS) == 0){
   1.554-				v = ra[7];
   1.555-				ra[7] = asp;
   1.556-				asp = v;
   1.557-			}
   1.558-			tim += 20;
   1.559-			break;
   1.560-		}
   1.561-		if((op & 0x138) == 0x108){ /* MOVEP */
   1.562-			a = ra[op & 7] + (s16int)fetch16();
   1.563-			switch(s){
   1.564-			case 0:
   1.565-				v = (u8int)rmode(a, 0) << 8;
   1.566-				v |= (u8int)rmode(a + 2, 0);
   1.567-				r[n] = r[n] & 0xff00 | v;
   1.568-				tim += 16;
   1.569-				break;
   1.570-			case 1:
   1.571-				v = (u8int)rmode(a, 0) << 24;
   1.572-				v |= (u8int)rmode(a + 2, 0) << 16;
   1.573-				v |= (u8int)rmode(a + 4, 0) << 8;
   1.574-				v |= (u8int)rmode(a + 6, 0);
   1.575-				tim += 24;
   1.576-				r[n] = v;
   1.577-				break;
   1.578-			case 2:
   1.579-				wmode(a, 0, r[n] >> 8);
   1.580-				wmode(a + 2, 0, r[n]);
   1.581-				tim += 16;
   1.582-				break;
   1.583-			case 3:
   1.584-				wmode(a, 0, r[n] >> 24);
   1.585-				wmode(a + 2, 0, r[n] >> 16);
   1.586-				wmode(a + 4, 0, r[n] >> 8);
   1.587-				wmode(a + 6, 0, r[n]);
   1.588-				tim += 24;
   1.589-				break;
   1.590-			}
   1.591-			break;
   1.592-		}
   1.593-		if((op & 0x100) != 0 || n == 4){ /* BTST, BCHG, BCLR, BSET */
   1.594-			if((op & 0x100) != 0)
   1.595-				w = r[n];
   1.596-			else
   1.597-				w = fetch16();
   1.598-			if((op & 0x38) != 0){
   1.599-				n = 0;
   1.600-				w = 1<<(w & 7);
   1.601-			}else{
   1.602-				n = 2;
   1.603-				w = 1<<(w & 31);
   1.604-			}
   1.605-			a = amode(op >> 3, op, n);
   1.606-			v = rmode(a, n);
   1.607-			rS &= ~FLAGZ;
   1.608-			if((v & w) == 0)
   1.609-				rS |= FLAGZ;
   1.610-			switch(s){
   1.611-			case 1: v ^= w; break;
   1.612-			case 2: v &= ~w; if(n == 2) tim += 2; break;
   1.613-			case 3: v |= w; break;
   1.614-			}
   1.615-			if(s != 0){
   1.616-				wmode(a, n, v);
   1.617-				tim += (op & 0x100) != 0 ? 8 : 12;
   1.618-			}else{
   1.619-				tim += (op & 0x100) != 0 ? 4 : 8;
   1.620-				if(n == 2)
   1.621-					tim += 2;
   1.622-			}
   1.623-			break;
   1.624-		}
   1.625-		switch(s){
   1.626-		case 0: w = (s8int)fetch16(); break;
   1.627-		default: w = fetch16(); break;
   1.628-		case 2: w = fetch32(); break;
   1.629-		}
   1.630-		a = amode(op >> 3, op, s);
   1.631-		v = rmode(a, s);
   1.632-		switch(n){
   1.633-		case 0: nz(v |= w, s); break;
   1.634-		case 1: nz(v &= w, s); break;
   1.635-		case 2: rS |= FLAGZ; v = sub(v, w, 0, s); break;
   1.636-		case 3: rS |= FLAGZ; v = add(v, w, 0, s); break;
   1.637-		case 5: nz(v ^= w, s); break;
   1.638-		case 6: rS |= FLAGZ; sub(v, w, 0, s); break;
   1.639-		default: undef();
   1.640-		}
   1.641-		if(a < 0)
   1.642-			tim += s == 2 ? (n == 1 || n == 6 ? 14 : 16) : 8;
   1.643-		else
   1.644-			tim += s == 2 ? 20 : 12;
   1.645-		if(n != 6)
   1.646-			wmode(a, s, v);
   1.647-		break;
   1.648-	case 1: /* MOVE */
   1.649-		s = 0;
   1.650-		goto move;
   1.651-	case 2:
   1.652-		s = 2;
   1.653-		goto move;
   1.654-	case 3:
   1.655-		s = 1;
   1.656-	move:
   1.657-		v = rmode(amode(op >> 3, op, s), s);
   1.658-		wmode(amode(op >> 6, op >> 9, s), s, v);
   1.659-		if((op & 0x1c0) != 0x40)
   1.660-			nz(v, s);
   1.661-		tim += 4;
   1.662-		break;
   1.663-	case 4:
   1.664-		if((op & 0x1c0) == 0x1c0){ /* LEA */
   1.665-			ra[n] = amode(op >> 3, op, 2);
   1.666-			break;
   1.667-		}
   1.668-		if((op & 0x1c0) == 0x180){ /* CHK */
   1.669-			a = amode(op >> 3, op, s);
   1.670-			v = rmode(a, s);
   1.671-			if((s32int)r[n] < 0 || (s32int)r[n] > (s32int)v)
   1.672-				trap(6, curpc);
   1.673-			else
   1.674-				tim += 10;
   1.675-		}
   1.676-		if((op & 0xb80) == 0x880 && (op & 0x38) >= 0x10){ /* MOVEM */
   1.677-			s = (op >> 6 & 1) + 1;
   1.678-			w = fetch16();
   1.679-			if((op & 0x38) == 0x18){
   1.680-				n = op & 7;
   1.681-				a = ra[n];
   1.682-				for(m = 0; m < 16; m++){
   1.683-					if((w & 1) != 0){
   1.684-						r[m] = rmode(a, s);
   1.685-						a += 1<<s;
   1.686-						tim += 2<<s;
   1.687-					}
   1.688-					w >>= 1;
   1.689-				}
   1.690-				ra[n] = a;
   1.691-				tim += 12;
   1.692-				break;
   1.693-			}
   1.694-			if((op & 0x38) == 0x20){
   1.695-				n = op & 7;
   1.696-				a = ra[n];
   1.697-				for(m = 0; m < 16; m++){
   1.698-					if((w & 1) != 0){
   1.699-						a -= 1<<s;
   1.700-						wmode(a, s, r[15 - m]);
   1.701-						tim += 2<<s;
   1.702-					}
   1.703-					w >>= 1;
   1.704-				}
   1.705-				ra[n] = a;
   1.706-				tim += 8;
   1.707-				break;
   1.708-			}
   1.709-			a = amode(op >> 3, op, s);
   1.710-			for(m = 0; m < 16; m++){
   1.711-				if((w & 1) != 0){
   1.712-					if((op & 0x400) != 0)
   1.713-						r[m] = rmode(a, s);
   1.714-					else
   1.715-						wmode(a, s, r[m]);
   1.716-					a += 1<<s;
   1.717-					tim += 2<<s;
   1.718-				}
   1.719-				w >>= 1;
   1.720-			}
   1.721-			tim += (op & 0x400) != 0 ? 8 : 12;
   1.722-			break;
   1.723-		}
   1.724-		switch(op >> 8 & 0xf){
   1.725-		case 0:
   1.726-			if(s == 3){ /* MOVE from SR */
   1.727-				if((rS & FLAGS) != 0){
   1.728-					a = amode(op >> 3, op, 1);
   1.729-					wmode(a, 1, rS);
   1.730-					tim += a < 0 ? 6 : 8;
   1.731-				}else
   1.732-					trap(8, curpc);
   1.733-				break;
   1.734-			} /* NEGX */
   1.735-			a = amode(op >> 3, op, s);
   1.736-			m = (rS & FLAGX) != 0;
   1.737-			d = 1<<(8<<s)-1;
   1.738-			v = rmode(a, s);
   1.739-			w = -(v+m) & (d << 1) - 1;
   1.740-			rS &= ~(FLAGC|FLAGX|FLAGN|FLAGV);
   1.741-			if((w & d) != 0)
   1.742-				rS |= FLAGN;
   1.743-			if(m && w == d)
   1.744-				rS |= FLAGV;
   1.745-			if(w != 0){
   1.746-				rS |= FLAGC|FLAGX;
   1.747-				rS &= ~FLAGZ;
   1.748-			}
   1.749-			wmode(a, s, w);
   1.750-			stime(a < 0, s);
   1.751-			break;
   1.752-		case 2: /* CLR */
   1.753-			a = amode(op >> 3, op, s);
   1.754-			wmode(a, s, 0);
   1.755-			nz(0, 0);
   1.756-			stime(a < 0, s);
   1.757-			break;
   1.758-		case 4:
   1.759-			if(s == 3){ /* MOVE to CCR */
   1.760-				rS = rS & 0xff00 | rmode(amode(op >> 3, op, 1), 1);
   1.761-				tim += 12;
   1.762-				break;
   1.763-			} /* NEG */
   1.764-			a = amode(op >> 3, op, s);
   1.765-			v = -rmode(a, s);
   1.766-			nz(v, s);
   1.767-			rS = rS & ~FLAGX | ~rS << 2 & FLAGX | ~rS >> 2 & FLAGC;
   1.768-			wmode(a, s, v);
   1.769-			stime(a < 0, s);
   1.770-			break;
   1.771-		case 6:
   1.772-			if(s == 3){ /* MOVE to SR */
   1.773-				if((rS & FLAGS) != 0){
   1.774-					rS = rmode(amode(op >> 3, op, 1), 1);
   1.775-					if((rS & FLAGS) == 0){
   1.776-						v = asp;
   1.777-						asp = ra[7];
   1.778-						ra[7] = v;
   1.779-					}
   1.780-					tim += 12;
   1.781-				}else
   1.782-					trap(8, curpc);
   1.783-				break;
   1.784-			} /* NOT */
   1.785-			a = amode(op >> 3, op, s);
   1.786-			v = ~rmode(a, s);
   1.787-			nz(v, s);
   1.788-			wmode(a, s, v);
   1.789-			stime(a < 0, s);
   1.790-			break;
   1.791-		case 8:
   1.792-			n = op & 7;
   1.793-			switch(s){
   1.794-			case 0: /* NBCD */
   1.795-				a = amode(op >> 3, op, 0);
   1.796-				v = rmode(a, 0);
   1.797-				wmode(a, 0, subbcd(0, v));
   1.798-				if(a < 0)
   1.799-					tim += 8;
   1.800-				else
   1.801-					tim += 6;
   1.802-				break;
   1.803-			case 1:
   1.804-				if((op >> 3 & 7) != 0){
   1.805-					push32(amode(op >> 3, op, 0)); /* PEA */
   1.806-					tim += 8;
   1.807-				}else{
   1.808-					nz(r[n] = r[n] >> 16 | r[n] << 16, 2); /* SWAP */
   1.809-					tim += 4;
   1.810-				}
   1.811-				break;
   1.812-			case 2: /* EXT */
   1.813-				nz(r[n] = r[n] & 0xffff0000 | (u16int)(s8int)r[n], 1);
   1.814-				tim += 4;
   1.815-				break;
   1.816-			case 3: /* EXT */
   1.817-				nz(r[n] = (s16int)r[n], 2);
   1.818-				tim += 4;
   1.819-				break;
   1.820-			}
   1.821-			break;
   1.822-		case 10:
   1.823-			if(s == 3){ /* TAS */
   1.824-				a = amode(op >> 3, op, 0);
   1.825-				v = rmode(a, 0);
   1.826-				nz(v, 0);
   1.827-				wmode(a, s, v | 0x80);
   1.828-				tim += a < 0 ? 4 : 14;
   1.829-				break;
   1.830-			} /* TST */
   1.831-			a = amode(op >> 3, op, s);
   1.832-			nz(rmode(a, s), s);
   1.833-			tim += 4;
   1.834-			break;
   1.835-		case 14:
   1.836-			v = op >> 4 & 0xf;
   1.837-			n = op & 7;
   1.838-			if(v == 4){ /* TRAP */
   1.839-				trap(0x20 | op & 0xf, pc);
   1.840-				break;
   1.841-			}else if(v == 5){
   1.842-				if((op & 8) == 0){ /* LINK */
   1.843-					push32(ra[n]);
   1.844-					ra[n] = ra[7];
   1.845-					ra[7] += (s16int)fetch16();
   1.846-					tim += 16;
   1.847-				}else{ /* UNLK */
   1.848-					ra[7] = ra[n];
   1.849-					ra[n] = pop32();
   1.850-					tim += 12;
   1.851-				}
   1.852-				break;
   1.853-			}else if(v == 6){ /* MOVE USP */
   1.854-				if((rS & FLAGS) != 0){
   1.855-					if((op & 8) != 0)
   1.856-						ra[n] = asp;
   1.857-					else
   1.858-						asp = ra[n];
   1.859-					tim += 4;
   1.860-				}else
   1.861-					trap(8, curpc);
   1.862-				break;
   1.863-			}
   1.864-			if((op & 0xc0) == 0xc0){ /* JMP */
   1.865-				pc = amode(op >> 3, op, 2);
   1.866-				tim += 4;
   1.867-				break;
   1.868-			}
   1.869-			if((op & 0xc0) == 0x80){ /* JSR */
   1.870-				a = amode(op >> 3, op, 2);
   1.871-				push32(pc);
   1.872-				pc = a;
   1.873-				tim += 12;
   1.874-				break;
   1.875-			}
   1.876-			switch(op){
   1.877-			case 0x4e70: tim += 132; break; /* RESET */
   1.878-			case 0x4e71: tim += 4; break; /* NOP */
   1.879-			case 0x4e72: /* STOP */
   1.880-				if((rS & FLAGS) != 0){
   1.881-					rS = fetch16();
   1.882-					stop = 1;
   1.883-				}else
   1.884-					trap(8, curpc);
   1.885-				tim += 4;
   1.886-				break;
   1.887-			case 0x4e73: /* RTE */
   1.888-				if((rS & FLAGS) != 0){
   1.889-					v = rS;
   1.890-					rS = pop16();
   1.891-					pc = pop32();
   1.892-					if(((v ^ rS) & FLAGS) != 0){
   1.893-						v = asp;
   1.894-						asp = ra[7];
   1.895-						ra[7] = v;
   1.896-					}
   1.897-					tim += 20;
   1.898-				}else
   1.899-					trap(8, curpc);
   1.900-				break;
   1.901-			case 0x4e75: pc = pop32(); tim += 16; break; /* RTS */
   1.902-			case 0x4e76: if((rS & FLAGV) != 0) trap(7, curpc); tim += 4; break; /* TRAPV */
   1.903-			case 0x4e77: /* RTR */
   1.904-				rS = rS & 0xff00 | pop16() & 0xff;
   1.905-				pc = pop32();
   1.906-				tim += 20;
   1.907-				break;
   1.908-			default: undef();
   1.909-			}
   1.910-			break;
   1.911-		default:
   1.912-			undef();
   1.913-		}
   1.914-		break;
   1.915-	case 5:
   1.916-		if((op & 0xf8) == 0xc8){ /* DBcc */
   1.917-			n = op & 7;
   1.918-			v = (s16int)fetch16();
   1.919-			if(!cond((op >> 8) & 0xf)){
   1.920-				if((u16int)r[n] != 0){
   1.921-					r[n]--;
   1.922-					pc = pc + v - 2;
   1.923-					tim += 10;
   1.924-				}else{
   1.925-					r[n] |= 0xffff;
   1.926-					tim += 14;
   1.927-				}
   1.928-			}else
   1.929-				tim += 12;
   1.930-			break;
   1.931-		}
   1.932-		if(s == 3){ /* Scc */
   1.933-			a = amode(op >> 3, op, 0);
   1.934-			v = cond(op >> 8 & 0xf);
   1.935-			wmode(a, 0, -v);
   1.936-			if(a < 0)
   1.937-				tim += 4 + 2 * v;
   1.938-			else
   1.939-				tim += 8;
   1.940-			break;
   1.941-		} /* ADDQ, SUBQ */
   1.942-		rS |= FLAGZ;
   1.943-		if((op & 0x38) == 0x08)
   1.944-			s = 2;
   1.945-		a = amode(op >> 3, op, s);
   1.946-		v = rmode(a, s);
   1.947-		if(n == 0)
   1.948-			n = 8;
   1.949-		if((op & 0x100) == 0)
   1.950-			v = add(v, n, 0, s);
   1.951-		else
   1.952-			v = sub(v, n, 0, s);
   1.953-		rS = rS & ~FLAGX | rS << 4 & FLAGX;
   1.954-		if(a < 0)
   1.955-			tim += s == 2 || (op & 0x130) == 0x110 ? 8 : 4;
   1.956-		else
   1.957-			tim += s == 2 ? 12 : 8;
   1.958-		wmode(a, s, v);
   1.959-		break;
   1.960-	case 6: /* BRA */
   1.961-		v = (s8int)op;
   1.962-		if(v == 0)
   1.963-			v = (s16int)fetch16();
   1.964-		else if(v == (u32int)-1)
   1.965-			v = fetch32();
   1.966-		if((op & 0xf00) == 0x100){ /* BSR */
   1.967-			push32(pc);
   1.968-			pc = curpc + 2 + v;
   1.969-			tim += 18;
   1.970-			break;
   1.971-		}
   1.972-		if(cond((op >> 8) & 0xf)){
   1.973-			pc = curpc + 2 + v;
   1.974-			tim += 10;
   1.975-		}else
   1.976-			tim += (u8int)(op + 1) <= 1 ? 12 : 8;
   1.977-		break;
   1.978-	case 7: /* MOVEQ */
   1.979-		r[n] = (s8int)op;
   1.980-		nz(r[n], 0);
   1.981-		tim += 4;
   1.982-		break;
   1.983-	case 8:
   1.984-		if(s == 3){ /* DIVU, DIVS */
   1.985-			a = amode(op >> 3, op, 1);
   1.986-			v = rmode(a, 1);
   1.987-			if(v == 0){
   1.988-				trap(5, curpc);
   1.989-				break;
   1.990-			}
   1.991-			if((op & 0x100) != 0){
   1.992-				w = (s32int)r[n] % (s16int)v;
   1.993-				v = (s32int)r[n] / (s16int)v;
   1.994-				if(((s16int)w ^ (s16int)v) < 0)
   1.995-					w = -w;
   1.996-				if(v != (u32int)(s16int)v){
   1.997-					rS = rS & ~FLAGC | FLAGV;
   1.998-					break;
   1.999-				}
  1.1000-				tim += 158;
  1.1001-			}else{
  1.1002-				w = r[n] % (u16int)v;
  1.1003-				v = r[n] / (u16int)v;
  1.1004-				if(v >= 0x10000){
  1.1005-					rS = rS & ~FLAGC | FLAGV;
  1.1006-					break;
  1.1007-				}
  1.1008-				tim += 140;
  1.1009-			}
  1.1010-			r[n] = (u16int)v | w << 16;
  1.1011-			nz(v, 1);
  1.1012-			break;
  1.1013-		}
  1.1014-		if((op & 0x1f0) == 0x100){ /* SBCD */
  1.1015-			n = (op >> 9) & 7;
  1.1016-			m = op & 7;
  1.1017-			if((op & 8) != 0){
  1.1018-				a = amode(4, n, 0);
  1.1019-				v = rmode(a, 0);
  1.1020-				w = rmode(amode(4, m, 0), 0);
  1.1021-				v = subbcd(v, w);
  1.1022-				wmode(a, 0, v);
  1.1023-				tim += 18;
  1.1024-			}else{
  1.1025-				r[n] = r[n] & 0xffffff00 | subbcd((u8int)r[n], (u8int)r[m]);
  1.1026-				tim += 6;
  1.1027-			}
  1.1028-			break;
  1.1029-		}
  1.1030-	logic: /* OR, EOR, AND */
  1.1031-		a = amode(op >> 3, op, s);
  1.1032-		n = (op >> 9) & 7;
  1.1033-		v = rmode(a, s);
  1.1034-		switch(op >> 12){
  1.1035-		case 8: v |= r[n]; break;
  1.1036-		case 11: v ^= r[n]; break;
  1.1037-		case 12: v &= r[n]; break;
  1.1038-		}
  1.1039-		if((op & 0x100) == 0)
  1.1040-			a = ~n;
  1.1041-		wmode(a, s, v);
  1.1042-		nz(v, s);
  1.1043-		dtime(op, s);
  1.1044-		break;
  1.1045-	case 11:
  1.1046-		if(s == 3){ /* CMPA */
  1.1047-			s = (op >> 8 & 1) + 1;
  1.1048-			a = amode(op >> 3, op, s);
  1.1049-			rS |= FLAGZ;
  1.1050-			sub(ra[n], rmode(a, s), 0, 2);
  1.1051-			tim += 6;
  1.1052-			break;
  1.1053-		}
  1.1054-		if((op & 0x138) == 0x108){ /* CMPM */
  1.1055-			m = op & 7;
  1.1056-			rS |= FLAGZ;
  1.1057-			sub(rmode(amode(3, n, s), s), rmode(amode(3, m, s), s), 0, s);
  1.1058-			tim += s == 2 ? 20 : 12;
  1.1059-			break;
  1.1060-		}
  1.1061-		if((op & 0x100) == 0){ /* CMP */
  1.1062-			a = amode(op >> 3, op, s);
  1.1063-			rS |= FLAGZ;
  1.1064-			sub(r[n], rmode(a, s), 0, s);
  1.1065-			tim += s == 2 ? 6 : 4;
  1.1066-			break;
  1.1067-		}
  1.1068-		goto logic;
  1.1069-	case 12:
  1.1070-		if(s == 3){ /* MULU, MULS */
  1.1071-			a = amode(op >> 3, op, 1);
  1.1072-			v = rmode(a, 1);
  1.1073-			if((op & 0x100) != 0)
  1.1074-				v *= (s16int)r[n];
  1.1075-			else
  1.1076-				v = (u16int)v * (u16int)r[n];
  1.1077-			r[n] = v;
  1.1078-			nz(v, 1);
  1.1079-			tim += 70;
  1.1080-			break;
  1.1081-		}
  1.1082-		if((op & 0x1f0) == 0x100){ /* ABCD */
  1.1083-			n = (op >> 9) & 7;
  1.1084-			m = op & 7;
  1.1085-			if((op & 8) != 0){
  1.1086-				a = amode(4, n, 0);
  1.1087-				v = rmode(a, 0);
  1.1088-				w = rmode(amode(4, m, 0), 0);
  1.1089-				v = addbcd(v, w);
  1.1090-				wmode(a, 0, v);
  1.1091-				tim += 18;
  1.1092-			}else{
  1.1093-				r[n] = r[n] & 0xffffff00 | addbcd((u8int)r[n], (u8int)r[m]);
  1.1094-				tim += 6;
  1.1095-			}
  1.1096-			break;
  1.1097-		
  1.1098-		}
  1.1099-		if((op & 0x130) == 0x100){ /* EXG */
  1.1100-			m = op & 0xf;
  1.1101-			if((op & 0xc8) == 0x48)
  1.1102-				n |= 8;
  1.1103-			v = r[n];
  1.1104-			r[n] = r[m];
  1.1105-			r[m] = v;
  1.1106-			tim += 6;
  1.1107-			break;
  1.1108-		}
  1.1109-		goto logic;
  1.1110-	case 9:
  1.1111-	case 13:
  1.1112-		if(s == 3){ /* ADDA, SUBA */
  1.1113-			if((op & 0x100) != 0){
  1.1114-				s = 2;
  1.1115-				tim += 6;
  1.1116-			}else{
  1.1117-				s = 1;
  1.1118-				tim += 8;
  1.1119-			}
  1.1120-			a = amode(op >> 3, op, s);
  1.1121-			if((op >> 12) == 13)
  1.1122-				ra[n] += rmode(a, s);
  1.1123-			else
  1.1124-				ra[n] -= rmode(a, s);
  1.1125-			break;
  1.1126-		}
  1.1127-		if((op & 0x130) == 0x100){ /* ADDX, SUBX */
  1.1128-			m = op & 7;
  1.1129-			if((op & 8) != 0){
  1.1130-				a = ra[n] -= 1<<s;
  1.1131-				v = rmode(a, s);
  1.1132-				w = rmode(ra[m] -= 1<<s, s);
  1.1133-				tim += s == 2 ? 30 : 18;
  1.1134-			}else{
  1.1135-				v = r[n];
  1.1136-				w = r[m];
  1.1137-				a = ~n;
  1.1138-				tim += s == 2 ? 8 : 4;
  1.1139-			}
  1.1140-			if((op >> 12) == 13)
  1.1141-				v = add(v, w, (rS & FLAGX) != 0, s);
  1.1142-			else
  1.1143-				v = sub(v, w, (rS & FLAGX) != 0, s);
  1.1144-			wmode(a, s, v);
  1.1145-			rS = rS & ~FLAGX | rS << 4 & FLAGX;
  1.1146-			break;
  1.1147-		} /* ADD, SUB */
  1.1148-		a = amode(op >> 3, op, s);
  1.1149-		rS |= FLAGZ;
  1.1150-		d = (op & 0x100) == 0;
  1.1151-		v = rmode(a, s);
  1.1152-		if((op >> 12) == 13)
  1.1153-			v = add(v, r[n], 0, s);
  1.1154-		else
  1.1155-			v = sub(d ? r[n] : v, d ? v : r[n], 0, s);
  1.1156-		rS = rS & ~FLAGX | rS << 4 & FLAGX;
  1.1157-		if(d)
  1.1158-			a = ~n;
  1.1159-		wmode(a, s, v);
  1.1160-		dtime(op, s);
  1.1161-		break;
  1.1162-	case 14: /* shifts */
  1.1163-		if(s == 3){
  1.1164-			m = op >> 8 & 7;
  1.1165-			n = 1;
  1.1166-			s = 1;
  1.1167-			a = amode(op >> 3, op, s);
  1.1168-		}else{
  1.1169-			a = ~(uvlong)(op & 7);
  1.1170-			m = op >> 2 & 6 | op >> 8 & 1;
  1.1171-			n = (op >> 9) & 7;
  1.1172-			if((op & 0x20) != 0)
  1.1173-				n = r[n] & 63;
  1.1174-			else if(n == 0)
  1.1175-				n = 8;
  1.1176-		}
  1.1177-		wmode(a, s, rot(rmode(a, s), m, n, s));
  1.1178-		break;
  1.1179-	case 10:
  1.1180-		trap(10, curpc);
  1.1181-		break;
  1.1182-	case 15:
  1.1183-		trap(11, curpc);
  1.1184-		break;
  1.1185-	default:
  1.1186-		undef();
  1.1187-	}
  1.1188-	return tim;
  1.1189-}
     2.1--- a/sys/src/games/md/mkfile
     2.2+++ b/sys/src/games/md/mkfile
     2.3@@ -3,7 +3,7 @@
     2.4 BIN=/$objtype/bin/games
     2.5 TARG=md
     2.6 OFILES=\
     2.7-	cpu.$O\
     2.8+	../blit/cpu.$O\
     2.9 	mem.$O\
    2.10 	md.$O\
    2.11 	vdp.$O\