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