First Commit of my working state
[simh.git] / AltairZ80 / altairz80_sys.c
CommitLineData
196ba1fc
PH
1/* altairz80_sys.c: MITS Altair system interface
2
3 Copyright (c) 2002-2008, Peter Schorn
4
5 Permission is hereby granted, free of charge, to any person obtaining a
6 copy of this software and associated documentation files (the "Software"),
7 to deal in the Software without restriction, including without limitation
8 the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 and/or sell copies of the Software, and to permit persons to whom the
10 Software is furnished to do so, subject to the following conditions:
11
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 PETER SCHORN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22 Except as contained in this notice, the name of Peter Schorn shall not
23 be used in advertising or otherwise to promote the sale, use or other dealings
24 in this Software without prior written authorization from Peter Schorn.
25
26 Based on work by Charles E Owen (c) 1997
27 Disassembler from Marat Fayzullin ((c) 1995, 1996, 1997 - Commercial use prohibited)
28*/
29
30#include <ctype.h>
31#include "altairz80_defs.h"
32
33#define SIM_EMAX 6
34
35extern UNIT cpu_unit;
36extern REG cpu_reg[];
37extern DEVICE cpu_dev;
38extern DEVICE sio_dev;
39extern DEVICE simh_device;
40extern DEVICE ptr_dev;
41extern DEVICE ptp_dev;
42extern DEVICE dsk_dev;
43extern DEVICE hdsk_dev;
44extern DEVICE net_dev;
45
46extern DEVICE mfdc_dev;
47extern DEVICE fw2_dev;
48extern DEVICE fif_dev;
49extern DEVICE vfdhd_dev;
50extern DEVICE mdsad_dev;
51extern DEVICE nsfpb_dev;
52extern DEVICE disk1a_dev;
53extern DEVICE disk2_dev;
54extern DEVICE selchan_dev;
55extern DEVICE ss1_dev;
56extern DEVICE i8272_dev;
57extern DEVICE mdriveh_dev;
58
59extern DEVICE cromfdc_dev;
60extern DEVICE wd179x_dev;
61extern DEVICE n8vem_dev;
62extern DEVICE scp300f_dev;
63
64#ifdef USE_FPC
65extern DEVICE fpc_dev;
66#endif /* USE_FPC */
67
68extern int32 chiptype;
69extern long disasm (unsigned char *data, char *output, int segsize, long offset);
70
71t_stat fprint_sym (FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw); /* psco */
72t_stat parse_sym(char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw); /* psco */
73
74t_stat set_membase(UNIT *uptr, int32 val, char *cptr, void *desc);
75t_stat show_membase(FILE *st, UNIT *uptr, int32 val, void *desc);
76t_stat set_iobase(UNIT *uptr, int32 val, char *cptr, void *desc);
77t_stat show_iobase(FILE *st, UNIT *uptr, int32 val, void *desc);
78
79/* SCP data structures
80 sim_name simulator name string
81 sim_PC pointer to saved PC register descriptor
82 sim_emax number of words needed for examine
83 sim_devices array of pointers to simulated devices
84 sim_stop_messages array of pointers to stop messages
85*/
86
87char sim_name[] = "Altair 8800 (Z80)";
88REG *sim_PC = &cpu_reg[6];
89int32 sim_emax = SIM_EMAX;
90DEVICE *sim_devices[] = {
91 &cpu_dev, &sio_dev, &simh_device, &ptr_dev, &ptp_dev, &dsk_dev,
92 &hdsk_dev, &net_dev, &mfdc_dev, &fw2_dev, &fif_dev, &vfdhd_dev, &mdsad_dev,
93 &disk1a_dev, &disk2_dev, &selchan_dev, &ss1_dev, &i8272_dev, &mdriveh_dev,
94 &cromfdc_dev, &wd179x_dev, &n8vem_dev, &scp300f_dev,
95#ifdef USE_FPC
96 &fpc_dev,
97#endif /* USE_FPC */
98 NULL
99};
100
101char memoryAccessMessage[80];
102const char *sim_stop_messages[] = {
103 "HALT instruction",
104 "Breakpoint",
105 memoryAccessMessage,
106 "Invalid Opcode"
107};
108
109static char *const Mnemonics8080[] = {
110/* 0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */
111 "NOP", "LXI B,#h", "STAX B", "INX B", "INR B", "DCR B", "MVI B,*h", "RLC", /* 00-07 */
112 "DB 09h", "DAD B", "LDAX B", "DCX B", "INR C", "DCR C", "MVI C,*h", "RRC", /* 08-0f */
113 "DB 10h", "LXI D,#h", "STAX D", "INX D", "INR D", "DCR D", "MVI D,*h", "RAL", /* 10-17 */
114 "DB 18h", "DAD D", "LDAX D", "DCX D", "INR E", "DCR E", "MVI E,*h", "RAR", /* 18-1f */
115 "DB 20h", "LXI H,#h", "SHLD #h", "INX H", "INR H", "DCR H", "MVI H,*h", "DAA", /* 20-27 */
116 "DB 28h", "DAD H", "LHLD #h", "DCX H", "INR L", "DCR L", "MVI L,*h", "CMA", /* 28-2f */
117 "DB 30h", "LXI SP,#h", "STA #h", "INX SP", "INR M", "DCR M", "MVI M,*h", "STC", /* 30-37 */
118 "DB 38h", "DAD SP", "LDA #h", "DCX SP", "INR A", "DCR A", "MVI A,*h", "CMC", /* 38-3f */
119 "MOV B,B", "MOV B,C", "MOV B,D", "MOV B,E", "MOV B,H", "MOV B,L", "MOV B,M", "MOV B,A", /* 40-47 */
120 "MOV C,B", "MOV C,C", "MOV C,D", "MOV C,E", "MOV C,H", "MOV C,L", "MOV C,M", "MOV C,A", /* 48-4f */
121 "MOV D,B", "MOV D,C", "MOV D,D", "MOV D,E", "MOV D,H", "MOV D,L", "MOV D,M", "MOV D,A", /* 50-57 */
122 "MOV E,B", "MOV E,C", "MOV E,D", "MOV E,E", "MOV E,H", "MOV E,L", "MOV E,M", "MOV E,A", /* 58-5f */
123 "MOV H,B", "MOV H,C", "MOV H,D", "MOV H,E", "MOV H,H", "MOV H,L", "MOV H,M", "MOV H,A", /* 60-67 */
124 "MOV L,B", "MOV L,C", "MOV L,D", "MOV L,E", "MOV L,H", "MOV L,L", "MOV L,M", "MOV L,A", /* 68-6f */
125 "MOV M,B", "MOV M,C", "MOV M,D", "MOV M,E", "MOV M,H", "MOV M,L", "HLT", "MOV M,A", /* 70-77 */
126 "MOV A,B", "MOV A,C", "MOV A,D", "MOV A,E", "MOV A,H", "MOV A,L", "MOV A,M", "MOV A,A", /* 78-7f */
127 "ADD B", "ADD C", "ADD D", "ADD E", "ADD H", "ADD L", "ADD M", "ADD A", /* 80-87 */
128 "ADC B", "ADC C", "ADC D", "ADC E", "ADC H", "ADC L", "ADC M", "ADC A", /* 88-8f */
129 "SUB B", "SUB C", "SUB D", "SUB E", "SUB H", "SUB L", "SUB M", "SUB A", /* 90-97 */
130 "SBB B", "SBB C", "SBB D", "SBB E", "SBB H", "SBB L", "SBB M", "SBB A", /* 98-9f */
131 "ANA B", "ANA C", "ANA D", "ANA E", "ANA H", "ANA L", "ANA M", "ANA A", /* a0-a7 */
132 "XRA B", "XRA C", "XRA D", "XRA E", "XRA H", "XRA L", "XRA M", "XRA A", /* a8-af */
133 "ORA B", "ORA C", "ORA D", "ORA E", "ORA H", "ORA L", "ORA M", "ORA A", /* b0-b7 */
134 "CMP B", "CMP C", "CMP D", "CMP E", "CMP H", "CMP L", "CMP M", "CMP A", /* b8-bf */
135 "RNZ", "POP B", "JNZ #h", "JMP #h", "CNZ #h", "PUSH B", "ADI *h", "RST 0", /* c0-c7 */
136 "RZ", "RET", "JZ #h", "DB CBh", "CZ #h", "CALL #h", "ACI *h", "RST 1", /* c8-cf */
137 "RNC", "POP D", "JNC #h", "OUT *h", "CNC #h", "PUSH D", "SUI *h", "RST 2", /* d0-d7 */
138 "RC", "DB D9h", "JC #h", "IN *h", "CC #h", "DB DDh", "SBI *h", "RST 3", /* d8-df */
139 "RPO", "POP H", "JPO #h", "XTHL", "CPO #h", "PUSH H", "ANI *h", "RST 4", /* e0-e7 */
140 "RPE", "PCHL", "JPE #h", "XCHG", "CPE #h", "DB EDh", "XRI *h", "RST 5", /* e8-ef */
141 "RP", "POP PSW", "JP #h", "DI", "CP #h", "PUSH PSW", "ORI *h", "RST 6", /* f0-f7 */
142 "RM", "SPHL", "JM #h", "EI", "CM #h", "DB FDh", "CPI *h", "RST 7" /* f8-ff */
143};
144
145static char *const MnemonicsZ80[256] = {
146/* 0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */
147 "NOP", "LD BC,#h", "LD (BC),A", "INC BC", "INC B", "DEC B", "LD B,*h", "RLCA", /* 00-07 */
148 "EX AF,AF'", "ADD HL,BC", "LD A,(BC)", "DEC BC", "INC C", "DEC C", "LD C,*h", "RRCA", /* 08-0f */
149 "DJNZ $h", "LD DE,#h", "LD (DE),A", "INC DE", "INC D", "DEC D", "LD D,*h", "RLA", /* 10-17 */
150 "JR $h", "ADD HL,DE", "LD A,(DE)", "DEC DE", "INC E", "DEC E", "LD E,*h", "RRA", /* 18-1f */
151 "JR NZ,$h", "LD HL,#h", "LD (#h),HL", "INC HL", "INC H", "DEC H", "LD H,*h", "DAA", /* 20-27 */
152 "JR Z,$h", "ADD HL,HL", "LD HL,(#h)", "DEC HL", "INC L", "DEC L", "LD L,*h", "CPL", /* 28-2f */
153 "JR NC,$h", "LD SP,#h", "LD (#h),A", "INC SP", "INC (HL)", "DEC (HL)", "LD (HL),*h", "SCF", /* 30-37 */
154 "JR C,$h", "ADD HL,SP", "LD A,(#h)", "DEC SP", "INC A", "DEC A", "LD A,*h", "CCF", /* 38-3f */
155 "LD B,B", "LD B,C", "LD B,D", "LD B,E", "LD B,H", "LD B,L", "LD B,(HL)", "LD B,A", /* 40-47 */
156 "LD C,B", "LD C,C", "LD C,D", "LD C,E", "LD C,H", "LD C,L", "LD C,(HL)", "LD C,A", /* 48-4f */
157 "LD D,B", "LD D,C", "LD D,D", "LD D,E", "LD D,H", "LD D,L", "LD D,(HL)", "LD D,A", /* 50-57 */
158 "LD E,B", "LD E,C", "LD E,D", "LD E,E", "LD E,H", "LD E,L", "LD E,(HL)", "LD E,A", /* 58-5f */
159 "LD H,B", "LD H,C", "LD H,D", "LD H,E", "LD H,H", "LD H,L", "LD H,(HL)", "LD H,A", /* 60-67 */
160 "LD L,B", "LD L,C", "LD L,D", "LD L,E", "LD L,H", "LD L,L", "LD L,(HL)", "LD L,A", /* 68-6f */
161 "LD (HL),B", "LD (HL),C", "LD (HL),D", "LD (HL),E", "LD (HL),H", "LD (HL),L", "HALT", "LD (HL),A", /* 70-77 */
162 "LD A,B", "LD A,C", "LD A,D", "LD A,E", "LD A,H", "LD A,L", "LD A,(HL)", "LD A,A", /* 78-7f */
163 "ADD A,B", "ADD A,C", "ADD A,D", "ADD A,E", "ADD A,H", "ADD A,L", "ADD A,(HL)", "ADD A,A", /* 80-87 */
164 "ADC A,B", "ADC A,C", "ADC A,D", "ADC A,E", "ADC A,H", "ADC A,L", "ADC A,(HL)", "ADC A,A", /* 88-8f */
165 "SUB B", "SUB C", "SUB D", "SUB E", "SUB H", "SUB L", "SUB (HL)", "SUB A", /* 90-97 */
166 "SBC A,B", "SBC A,C", "SBC A,D", "SBC A,E", "SBC A,H", "SBC A,L", "SBC A,(HL)", "SBC A,A", /* 98-9f */
167 "AND B", "AND C", "AND D", "AND E", "AND H", "AND L", "AND (HL)", "AND A", /* a0-a7 */
168 "XOR B", "XOR C", "XOR D", "XOR E", "XOR H", "XOR L", "XOR (HL)", "XOR A", /* a8-af */
169 "OR B", "OR C", "OR D", "OR E", "OR H", "OR L", "OR (HL)", "OR A", /* b0-b7 */
170 "CP B", "CP C", "CP D", "CP E", "CP H", "CP L", "CP (HL)", "CP A", /* b8-bf */
171 "RET NZ", "POP BC", "JP NZ,#h", "JP #h", "CALL NZ,#h", "PUSH BC", "ADD A,*h", "RST 00h", /* c0-c7 */
172 "RET Z", "RET", "JP Z,#h", "PFX_CB", "CALL Z,#h", "CALL #h", "ADC A,*h", "RST 08h", /* c8-cf */
173 "RET NC", "POP DE", "JP NC,#h", "OUT (*h),A", "CALL NC,#h", "PUSH DE", "SUB *h", "RST 10h", /* d0-d7 */
174 "RET C", "EXX", "JP C,#h", "IN A,(*h)", "CALL C,#h", "PFX_DD", "SBC A,*h", "RST 18h", /* d8-df */
175 "RET PO", "POP HL", "JP PO,#h", "EX (SP),HL", "CALL PO,#h", "PUSH HL", "AND *h", "RST 20h", /* e0-e7 */
176 "RET PE", "LD PC,HL", "JP PE,#h", "EX DE,HL", "CALL PE,#h", "PFX_ED", "XOR *h", "RST 28h", /* e8-ef */
177 "RET P", "POP AF", "JP P,#h", "DI", "CALL P,#h", "PUSH AF", "OR *h", "RST 30h", /* f0-f7 */
178 "RET M", "LD SP,HL", "JP M,#h", "EI", "CALL M,#h", "PFX_FD", "CP *h", "RST 38h" /* f8-ff */
179};
180
181static char *const MnemonicsCB[256] = {
182/* 0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */
183 "RLC B", "RLC C", "RLC D", "RLC E", "RLC H", "RLC L", "RLC (HL)", "RLC A", /* 00-07 */
184 "RRC B", "RRC C", "RRC D", "RRC E", "RRC H", "RRC L", "RRC (HL)", "RRC A", /* 08-0f */
185 "RL B", "RL C", "RL D", "RL E", "RL H", "RL L", "RL (HL)", "RL A", /* 10-17 */
186 "RR B", "RR C", "RR D", "RR E", "RR H", "RR L", "RR (HL)", "RR A", /* 18-1f */
187 "SLA B", "SLA C", "SLA D", "SLA E", "SLA H", "SLA L", "SLA (HL)", "SLA A", /* 20-27 */
188 "SRA B", "SRA C", "SRA D", "SRA E", "SRA H", "SRA L", "SRA (HL)", "SRA A", /* 28-2f */
189 "SLL B", "SLL C", "SLL D", "SLL E", "SLL H", "SLL L", "SLL (HL)", "SLL A", /* 30-37 */
190 "SRL B", "SRL C", "SRL D", "SRL E", "SRL H", "SRL L", "SRL (HL)", "SRL A", /* 38-3f */
191 "BIT 0,B", "BIT 0,C", "BIT 0,D", "BIT 0,E", "BIT 0,H", "BIT 0,L", "BIT 0,(HL)", "BIT 0,A", /* 40-47 */
192 "BIT 1,B", "BIT 1,C", "BIT 1,D", "BIT 1,E", "BIT 1,H", "BIT 1,L", "BIT 1,(HL)", "BIT 1,A", /* 48-4f */
193 "BIT 2,B", "BIT 2,C", "BIT 2,D", "BIT 2,E", "BIT 2,H", "BIT 2,L", "BIT 2,(HL)", "BIT 2,A", /* 50-57 */
194 "BIT 3,B", "BIT 3,C", "BIT 3,D", "BIT 3,E", "BIT 3,H", "BIT 3,L", "BIT 3,(HL)", "BIT 3,A", /* 58-5f */
195 "BIT 4,B", "BIT 4,C", "BIT 4,D", "BIT 4,E", "BIT 4,H", "BIT 4,L", "BIT 4,(HL)", "BIT 4,A", /* 60-67 */
196 "BIT 5,B", "BIT 5,C", "BIT 5,D", "BIT 5,E", "BIT 5,H", "BIT 5,L", "BIT 5,(HL)", "BIT 5,A", /* 68-6f */
197 "BIT 6,B", "BIT 6,C", "BIT 6,D", "BIT 6,E", "BIT 6,H", "BIT 6,L", "BIT 6,(HL)", "BIT 6,A", /* 70-77 */
198 "BIT 7,B", "BIT 7,C", "BIT 7,D", "BIT 7,E", "BIT 7,H", "BIT 7,L", "BIT 7,(HL)", "BIT 7,A", /* 78-7f */
199 "RES 0,B", "RES 0,C", "RES 0,D", "RES 0,E", "RES 0,H", "RES 0,L", "RES 0,(HL)", "RES 0,A", /* 80-87 */
200 "RES 1,B", "RES 1,C", "RES 1,D", "RES 1,E", "RES 1,H", "RES 1,L", "RES 1,(HL)", "RES 1,A", /* 88-8f */
201 "RES 2,B", "RES 2,C", "RES 2,D", "RES 2,E", "RES 2,H", "RES 2,L", "RES 2,(HL)", "RES 2,A", /* 90-97 */
202 "RES 3,B", "RES 3,C", "RES 3,D", "RES 3,E", "RES 3,H", "RES 3,L", "RES 3,(HL)", "RES 3,A", /* 98-9f */
203 "RES 4,B", "RES 4,C", "RES 4,D", "RES 4,E", "RES 4,H", "RES 4,L", "RES 4,(HL)", "RES 4,A", /* a0-a7 */
204 "RES 5,B", "RES 5,C", "RES 5,D", "RES 5,E", "RES 5,H", "RES 5,L", "RES 5,(HL)", "RES 5,A", /* a8-af */
205 "RES 6,B", "RES 6,C", "RES 6,D", "RES 6,E", "RES 6,H", "RES 6,L", "RES 6,(HL)", "RES 6,A", /* b0-b7 */
206 "RES 7,B", "RES 7,C", "RES 7,D", "RES 7,E", "RES 7,H", "RES 7,L", "RES 7,(HL)", "RES 7,A", /* b8-bf */
207 "SET 0,B", "SET 0,C", "SET 0,D", "SET 0,E", "SET 0,H", "SET 0,L", "SET 0,(HL)", "SET 0,A", /* c0-c7 */
208 "SET 1,B", "SET 1,C", "SET 1,D", "SET 1,E", "SET 1,H", "SET 1,L", "SET 1,(HL)", "SET 1,A", /* c8-cf */
209 "SET 2,B", "SET 2,C", "SET 2,D", "SET 2,E", "SET 2,H", "SET 2,L", "SET 2,(HL)", "SET 2,A", /* d0-d7 */
210 "SET 3,B", "SET 3,C", "SET 3,D", "SET 3,E", "SET 3,H", "SET 3,L", "SET 3,(HL)", "SET 3,A", /* d8-df */
211 "SET 4,B", "SET 4,C", "SET 4,D", "SET 4,E", "SET 4,H", "SET 4,L", "SET 4,(HL)", "SET 4,A", /* e0-e7 */
212 "SET 5,B", "SET 5,C", "SET 5,D", "SET 5,E", "SET 5,H", "SET 5,L", "SET 5,(HL)", "SET 5,A", /* e8-ef */
213 "SET 6,B", "SET 6,C", "SET 6,D", "SET 6,E", "SET 6,H", "SET 6,L", "SET 6,(HL)", "SET 6,A", /* f0-f7 */
214 "SET 7,B", "SET 7,C", "SET 7,D", "SET 7,E", "SET 7,H", "SET 7,L", "SET 7,(HL)", "SET 7,A" /* f8-ff */
215};
216
217static char *const MnemonicsED[256] = {
218/* 0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */
219 "DB EDh,00h", "DB EDh,01h", "DB EDh,02h", "DB EDh,03h", "DB EDh,04h", "DB EDh,05h", "DB EDh,06h", "DB EDh,07h", /* 00-07 */
220 "DB EDh,08h", "DB EDh,09h", "DB EDh,0Ah", "DB EDh,0Bh", "DB EDh,0Ch", "DB EDh,0Dh", "DB EDh,0Eh", "DB EDh,0Fh", /* 08-0f */
221 "DB EDh,10h", "DB EDh,11h", "DB EDh,12h", "DB EDh,13h", "DB EDh,14h", "DB EDh,15h", "DB EDh,16h", "DB EDh,17h", /* 10-17 */
222 "DB EDh,18h", "DB EDh,19h", "DB EDh,1Ah", "DB EDh,1Bh", "DB EDh,1Ch", "DB EDh,1Dh", "DB EDh,1Eh", "DB EDh,1Fh", /* 18-1f */
223 "DB EDh,20h", "DB EDh,21h", "DB EDh,22h", "DB EDh,23h", "DB EDh,24h", "DB EDh,25h", "DB EDh,26h", "DB EDh,27h", /* 20-27 */
224 "DB EDh,28h", "DB EDh,29h", "DB EDh,2Ah", "DB EDh,2Bh", "DB EDh,2Ch", "DB EDh,2Dh", "DB EDh,2Eh", "DB EDh,2Fh", /* 28-2f */
225 "DB EDh,30h", "DB EDh,31h", "DB EDh,32h", "DB EDh,33h", "DB EDh,34h", "DB EDh,35h", "DB EDh,36h", "DB EDh,37h", /* 30-37 */
226 "DB EDh,38h", "DB EDh,39h", "DB EDh,3Ah", "DB EDh,3Bh", "DB EDh,3Ch", "DB EDh,3Dh", "DB EDh,3Eh", "DB EDh,3Fh", /* 38-3f */
227 "IN B,(C)", "OUT (C),B", "SBC HL,BC", "LD (#h),BC", "NEG", "RETN", "IM 0", "LD I,A", /* 40-47 */
228 "IN C,(C)", "OUT (C),C", "ADC HL,BC", "LD BC,(#h)", "DB EDh,4Ch", "RETI", "DB EDh,4Eh", "LD R,A", /* 48-4f */
229 "IN D,(C)", "OUT (C),D", "SBC HL,DE", "LD (#h),DE", "DB EDh,54h", "DB EDh,55h", "IM 1", "LD A,I", /* 50-57 */
230 "IN E,(C)", "OUT (C),E", "ADC HL,DE", "LD DE,(#h)", "DB EDh,5Ch", "DB EDh,5Dh", "IM 2", "LD A,R", /* 58-5f */
231 "IN H,(C)", "OUT (C),H", "SBC HL,HL", "LD (#h),HL", "DB EDh,64h", "DB EDh,65h", "DB EDh,66h", "RRD", /* 60-67 */
232 "IN L,(C)", "OUT (C),L", "ADC HL,HL", "LD HL,(#h)", "DB EDh,6Ch", "DB EDh,6Dh", "DB EDh,6Eh", "RLD", /* 68-6f */
233 "IN F,(C)", "DB EDh,71h", "SBC HL,SP", "LD (#h),SP", "DB EDh,74h", "DB EDh,75h", "DB EDh,76h", "DB EDh,77h", /* 70-77 */
234 "IN A,(C)", "OUT (C),A", "ADC HL,SP", "LD SP,(#h)", "DB EDh,7Ch", "DB EDh,7Dh", "DB EDh,7Eh", "DB EDh,7Fh", /* 78-7f */
235 "DB EDh,80h", "DB EDh,81h", "DB EDh,82h", "DB EDh,83h", "DB EDh,84h", "DB EDh,85h", "DB EDh,86h", "DB EDh,87h", /* 80-87 */
236 "DB EDh,88h", "DB EDh,89h", "DB EDh,8Ah", "DB EDh,8Bh", "DB EDh,8Ch", "DB EDh,8Dh", "DB EDh,8Eh", "DB EDh,8Fh", /* 88-8f */
237 "DB EDh,90h", "DB EDh,91h", "DB EDh,92h", "DB EDh,93h", "DB EDh,94h", "DB EDh,95h", "DB EDh,96h", "DB EDh,97h", /* 90-97 */
238 "DB EDh,98h", "DB EDh,99h", "DB EDh,9Ah", "DB EDh,9Bh", "DB EDh,9Ch", "DB EDh,9Dh", "DB EDh,9Eh", "DB EDh,9Fh", /* 98-9f */
239 "LDI", "CPI", "INI", "OUTI", "DB EDh,A4h", "DB EDh,A5h", "DB EDh,A6h", "DB EDh,A7h", /* a0-a7 */
240 "LDD", "CPD", "IND", "OUTD", "DB EDh,ACh", "DB EDh,ADh", "DB EDh,AEh", "DB EDh,AFh", /* a8-af */
241 "LDIR", "CPIR", "INIR", "OTIR", "DB EDh,B4h", "DB EDh,B5h", "DB EDh,B6h", "DB EDh,B7h", /* b0-b7 */
242 "LDDR", "CPDR", "INDR", "OTDR", "DB EDh,BCh", "DB EDh,BDh", "DB EDh,BEh", "DB EDh,BFh", /* b8-bf */
243 "DB EDh,C0h", "DB EDh,C1h", "DB EDh,C2h", "DB EDh,C3h", "DB EDh,C4h", "DB EDh,C5h", "DB EDh,C6h", "DB EDh,C7h", /* c0-c7 */
244 "DB EDh,C8h", "DB EDh,C9h", "DB EDh,CAh", "DB EDh,CBh", "DB EDh,CCh", "DB EDh,CDh", "DB EDh,CEh", "DB EDh,CFh", /* c8-cf */
245 "DB EDh,D0h", "DB EDh,D1h", "DB EDh,D2h", "DB EDh,D3h", "DB EDh,D4h", "DB EDh,D5h", "DB EDh,D6h", "DB EDh,D7h", /* d0-d7 */
246 "DB EDh,D8h", "DB EDh,D9h", "DB EDh,DAh", "DB EDh,DBh", "DB EDh,DCh", "DB EDh,DDh", "DB EDh,DEh", "DB EDh,DFh", /* d8-df */
247 "DB EDh,E0h", "DB EDh,E1h", "DB EDh,E2h", "DB EDh,E3h", "DB EDh,E4h", "DB EDh,E5h", "DB EDh,E6h", "DB EDh,E7h", /* e0-e7 */
248 "DB EDh,E8h", "DB EDh,E9h", "DB EDh,EAh", "DB EDh,EBh", "DB EDh,ECh", "DB EDh,EDh", "DB EDh,EEh", "DB EDh,EFh", /* e8-ef */
249 "DB EDh,F0h", "DB EDh,F1h", "DB EDh,F2h", "DB EDh,F3h", "DB EDh,F4h", "DB EDh,F5h", "DB EDh,F6h", "DB EDh,F7h", /* f0-f7 */
250 "DB EDh,F8h", "DB EDh,F9h", "DB EDh,FAh", "DB EDh,FBh", "DB EDh,FCh", "DB EDh,FDh", "DB EDh,FEh", "DB EDh,FFh" /* f8-ff */
251};
252
253static char *const MnemonicsXX[256] = {
254/* 0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */
255 "NOP", "LD BC,#h", "LD (BC),A", "INC BC", "INC B", "DEC B", "LD B,*h", "RLCA", /* 00-07 */
256 "EX AF,AF'", "ADD I%,BC", "LD A,(BC)", "DEC BC", "INC C", "DEC C", "LD C,*h", "RRCA", /* 08-0f */
257 "DJNZ $h", "LD DE,#h", "LD (DE),A", "INC DE", "INC D", "DEC D", "LD D,*h", "RLA", /* 10-17 */
258 "JR $h", "ADD I%,DE", "LD A,(DE)", "DEC DE", "INC E", "DEC E", "LD E,*h", "RRA", /* 18-1f */
259 "JR NZ,$h", "LD I%,#h", "LD (#h),I%", "INC I%", "INC I%H", "DEC I%H", "LD I%H,*h", "DAA", /* 20-27 */
260 "JR Z,$h", "ADD I%,I%", "LD I%,(#h)", "DEC I%", "INC I%L", "DEC I%L", "LD I%L,*h", "CPL", /* 28-2f */
261 "JR NC,$h", "LD SP,#h", "LD (#h),A", "INC SP", "INC (I%+^h)", "DEC (I%+^h)", "LD (I%+^h),*h","SCF", /* 30-37 */
262 "JR C,$h", "ADD I%,SP", "LD A,(#h)", "DEC SP", "INC A", "DEC A", "LD A,*h", "CCF", /* 38-3f */
263 "LD B,B", "LD B,C", "LD B,D", "LD B,E", "LD B,I%H", "LD B,I%L", "LD B,(I%+^h)", "LD B,A", /* 40-47 */
264 "LD C,B", "LD C,C", "LD C,D", "LD C,E", "LD C,I%H", "LD C,I%L", "LD C,(I%+^h)", "LD C,A", /* 48-4f */
265 "LD D,B", "LD D,C", "LD D,D", "LD D,E", "LD D,I%H", "LD D,I%L", "LD D,(I%+^h)", "LD D,A", /* 50-57 */
266 "LD E,B", "LD E,C", "LD E,D", "LD E,E", "LD E,I%H", "LD E,I%L", "LD E,(I%+^h)", "LD E,A", /* 58-5f */
267 "LD I%H,B", "LD I%H,C", "LD I%H,D", "LD I%H,E", "LD I%H,I%H", "LD I%H,I%L", "LD H,(I%+^h)", "LD I%H,A", /* 60-67 */
268 "LD I%L,B", "LD I%L,C", "LD I%L,D", "LD I%L,E", "LD I%L,I%H", "LD I%L,I%L", "LD L,(I%+^h)", "LD I%L,A", /* 68-6f */
269 "LD (I%+^h),B", "LD (I%+^h),C", "LD (I%+^h),D", "LD (I%+^h),E", "LD (I%+^h),H", "LD (I%+^h),L", "HALT", "LD (I%+^h),A", /* 70-77 */
270 "LD A,B", "LD A,C", "LD A,D", "LD A,E", "LD A,I%H", "LD A,I%L", "LD A,(I%+^h)", "LD A,A", /* 78-7f */
271 "ADD A,B", "ADD A,C", "ADD A,D", "ADD A,E", "ADD A,I%H", "ADD A,I%L", "ADD A,(I%+^h)","ADD A,A", /* 80-87 */
272 "ADC A,B", "ADC A,C", "ADC A,D", "ADC A,E", "ADC A,I%H", "ADC A,I%L", "ADC A,(I%+^h)","ADC A,A", /* 88-8f */
273 "SUB B", "SUB C", "SUB D", "SUB E", "SUB I%H", "SUB I%L", "SUB (I%+^h)", "SUB A", /* 90-97 */
274 "SBC A,B", "SBC A,C", "SBC A,D", "SBC A,E", "SBC A,I%H", "SBC A,I%L", "SBC A,(I%+^h)","SBC A,A", /* 98-9f */
275 "AND B", "AND C", "AND D", "AND E", "AND I%H", "AND I%L", "AND (I%+^h)", "AND A", /* a0-a7 */
276 "XOR B", "XOR C", "XOR D", "XOR E", "XOR I%H", "XOR I%L", "XOR (I%+^h)", "XOR A", /* a8-af */
277 "OR B", "OR C", "OR D", "OR E", "OR I%H", "OR I%L", "OR (I%+^h)", "OR A", /* b0-b7 */
278 "CP B", "CP C", "CP D", "CP E", "CP I%H", "CP I%L", "CP (I%+^h)", "CP A", /* b8-bf */
279 "RET NZ", "POP BC", "JP NZ,#h", "JP #h", "CALL NZ,#h", "PUSH BC", "ADD A,*h", "RST 00h", /* c8-cf */
280 "RET Z", "RET", "JP Z,#h", "PFX_CB", "CALL Z,#h", "CALL #h", "ADC A,*h", "RST 08h", /* c8-cf */
281 "RET NC", "POP DE", "JP NC,#h", "OUT (*h),A", "CALL NC,#h", "PUSH DE", "SUB *h", "RST 10h", /* d0-d7 */
282 "RET C", "EXX", "JP C,#h", "IN A,(*h)", "CALL C,#h", "PFX_DD", "SBC A,*h", "RST 18h", /* d8-df */
283 "RET PO", "POP I%", "JP PO,#h", "EX (SP),I%", "CALL PO,#h", "PUSH I%", "AND *h", "RST 20h", /* e0-e7 */
284 "RET PE", "LD PC,I%", "JP PE,#h", "EX DE,I%", "CALL PE,#h", "PFX_ED", "XOR *h", "RST 28h", /* e8-ef */
285 "RET P", "POP AF", "JP P,#h", "DI", "CALL P,#h", "PUSH AF", "OR *h", "RST 30h", /* f0-f7 */
286 "RET M", "LD SP,I%", "JP M,#h", "EI", "CALL M,#h", "PFX_FD", "CP *h", "RST 38h" /* f8-ff */
287};
288
289static char *const MnemonicsXCB[256] = {
290/*0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */
291 "RLC B", "RLC C", "RLC D", "RLC E", "RLC H", "RLC L", "RLC (I%@h)", "RLC A", /* 00-07 */
292 "RRC B", "RRC C", "RRC D", "RRC E", "RRC H", "RRC L", "RRC (I%@h)", "RRC A", /* 08-0f */
293 "RL B", "RL C", "RL D", "RL E", "RL H", "RL L", "RL (I%@h)", "RL A", /* 10-17 */
294 "RR B", "RR C", "RR D", "RR E", "RR H", "RR L", "RR (I%@h)", "RR A", /* 18-1f */
295 "SLA B", "SLA C", "SLA D", "SLA E", "SLA H", "SLA L", "SLA (I%@h)", "SLA A", /* 20-27 */
296 "SRA B", "SRA C", "SRA D", "SRA E", "SRA H", "SRA L", "SRA (I%@h)", "SRA A", /* 28-2f */
297 "SLL B", "SLL C", "SLL D", "SLL E", "SLL H", "SLL L", "SLL (I%@h)", "SLL A", /* 30-37 */
298 "SRL B", "SRL C", "SRL D", "SRL E", "SRL H", "SRL L", "SRL (I%@h)", "SRL A", /* 38-3f */
299 "BIT 0,B", "BIT 0,C", "BIT 0,D", "BIT 0,E", "BIT 0,H", "BIT 0,L", "BIT 0,(I%@h)", "BIT 0,A", /* 40-47 */
300 "BIT 1,B", "BIT 1,C", "BIT 1,D", "BIT 1,E", "BIT 1,H", "BIT 1,L", "BIT 1,(I%@h)", "BIT 1,A", /* 48-4f */
301 "BIT 2,B", "BIT 2,C", "BIT 2,D", "BIT 2,E", "BIT 2,H", "BIT 2,L", "BIT 2,(I%@h)", "BIT 2,A", /* 50-57 */
302 "BIT 3,B", "BIT 3,C", "BIT 3,D", "BIT 3,E", "BIT 3,H", "BIT 3,L", "BIT 3,(I%@h)", "BIT 3,A", /* 58-5f */
303 "BIT 4,B", "BIT 4,C", "BIT 4,D", "BIT 4,E", "BIT 4,H", "BIT 4,L", "BIT 4,(I%@h)", "BIT 4,A", /* 60-67 */
304 "BIT 5,B", "BIT 5,C", "BIT 5,D", "BIT 5,E", "BIT 5,H", "BIT 5,L", "BIT 5,(I%@h)", "BIT 5,A", /* 68-6f */
305 "BIT 6,B", "BIT 6,C", "BIT 6,D", "BIT 6,E", "BIT 6,H", "BIT 6,L", "BIT 6,(I%@h)", "BIT 6,A", /* 70-77 */
306 "BIT 7,B", "BIT 7,C", "BIT 7,D", "BIT 7,E", "BIT 7,H", "BIT 7,L", "BIT 7,(I%@h)", "BIT 7,A", /* 78-7f */
307 "RES 0,B", "RES 0,C", "RES 0,D", "RES 0,E", "RES 0,H", "RES 0,L", "RES 0,(I%@h)", "RES 0,A", /* 80-87 */
308 "RES 1,B", "RES 1,C", "RES 1,D", "RES 1,E", "RES 1,H", "RES 1,L", "RES 1,(I%@h)", "RES 1,A", /* 88-8f */
309 "RES 2,B", "RES 2,C", "RES 2,D", "RES 2,E", "RES 2,H", "RES 2,L", "RES 2,(I%@h)", "RES 2,A", /* 90-97 */
310 "RES 3,B", "RES 3,C", "RES 3,D", "RES 3,E", "RES 3,H", "RES 3,L", "RES 3,(I%@h)", "RES 3,A", /* 98-9f */
311 "RES 4,B", "RES 4,C", "RES 4,D", "RES 4,E", "RES 4,H", "RES 4,L", "RES 4,(I%@h)", "RES 4,A", /* a0-a7 */
312 "RES 5,B", "RES 5,C", "RES 5,D", "RES 5,E", "RES 5,H", "RES 5,L", "RES 5,(I%@h)", "RES 5,A", /* a8-af */
313 "RES 6,B", "RES 6,C", "RES 6,D", "RES 6,E", "RES 6,H", "RES 6,L", "RES 6,(I%@h)", "RES 6,A", /* b0-b7 */
314 "RES 7,B", "RES 7,C", "RES 7,D", "RES 7,E", "RES 7,H", "RES 7,L", "RES 7,(I%@h)", "RES 7,A", /* b8-bf */
315 "SET 0,B", "SET 0,C", "SET 0,D", "SET 0,E", "SET 0,H", "SET 0,L", "SET 0,(I%@h)", "SET 0,A", /* c0-c7 */
316 "SET 1,B", "SET 1,C", "SET 1,D", "SET 1,E", "SET 1,H", "SET 1,L", "SET 1,(I%@h)", "SET 1,A", /* c8-cf */
317 "SET 2,B", "SET 2,C", "SET 2,D", "SET 2,E", "SET 2,H", "SET 2,L", "SET 2,(I%@h)", "SET 2,A", /* d0-d7 */
318 "SET 3,B", "SET 3,C", "SET 3,D", "SET 3,E", "SET 3,H", "SET 3,L", "SET 3,(I%@h)", "SET 3,A", /* d8-df */
319 "SET 4,B", "SET 4,C", "SET 4,D", "SET 4,E", "SET 4,H", "SET 4,L", "SET 4,(I%@h)", "SET 4,A", /* e0-e7 */
320 "SET 5,B", "SET 5,C", "SET 5,D", "SET 5,E", "SET 5,H", "SET 5,L", "SET 5,(I%@h)", "SET 5,A", /* e8-ef */
321 "SET 6,B", "SET 6,C", "SET 6,D", "SET 6,E", "SET 6,H", "SET 6,L", "SET 6,(I%@h)", "SET 6,A", /* f0-f7 */
322 "SET 7,B", "SET 7,C", "SET 7,D", "SET 7,E", "SET 7,H", "SET 7,L", "SET 7,(I%@h)", "SET 7,A" /* f8-ff */
323};
324
325/* Symbolic disassembler
326
327 Inputs:
328 *val = instructions to disassemble
329 useZ80Mnemonics = > 0 iff Z80 mnemonics are to be used
330 addr = current PC
331 Outputs:
332 *S = output text
333
334 DAsm is Copyright (C) Marat Fayzullin 1995,1996,1997
335 You are not allowed to distribute this software
336 commercially.
337
338*/
339
340static int32 DAsm(char *S, const uint32 *val, const int32 useZ80Mnemonics, const int32 addr) {
341 char R[128], H[10], C = '\0', *T, *P;
342 uint8 J = 0, Offset = 0;
343 uint16 B = 0;
344
345 if (useZ80Mnemonics)
346 switch(val[B]) {
347
348 case 0xcb:
349 B++;
350 T = MnemonicsCB[val[B++]];
351 break;
352
353 case 0xed:
354 B++;
355 T = MnemonicsED[val[B++]];
356 break;
357
358 case 0xdd:
359
360 case 0xfd:
361 C = (val[B++] == 0xdd) ? 'X' : 'Y';
362 if (val[B] == 0xcb) {
363 B++;
364 Offset = val[B++];
365 J = 1;
366 T = MnemonicsXCB[val[B++]];
367 }
368 else T = MnemonicsXX[val[B++]];
369 break;
370
371 default:
372 T = MnemonicsZ80[val[B++]];
373 }
374 else T = Mnemonics8080[val[B++]];
375
376 if ( (P = strchr(T, '^')) ) {
377 strncpy(R, T, P - T);
378 R[P - T] = '\0';
379 sprintf(H, "%02X", val[B++]);
380 strcat(R, H);
381 strcat(R, P + 1);
382 }
383 else strcpy(R, T);
384 if ( (P = strchr(R, '%')) ) {
385 *P = C;
386 if ( (P = strchr(P + 1, '%')) ) *P = C;
387 }
388
389 if ( (P = strchr(R, '*')) ) {
390 strncpy(S, R, P - R);
391 S[P - R] = '\0';
392 sprintf(H, "%02X", val[B++]);
393 strcat(S, H);
394 strcat(S, P + 1);
395 }
396 else if ( (P = strchr(R, '@')) ) {
397 strncpy(S, R, P - R);
398 S[P - R] = '\0';
399 if (!J) Offset = val[B++];
400 strcat(S, Offset & 0x80 ? "-" : "+");
401 J = Offset & 0x80 ? 256 - Offset : Offset;
402 sprintf(H, "%02X", J);
403 strcat(S, H);
404 strcat(S, P + 1);
405 }
406 else if ( (P = strchr(R, '$')) ) {
407 strncpy(S, R, P - R);
408 S[P - R] = '\0';
409 Offset = val[B++];
410 sprintf(H, "%04X", (addr + 2 + (Offset & 0x80 ? (Offset - 256) : Offset)) & 0xFFFF);
411 strcat(S, H);
412 strcat(S, P + 1);
413 }
414 else if ( (P = strchr(R, '#')) ) {
415 strncpy(S, R, P - R);
416 S[P - R] = '\0';
417 sprintf(H, "%04X", val[B] + 256 * val[B + 1]);
418 strcat(S, H);
419 strcat(S, P + 1);
420 B += 2;
421 }
422 else strcpy(S, R);
423 return(B);
424}
425
426/* Symbolic output
427
428 Inputs:
429 *of = output stream
430 addr = current PC
431 *val = pointer to values
432 *uptr = pointer to unit
433 sw = switches
434 Outputs:
435 status = error code
436*/
437
438t_stat fprint_sym(FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw) {
439 char disasm_result[128];
440 int32 ch = val[0] & 0x7f;
441 long r;
442 unsigned char vals[SIM_EMAX];
443 int32 i;
444 if (sw & (SWMASK('A') | SWMASK('C'))) {
445 fprintf(of, ((0x20 <= ch) && (ch < 0x7f)) ? "'%c'" : "%02x", ch);
446 return SCPE_OK;
447 }
448 if (!(sw & SWMASK('M'))) return SCPE_ARG;
449 if (chiptype == CHIP_TYPE_8086) {
450 for (i = 0; i < SIM_EMAX; i++) vals[i] = val[i] & 0xff;
451 r = disasm(vals, disasm_result, 16, addr);
452 }
453 else
454 r = DAsm(disasm_result, val, chiptype == CHIP_TYPE_Z80, addr);
455 fprintf(of, "%s", disasm_result);
456 return 1 - r;
457}
458
459/* checkbase determines the base of the number (ch, *numString)
460 and returns FALSE if the number is bad */
461static int32 checkbase(char ch, const char *numString) {
462 int32 decimal = (ch <= '9');
463 if (toupper(ch) == 'H') return FALSE;
464 while (isxdigit(ch = *numString++)) if (ch > '9') decimal = FALSE;
465 return toupper(ch) == 'H' ? 16 : (decimal ? 10 : FALSE);
466}
467
468static int32 numok(char ch, const char **numString, const int32 minvalue,
469 const int32 maxvalue, const int32 requireSign, int32 *result) {
470 int32 sign = 1, value = 0, base;
471 if (requireSign)
472 if (ch == '+') ch = *(*numString)++;
473 else if (ch == '-') {
474 sign = -1;
475 ch = *(*numString)++;
476 }
477 else return FALSE;
478 if (!(base = checkbase(ch, *numString))) return FALSE;
479 while (isxdigit(ch)) {
480 value = base * value + ((ch <= '9') ? (ch - '0') : (toupper(ch) - 'A' + 10));
481 ch = *(*numString)++;
482 }
483 if (toupper(ch) != 'H') (*numString)--;
484 *result = value * sign;
485 return (minvalue <= value) && (value <= maxvalue);
486}
487
488static int32 match(const char *pattern, const char *input, char *xyFirst, char *xy, int32 *number, int32 *star,
489 int32 *at, int32 *hat, int32 *dollar) {
490 char pat = *pattern++;
491 char inp = *input++;
492 while ((pat) && (inp)) {
493 switch(pat) {
494
495 case '_': /* patterns containing '_' should never match */
496 return FALSE;
497
498 case ',':
499 if (inp == ' ') {
500 inp = *input++;
501 continue;
502 } /* otherwise fall through */
503
504 case ' ':
505 if (inp != pat) return FALSE;
506 pat = *pattern++;
507 inp = *input++;
508 while (inp == ' ') inp = *input++;
509 continue;
510
511 case '%':
512 inp = toupper(inp);
513 if ((inp == 'X') || (inp == 'Y'))
514 if (*xyFirst) /* make sure that second '%' corresponds to first */
515 if (*xyFirst == inp) *xy = inp;
516 else return FALSE;
517 else { /* take note of first '%' for later */
518 *xyFirst = inp;
519 *xy = inp;
520 }
521 else return FALSE;
522 break;
523
524 case '#':
525 if (numok(inp, &input, 0, 65535, FALSE, number)) pattern++; /* skip h */
526 else return FALSE;
527 break;
528
529 case '*':
530 if (numok(inp, &input, 0, 255, FALSE, star)) pattern++; /* skip h */
531 else return FALSE;
532 break;
533
534 case '@':
535 if (numok(inp, &input, -128, 65535, TRUE, at)) pattern++; /* skip h */
536 else return FALSE;
537 break;
538
539 case '$':
540 if (numok(inp, &input, 0, 65535, FALSE, dollar)) pattern++; /* skip h */
541 else return FALSE;
542 break;
543
544 case '^':
545 if (numok(inp, &input, 0, 255, FALSE, hat)) pattern++; /* skip h */
546 else return FALSE;
547 break;
548
549 default:
550 if (toupper(pat) != toupper(inp)) return FALSE;
551 }
552 pat = *pattern++;
553 inp = *input++;
554 }
555 while (inp == ' ') inp = *input++;
556 return (pat == 0) && (inp == 0);
557}
558
559static int32 checkXY(const char xy) {
560 return xy == 'X' ? 0xdd : 0xfd; /* else is 'Y' */
561}
562
563static int32 parse_X80(const char *cptr, const int32 addr, uint32 *val, char *const Mnemonics[]) {
564 char xyFirst = 0, xy;
565 int32 op, number, star, at, hat, dollar;
566 for (op = 0; op < 256; op++) {
567 number = star = at = dollar = -129;
568 if (match(Mnemonics[op], cptr, &xyFirst, &xy, &number, &star, &at, &hat, &dollar)) {
569 val[0] = op;
570 if (number >= 0) {
571 val[1] = (0xff) & number;
572 val[2] = (0xff) & (number >> 8);
573 return -2; /* two additional bytes returned */
574 }
575 else if (star >= 0) {
576 val[1] = (0xff) & star;
577 return -1; /* one additional byte returned */
578 }
579 else if (at > -129)
580 if ((-128 <= at) && (at <= 127)) {
581 val[1] = (int8)(at);
582 return -1; /* one additional byte returned */
583 }
584 else return SCPE_ARG;
585 else if (dollar >= 0) {
586 dollar -= addr + 2; /* relative translation */
587 if ((-128 <= dollar) && (dollar <= 127)) {
588 val[1] = (int8)(dollar);
589 return -1; /* one additional byte returned */
590 }
591 else return SCPE_ARG;
592 }
593 else return SCPE_OK;
594 }
595 }
596 if (Mnemonics == Mnemonics8080) return SCPE_ARG;
597
598 for (op = 0; op < 256; op++)
599 if (match(MnemonicsCB[op], cptr, &xyFirst, &xy, &number, &star, &at, &hat, &dollar)) {
600 val[0] = 0xcb;
601 val[1] = op;
602 return -1; /* one additional byte returned */
603 }
604
605 for (op = 0; op < 256; op++) {
606 number = -1;
607 if (match(MnemonicsED[op], cptr, &xyFirst, &xy, &number, &star, &at, &hat, &dollar)) {
608 val[0] = 0xed;
609 val[1] = op;
610 if (number >= 0) {
611 val[2] = (0xff) & number;
612 val[3] = (0xff) & (number >> 8);
613 return -3; /* three additional bytes returned */
614 }
615 else return -1; /* one additional byte returned */
616 }
617 }
618
619 for (op = 0; op < 256; op++) {
620 number = star = hat = -1;
621 xy = 0;
622 if (match(MnemonicsXX[op], cptr, &xyFirst, &xy, &number, &star, &at, &hat, &dollar)) {
623 /* all matches must have contained a '%' character */
624 if (!(val[0] = checkXY(xy))) return SCPE_ARG;
625 val[1] = op;
626 if (number >= 0) {
627 val[2] = (0xff) & number;
628 val[3] = (0xff) & (number >> 8);
629 return -3; /* three additional bytes returned */
630 }
631 else if ((star >= 0) && (hat >= 0)) {
632 val[2] = (0xff) & hat;
633 val[3] = (0xff) & star;
634 return -3; /* three additional bytes returned */
635 }
636 else if (star >= 0) {
637 val[2] = (0xff) & star;
638 return -2; /* two additional bytes returned */
639 }
640 else if (hat >= 0) {
641 val[2] = (0xff) & hat;
642 return -2; /* two additional bytes returned */
643 }
644 else return -1; /* one additional byte returned */
645 }
646 }
647
648 for (op = 0; op < 256; op++) {
649 at = -129;
650 xy = 0;
651 if (match(MnemonicsXCB[op], cptr, &xyFirst, &xy, &number, &star, &at, &hat, &dollar)) {
652 /* all matches must have contained a '%' character */
653 if (!(val[0] = checkXY(xy))) return SCPE_ARG;
654 val[1] = 0xcb;
655 if (at > -129) val[2] = (int8) (at);
656 else {
657 printf("Offset expected.\n");
658 return SCPE_ARG;
659 }
660 val[3] = op;
661 return -3; /* three additional bytes returned */
662 }
663 }
664 return SCPE_ARG;
665}
666
667
668/* Symbolic input
669
670 Inputs:
671 *cptr = pointer to input string
672 addr = current PC
673 *uptr = pointer to unit
674 *val = pointer to output values
675 sw = switches
676 Outputs:
677 status = error status
678*/
679t_stat parse_sym(char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw) {
680 while (isspace(*cptr)) cptr++; /* absorb spaces */
681 if ((sw & (SWMASK('A') | SWMASK('C'))) || ((*cptr == '\'') && cptr++)) { /* ASCII char? */
682 if (cptr[0] == 0) return SCPE_ARG; /* must have one char */
683 val[0] = (uint32) cptr[0];
684 return SCPE_OK;
685 }
686 return parse_X80(cptr, addr, val, chiptype == CHIP_TYPE_Z80 ? MnemonicsZ80 : Mnemonics8080);
687}
688
689/* Set Memory Base Address routine */
690t_stat set_membase(UNIT *uptr, int32 val, char *cptr, void *desc)
691{
692 DEVICE *dptr;
693 PNP_INFO *pnp;
694 uint32 newba;
695 t_stat r;
696
697 if (cptr == NULL) return SCPE_ARG;
698 if (uptr == NULL) return SCPE_IERR;
699 dptr = find_dev_from_unit (uptr);
700 if (dptr == NULL) return SCPE_IERR;
701 pnp = (PNP_INFO *) dptr->ctxt;
702 if (pnp == NULL) return SCPE_IERR;
703
704 newba = get_uint (cptr, 16, 0xFFFF, &r);
705 if (r != SCPE_OK) return r;
706
707 if ((newba > 0xFFFF) ||
708 (newba % pnp->mem_size)) return SCPE_ARG;
709
710 if(dptr->flags & DEV_DIS) {
711 printf("device not enabled yet.\n");
712 pnp->mem_base = newba & ~(pnp->mem_size-1);
713 } else {
714 dptr->flags |= DEV_DIS;
715 dptr->reset(dptr);
716 pnp->mem_base = newba & ~(pnp->mem_size-1);
717 dptr->flags &= ~DEV_DIS;
718 dptr->reset(dptr);
719 }
720
721 return SCPE_OK;
722}
723
724/* Show Base Address routine */
725t_stat show_membase(FILE *st, UNIT *uptr, int32 val, void *desc)
726{
727 DEVICE *dptr;
728 PNP_INFO *pnp;
729
730 if (uptr == NULL) return SCPE_IERR;
731 dptr = find_dev_from_unit (uptr);
732 if (dptr == NULL) return SCPE_IERR;
733 pnp = (PNP_INFO *) dptr->ctxt;
734 if (pnp == NULL) return SCPE_IERR;
735
736 fprintf(st, "MEM=0x%04X-0x%04X", pnp->mem_base, pnp->mem_base+pnp->mem_size-1);
737 return SCPE_OK;
738}
739
740/* Set Memory Base Address routine */
741t_stat set_iobase(UNIT *uptr, int32 val, char *cptr, void *desc)
742{
743 DEVICE *dptr;
744 PNP_INFO *pnp;
745 uint32 newba;
746 t_stat r;
747
748 if (cptr == NULL) return SCPE_ARG;
749 if (uptr == NULL) return SCPE_IERR;
750 dptr = find_dev_from_unit (uptr);
751 if (dptr == NULL) return SCPE_IERR;
752 pnp = (PNP_INFO *) dptr->ctxt;
753 if (pnp == NULL) return SCPE_IERR;
754
755 newba = get_uint (cptr, 16, 0xFF, &r);
756 if (r != SCPE_OK) return r;
757
758 if ((newba > 0xFF) ||
759 (newba % pnp->io_size)) return SCPE_ARG;
760
761 if(dptr->flags & DEV_DIS) {
762 printf("device not enabled yet.\n");
763 pnp->io_base = newba & ~(pnp->io_size-1);
764 } else {
765 dptr->flags |= DEV_DIS;
766 dptr->reset(dptr);
767 pnp->io_base = newba & ~(pnp->io_size-1);
768 dptr->flags &= ~DEV_DIS;
769 dptr->reset(dptr);
770 }
771
772 return SCPE_OK;
773}
774
775/* Show I/O Base Address routine */
776t_stat show_iobase(FILE *st, UNIT *uptr, int32 val, void *desc)
777{
778 DEVICE *dptr;
779 PNP_INFO *pnp;
780
781 if (uptr == NULL) return SCPE_IERR;
782 dptr = find_dev_from_unit (uptr);
783 if (dptr == NULL) return SCPE_IERR;
784 pnp = (PNP_INFO *) dptr->ctxt;
785 if (pnp == NULL) return SCPE_IERR;
786
787 fprintf(st, "I/O=0x%02X-0x%02X", pnp->io_base, pnp->io_base+pnp->io_size-1);
788 return SCPE_OK;
789}
790