xref: /plan9-contrib/sys/src/cmd/aux/realemu/arg.c (revision ccaec48a6a7d481d90233fb80c88e608b0a02604)
1 #include <u.h>
2 #include <libc.h>
3 #include "dat.h"
4 #include "fns.h"
5 
6 #define ause(cpu) (cpu->abuf + (cpu->iabuf++ % nelem(cpu->abuf)))
7 
8 Iarg*
adup(Iarg * x)9 adup(Iarg *x)
10 {
11 	Iarg *a;
12 
13 	a = ause(x->cpu);
14 	*a = *x;
15 	return a;
16 }
17 
18 Iarg*
areg(Cpu * cpu,uchar len,uchar reg)19 areg(Cpu *cpu, uchar len, uchar reg)
20 {
21 	Iarg *a;
22 
23 	a = ause(cpu);
24 	a->cpu = cpu;
25 	a->tag = TREG;
26 	a->len = len;
27 	a->reg = reg;
28 	return a;
29 }
30 
31 Iarg*
amem(Cpu * cpu,uchar len,uchar sreg,ulong off)32 amem(Cpu *cpu, uchar len, uchar sreg, ulong off)
33 {
34 	Iarg *a;
35 
36 	a = ause(cpu);
37 	a->cpu = cpu;
38 	a->tag = TMEM;
39 	a->len = len;
40 	a->sreg = sreg;
41 	a->seg = cpu->reg[sreg];
42 	a->off = off;
43 	return a;
44 }
45 
46 Iarg*
afar(Iarg * mem,uchar len,uchar alen)47 afar(Iarg *mem, uchar len, uchar alen)
48 {
49 	Iarg *a, *p;
50 
51 	p = adup(mem);
52 	p->len = alen;
53 	a = amem(mem->cpu, len, R0S, ar(p));
54 	p->off += alen;
55 	p->len = 2;
56 	a->seg = ar(p);
57 	return a;
58 }
59 
60 Iarg*
acon(Cpu * cpu,uchar len,ulong val)61 acon(Cpu *cpu, uchar len, ulong val)
62 {
63 	Iarg *a;
64 
65 	a = ause(cpu);
66 	a->cpu = cpu;
67 	a->tag = TCON;
68 	a->len = len;
69 	a->val = val;
70 	return a;
71 }
72 
73 ulong
ar(Iarg * a)74 ar(Iarg *a)
75 {
76 	ulong w, o;
77 	Bus *io;
78 
79 	switch(a->tag){
80 	default:
81 		abort();
82 	case TMEM:
83 		o = ((a->seg<<4) + (a->off & 0xFFFF)) & 0xFFFFF;
84 		io = a->cpu->mem + (o>>16);
85 		w = io->r(io->aux, o, a->len);
86 		break;
87 	case TREG:
88 		w = a->cpu->reg[a->reg];
89 		break;
90 	case TREG|TH:
91 		w = a->cpu->reg[a->reg] >> 8;
92 		break;
93 	case TCON:
94 		w = a->val;
95 		break;
96 	}
97 	switch(a->len){
98 	default:
99 		abort();
100 	case 1:
101 		w &= 0xFF;
102 		break;
103 	case 2:
104 		w &= 0xFFFF;
105 		break;
106 	case 4:
107 		break;
108 	}
109 	return w;
110 }
111 
112 long
ars(Iarg * a)113 ars(Iarg *a)
114 {
115 	ulong w = ar(a);
116 	switch(a->len){
117 	default:
118 		abort();
119 	case 1:
120 		return (char)w;
121 	case 2:
122 		return (short)w;
123 	case 4:
124 		return (long)w;
125 	}
126 }
127 
128 void
aw(Iarg * a,ulong w)129 aw(Iarg *a, ulong w)
130 {
131 	ulong *p, o;
132 	Cpu *cpu;
133 	Bus *io;
134 
135 	cpu = a->cpu;
136 	switch(a->tag){
137 	default:
138 		abort();
139 	case TMEM:
140 		o = ((a->seg<<4) + (a->off & 0xFFFF)) & 0xFFFFF;
141 		io = cpu->mem + (o>>16);
142 		io->w(io->aux, o, w, a->len);
143 		break;
144 	case TREG:
145 		p = cpu->reg + a->reg;
146 		switch(a->len){
147 		case 4:
148 			*p = w;
149 			break;
150 		case 2:
151 			*p = (*p & ~0xFFFF) | (w & 0xFFFF);
152 			break;
153 		case 1:
154 			*p = (*p & ~0xFF) | (w & 0xFF);
155 			break;
156 		}
157 		break;
158 	case TREG|TH:
159 		p = cpu->reg + a->reg;
160 		*p = (*p & ~0xFF00) | (w & 0xFF)<<8;
161 		break;
162 	}
163 }
164