Pristine unpack of asxs5p30.zip (excluding top level text file above the root)
[asxv5pxx.git] / as8008 / i08mch.c
1 /* i08mch.c */\r
2 \r
3 /*\r
4  *  Copyright (C) 2018-2019  Alan R. Baldwin\r
5  *\r
6  *  This program is free software: you can redistribute it and/or modify\r
7  *  it under the terms of the GNU General Public License as published by\r
8  *  the Free Software Foundation, either version 3 of the License, or\r
9  *  (at your option) any later version.\r
10  *\r
11  *  This program is distributed in the hope that it will be useful,\r
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14  *  GNU General Public License for more details.\r
15  *\r
16  *  You should have received a copy of the GNU General Public License\r
17  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
18  *\r
19  *\r
20  * Alan R. Baldwin\r
21  * 721 Berkeley St.\r
22  * Kent, Ohio  44240\r
23  */\r
24 \r
25 #include "asxxxx.h"\r
26 #include "i08.h"\r
27 \r
28 char    *cpu    = "Intel 8008 MCS-8";\r
29 char    *dsft   = "asm";\r
30 \r
31 /*\r
32  * Opcode Cycle Definitions\r
33  */\r
34 #define OPCY_SDP        ((char) (0xFF))\r
35 #define OPCY_ERR        ((char) (0xFE))\r
36 \r
37 /*      OPCY_NONE       ((char) (0x80)) */\r
38 /*      OPCY_MASK       ((char) (0x7F)) */\r
39 \r
40 #define UN      ((char) (OPCY_NONE | 0x00))\r
41 \r
42 /*\r
43  * 8008 Cycle Count\r
44  *\r
45  *      opcycles = i80pg1[opcode]\r
46  */\r
47 static char i80pg1[256] = {\r
48 /*--*--* 0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F */\r
49 /*--*--* -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - */\r
50 /*00*/   1,UN, 1, 1, 2, 1, 3, 1, 1, 1, 1, 1, 2, 1, 3, 1,\r
51 /*10*/   1, 1, 1, 1, 2, 1, 3, 1, 1, 1, 1, 1, 2, 1, 3, 1,\r
52 /*20*/   1, 1,UN, 1, 2, 1, 3,UN, 1, 1,UN, 1, 2, 1, 3,UN,\r
53 /*30*/   1, 1,UN, 1, 2, 1, 3, 1,UN,UN,UN, 1, 2, 1, 3, 1,\r
54 /*40*/   3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2,UN, 2,UN, 2,\r
55 /*50*/   3, 2, 3, 2,UN, 2,UN, 2, 3, 2, 3, 2,UN, 2,UN, 2,\r
56 /*60*/   3, 2, 3, 2,UN, 2,UN, 2, 3, 2, 3, 2,UN, 2,UN, 2,\r
57 /*70*/   3, 2, 3, 2,UN, 2,UN, 2, 3, 2, 3, 2,UN, 2,UN, 2,\r
58 /*80*/   1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2,\r
59 /*90*/   1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2,\r
60 /*A0*/   1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2,\r
61 /*B0*/   1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2,\r
62 /*C0*/   1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2,\r
63 /*D0*/   1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2,\r
64 /*E0*/   1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2,\r
65 /*F0*/   1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2\r
66 };\r
67 \r
68 /*\r
69  * Process machine ops.\r
70  */\r
71 VOID\r
72 machine(mp)\r
73 struct mne *mp;\r
74 {\r
75         unsigned int op;\r
76         struct expr e1,e2;\r
77         int t1,t2;\r
78         a_uint v1,v2;\r
79 \r
80         clrexpr(&e1);\r
81         clrexpr(&e2);\r
82         op = (int) mp->m_valu;\r
83         switch (mp->m_type) {\r
84 \r
85         case S_INH:\r
86                 outab(op);\r
87                 break;\r
88 \r
89         case S_INR:\r
90                 t1 = addr(&e1);\r
91                 v1 = e1.e_addr;\r
92                 if ((t1 == S_REG) && (v1 > 0) && (v1 < 7)) {\r
93                         outab(op | (v1<<3));\r
94                 } else {\r
95                         outab(op);\r
96                         aerr();\r
97                 }\r
98                 break;\r
99 \r
100         case S_ADI:\r
101                 expr(&e1, 0);\r
102                 outab(op);\r
103                 outrb(&e1, 0);\r
104                 break;\r
105 \r
106         case S_RST:\r
107                 if (more()) {\r
108                         expr(&e1, 0);\r
109                         if (is_abs(&e1)) {\r
110                                 if (e1.e_addr & ~0x07) {\r
111                                         aerr();\r
112                                 }\r
113                                 v1 = (e1.e_addr & 0x07) << 3;\r
114                                 outab(op | v1);\r
115                         } else {\r
116                                 outrbm(&e1, R_RST, op);\r
117                         }\r
118                 } else {\r
119                         outab(op);\r
120                 }\r
121                 break;\r
122 \r
123         case S_MVI:\r
124                 t1 = addr(&e1);\r
125                 v1 = e1.e_addr;\r
126                 comma(1);\r
127                 expr(&e2, 0);\r
128                 if (t1 == S_REG) {\r
129                         outab(op | (v1<<3));\r
130                         outrb(&e2, 0);\r
131                 } else {\r
132                         outab(op);\r
133                         outab(0);\r
134                         aerr();\r
135                 }\r
136                 break;\r
137 \r
138         case S_JMP:\r
139                 expr(&e1, 0);\r
140                 outab(op);\r
141                 outrw(&e1, 0);\r
142                 break;\r
143 \r
144         case S_IN:\r
145                 expr(&e1, 0);\r
146                 if (is_abs(&e1)) {\r
147                         if (e1.e_addr & ~0x07) {\r
148                                 outab(op);\r
149                                 aerr();\r
150                         } else {\r
151                                 outab(op | (e1.e_addr<<1));\r
152                         }\r
153                 } else {\r
154                         outrbm(&e1, R_IN, op);\r
155                 }\r
156                 break;\r
157 \r
158         case S_OUT:\r
159                 expr(&e1, 0);\r
160                 if (is_abs(&e1)) {\r
161                         if ((e1.e_addr & ~0x1F) || (e1.e_addr < 0x08)) {\r
162                                 outab(op | 0x08);\r
163                                 aerr();\r
164                         } else {\r
165                                 outab(op | (e1.e_addr<<1));\r
166                         }\r
167                 } else {\r
168                         outrbm(&e1, R_OUT, op);\r
169                 }\r
170                 break;\r
171 \r
172         case S_ADD:\r
173                 t1 = addr(&e1);\r
174                 v1 = e1.e_addr;\r
175                 switch(t1) {\r
176                 case S_IMMED:\r
177                         switch(op) {\r
178                         default:\r
179                         case 0x80:      outab(0x04);    break;  /* ADD # -> ADI */\r
180                         case 0x88:      outab(0x0C);    break;  /* ADC # -> ACI */\r
181                         case 0x90:      outab(0x14);    break;  /* SUB # -> SUI */\r
182                         case 0x98:      outab(0x1C);    break;  /* SUB # -> SBI */\r
183                         case 0xA0:      outab(0x24);    break;  /* ANA # -> ANI */\r
184                         case 0xA8:      outab(0x2C);    break;  /* XRA # -> XRI */\r
185                         case 0xB0:      outab(0x34);    break;  /* ORA # -> ORI */\r
186                         case 0xB8:      outab(0x3C);    break;  /* CMP # -> CPI */\r
187                         }\r
188                         outrb(&e1, 0);\r
189                         break;\r
190                 case S_REG:\r
191                         outab(op | v1);\r
192                         break;\r
193                 default:\r
194                         aerr();\r
195                         outab(op);\r
196                         break;\r
197                 }\r
198                 break;\r
199 \r
200         case S_MOV:\r
201                 t1 = addr(&e1);\r
202                 v1 = e1.e_addr;\r
203                 comma(1);\r
204                 t2 = addr(&e2);\r
205                 v2 = e2.e_addr;\r
206                 if ((t1 == S_REG) && (t2 == S_REG)) {\r
207                         outab(op | (v1<<3) | v2);\r
208                 } else\r
209                 if ((t1 == S_REG) && (t2 == S_IMMED)) {\r
210                         switch(v1) {\r
211                         case A:         outab(0x06);    break;  /* MVI A,X */\r
212                         case B:         outab(0x0E);    break;  /* MVI B,X */\r
213                         case C:         outab(0x16);    break;  /* MVI C,X */\r
214                         case D:         outab(0x1E);    break;  /* MVI D,X */\r
215                         case E:         outab(0x26);    break;  /* MVI E,X */\r
216                         case H:         outab(0x2E);    break;  /* MVI H,X */\r
217                         case L:         outab(0x36);    break;  /* MVI L,X */\r
218                         case M:         outab(0x3E);    break;  /* MVI M,X */\r
219                         }\r
220                         outrb(&e2, 0);\r
221                 } else {\r
222                         outab(op);\r
223                         aerr();\r
224                 }\r
225                 break;\r
226 \r
227         default:\r
228                 opcycles = OPCY_ERR;\r
229                 err('o');\r
230                 break;\r
231         }\r
232         if (opcycles == OPCY_NONE) {\r
233                 opcycles = i80pg1[cb[0] & 0xFF];\r
234         }\r
235 }\r
236 \r
237 /*\r
238  *Machine specific initialization.\r
239  */\r
240 VOID\r
241 minit()\r
242 {\r
243         /*\r
244          * Byte Order\r
245          */\r
246         hilo = 0;\r
247 }\r