| 167 | } |
| 168 | |
| 169 | func parseIOInstruction(name string, operands string) (Instruction, error) { |
| 170 | arguments := IO_EXTRACTOR.FindStringSubmatch(operands) |
| 171 | if len(arguments) != 3 { |
| 172 | return nil, fmt.Errorf("Instruction %s is not valid", name) |
| 173 | } |
| 174 | |
| 175 | var iomode IO_MODE |
| 176 | switch arguments[1] { |
| 177 | case "Data": |
| 178 | iomode = DATA_MODE |
| 179 | case "Addr": |
| 180 | iomode = ADDRESS_MODE |
| 181 | default: |
| 182 | return nil, fmt.Errorf("Unsupported IO mode %s for instruction %s (must be Addr|Data)", arguments[1], name) |
| 183 | } |
| 184 | |
| 185 | var register REGISTER |
| 186 | if v, ok := REGISTERS[arguments[2]]; !ok { |
| 187 | return nil, fmt.Errorf("Unknown register %s for instruction %s", arguments[2], name) |
| 188 | } else { |
| 189 | register = v |
| 190 | } |
| 191 | |
| 192 | switch name { |
| 193 | case "OUT": |
| 194 | return OUT{iomode, register}, nil |
| 195 | case "IN": |
| 196 | return IN{iomode, register}, nil |
| 197 | default: |
| 198 | return nil, fmt.Errorf("Unknown IO instruction %s (only IN or OUT supported)", name) |
| 199 | } |
| 200 | } |
| 201 | |
| 202 | func parseTwoRegisterInstruction(name string, operands string) (Instruction, error) { |
| 203 | registers := TWO_REGISTER_EXTRACTOR.FindStringSubmatch(operands) |